首页 > 解决方案 > i have data in json format and want to convert it to csv

问题描述

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <fstream>
#include <iostream>
#include <string>

using namespace std;
int main()
{
    ofstream myfile;
    myfile.open("newtest.csv");
    mongocxx::instance instance{};
    mongocxx::uri uri("mongodb://localhost:27017");
    mongocxx::client client(uri);
    mongocxx::database db = client["work"];
    mongocxx::collection coll = db["User"];
    bsoncxx::stdx::optional<bsoncxx::document::value> maybe_result = coll.find_one({});
}

JSON in maybe_result:

{
    "_id": {
        "$oid": "5f2a435186ff70fb16f873ec"
    },
    "first_name": "Gutta",
    "last_name": "sumanth",
    "age": 25.0,
    "employee_status": "active",
    "email": "sumanth@gmail.com"
}

I want change the output to csv format.

标签: c++jsonmongodbcsv

解决方案


Here's one way to do it. There are a few more bsoncxx::types than I've cared to decode in this example. If you need them, you'll have to add them. This should be enough output your data as though.

I've put the support functions in a class to support streaming to any std::ostream.

bson_csv_adapter.hpp

#ifndef BSON_CSV_ADAPTER_HPP_IUPAHOIUHASDUIKHLKHAD
#define BSON_CSV_ADAPTER_HPP_IUPAHOIUHASDUIKHLKHAD

#include <bsoncxx/types.hpp>

#include <ostream>

class BsonCSVadapter {
public:
    // construct from a bsoncxx::document::view
    explicit BsonCSVadapter(bsoncxx::document::view&& bdv) : m_bdv(std::move(bdv)) {}

    std::ostream& print(std::ostream& os) const {
        print_view(os, m_bdv);
        return os << '\n';
    }

private:
    void print_view(std::ostream& os, const bsoncxx::document::view& v) const {
        print_range(os, v.begin(), v.end());
    }

    template<typename It>
    void print_range(std::ostream& os, It begin, It end) const {
        if(begin != end) {
            print_element(os, *begin);
            for(++begin; begin != end; ++begin) {
                os << ',';
                print_element(os, *begin);
            }
        }
    }

    // bsoncxx::document::element or bsoncxx::array::element
    template<typename ElType>
    void print_element(std::ostream& os, const ElType& e) const {
        // os << e.key().to_string() << ':';        // if you want the fields key name

        switch(e.type()) { // bsoncxx::type
            case bsoncxx::type::k_double:
                os << e.get_double();
                break;

            case bsoncxx::type::k_int32:
                os << e.get_int32();
                break;

            case bsoncxx::type::k_utf8: {
                bsoncxx::stdx::string_view sv = e.get_utf8();
                os << sv.data();
                break;
            }
            case bsoncxx::type::k_array: {
                const bsoncxx::array::view& av = e.get_array();
                print_view(os, av);
                break;
            }
            case bsoncxx::type::k_document: {
                const bsoncxx::document::view& dv = e.get_document();
                print_view(os, dv);
                break;
            }
        }
    }

    bsoncxx::document::view m_bdv;
};

// operator to support streaming
std::ostream& operator<<(std::ostream& os, const BsonCSVadapter& a) {
    return a.print(os);
}

#endif

Then in your .cpp file:

#include "bson_csv_adapter.hpp"

        // ...
        if(maybe_result) {
            // stream to std::cout
            std::cout << BsonCSVadapter(*maybe_result);

            // stream to a file
            std::ofstream myfile("newtest.csv");
            myfile << BsonCSVadapter(*maybe_result);
        }

Output:

5f2a435186ff70fb16f873ec,Gutta,sumanth,25,active,sumanth@gmail.com

If you uncomment the line os << e.key().to_string() << ':'; you'll get this output:

_id:$oid:5f2a435186ff70fb16f873ec,first_name:Gutta,last_name:sumanth,age:25,employee_status:active,email:sumanth@gmail.com

推荐阅读