#ifndef _IMPORTS_ODS_WRITER_HPP_ #define _IMPORTS_ODS_WRITER_HPP_ #include #include // Minimal OpenDocument Spreadsheet (.ods) writer. Backed by libzip + // pugixml (already in the build for the ODS *importer*). Produces // multi-sheet workbooks; each sheet is a 2-D grid of string cells. // // Usage: // OdsWriter w; // auto *s1 = w.add_sheet("connection A"); // s1->set(0, 0, "header1"); // s1->set(0, 1, "header2"); // s1->set(1, 0, "value"); // std::string err; // bool ok = w.save("out.ods", err); // // Limitations (intentional, the format is huge): // - string cells only (no numbers / dates / formulas) // - no styles, no merged cells, no formatting // - a single empty row is emitted when a row has at least one set cell; // trailing empty rows are skipped. class OdsSheet { public: explicit OdsSheet(std::string name) : name_(std::move(name)) {} void set(int row, int col, std::string value); // Index of the row that holds the column headers — gets the bold/grey // style, anchors the freeze, and is the first row of the auto-filter // range. Rows above it are rendered un-styled (a place for free-form // metadata such as the connection name). Default 0 = first row is // the header (no meta block). void set_header_row(int r) { header_row_ = r; } int header_row() const { return header_row_; } const std::string &name() const { return name_; } int rows() const { return (int)cells_.size(); } int cols() const; const std::string &cell(int row, int col) const; private: std::string name_; int header_row_ = 0; // Row-major sparse storage: cells_[r][c] = value. Rows/cols are grown // lazily on set(). std::vector> cells_; }; class OdsWriter { public: OdsSheet *add_sheet(const std::string &name); bool save(const std::string &path, std::string &error) const; private: std::vector sheets_; }; #endif // _IMPORTS_ODS_WRITER_HPP_