├── _config.yml ├── Samples ├── Image.gif ├── Image.jpg ├── Image.png ├── Image.tif ├── Anchored.png ├── Images.xlsx ├── Simple.xlsx ├── Scientific.xlsx ├── DefinedNames.xlsx ├── MultiCharts.xlsx ├── Images.pro ├── Scientific.pro ├── MultiCharts.pro ├── Simple.pro ├── DefinedNames.cpp ├── Images.cpp ├── MultiCharts.cpp ├── main.cpp ├── Simple.cpp └── Scientific.cpp ├── QSimpleXlsxWriter ├── QSimpleXlsxWriter.pro └── QSimpleXlsxWriter.pri ├── .github └── FUNDING.yml ├── simplexlsx-code ├── XLSXColors │ ├── XLSXColorLib.h │ ├── clsRGBColorRecord.h │ ├── clsRGBColorRecord.cpp │ └── XLSXColorLib.cpp ├── CMakeLists.txt ├── Xlsx │ ├── mainpage.dox │ ├── Chartsheet.h │ ├── XlsxHeaders.h │ ├── Chartsheet.cpp │ ├── Drawing.h │ ├── XlsxHeaders.cpp │ ├── Drawing.cpp │ ├── SimpleXlsxDef.cpp │ ├── Workbook.h │ ├── Worksheet.h │ ├── Worksheet.cpp │ └── SimpleXlsxDef.h ├── UTF8Encoder.hpp ├── PathManager.hpp ├── PathManager.cpp ├── Readme.txt ├── Zip │ └── zip.h └── XMLWriter.hpp ├── .licrc ├── LICENSE ├── .travis.yml ├── README.md └── .gitignore /_config.yml: -------------------------------------------------------------------------------- 1 | 2 | theme: jekyll-theme-cayman 3 | 4 | plugins: 5 | - jemoji 6 | 7 | -------------------------------------------------------------------------------- /Samples/Image.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Image.gif -------------------------------------------------------------------------------- /Samples/Image.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Image.jpg -------------------------------------------------------------------------------- /Samples/Image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Image.png -------------------------------------------------------------------------------- /Samples/Image.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Image.tif -------------------------------------------------------------------------------- /Samples/Anchored.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Anchored.png -------------------------------------------------------------------------------- /Samples/Images.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Images.xlsx -------------------------------------------------------------------------------- /Samples/Simple.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Simple.xlsx -------------------------------------------------------------------------------- /Samples/Scientific.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/Scientific.xlsx -------------------------------------------------------------------------------- /Samples/DefinedNames.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/DefinedNames.xlsx -------------------------------------------------------------------------------- /Samples/MultiCharts.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QtExcel/QSimpleXlsxWriter/HEAD/Samples/MultiCharts.xlsx -------------------------------------------------------------------------------- /QSimpleXlsxWriter/QSimpleXlsxWriter.pro: -------------------------------------------------------------------------------- 1 | # 2 | # QSimpleXlsxWriter.pro 3 | # 4 | 5 | TARGET = Qlibxlsxwriter 6 | TEMPLATE = lib 7 | CONFIG += staticlib 8 | 9 | DEFINES += QT_DEPRECATED_WARNINGS 10 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 11 | 12 | # SIMPLE_XLSX_WRITER_PARENTPATH = ../simplexlsx-code/ 13 | include(./QSimpleXlsxWriter.pri) 14 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: j2doll # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: # Replace with a single custom sponsorship URL 9 | -------------------------------------------------------------------------------- /Samples/Images.pro: -------------------------------------------------------------------------------- 1 | # 2 | # Images.pro 3 | # 4 | 5 | TARGET = Images 6 | 7 | CONFIG += console 8 | CONFIG -= app_bundle 9 | 10 | DEFINES += QT_DEPRECATED_WARNINGS 11 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 12 | 13 | # Set environment values. You may use default values. 14 | # SIMPLE_XLSX_WRITER_PARENTPATH = ../simplexlsx-code/ 15 | include(../QSimpleXlsxWriter/QSimpleXlsxWriter.pri) 16 | 17 | SOURCES += \ 18 | Images.cpp 19 | 20 | -------------------------------------------------------------------------------- /Samples/Scientific.pro: -------------------------------------------------------------------------------- 1 | # 2 | # Scientific.pro 3 | # 4 | 5 | TARGET = Scientific 6 | 7 | CONFIG += console 8 | CONFIG -= app_bundle 9 | 10 | DEFINES += QT_DEPRECATED_WARNINGS 11 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 12 | 13 | # Set environment values. You may use default values. 14 | # SIMPLE_XLSX_WRITER_PARENTPATH = ../simplexlsx-code/ 15 | include(../QSimpleXlsxWriter/QSimpleXlsxWriter.pri) 16 | 17 | SOURCES += \ 18 | Scientific.cpp 19 | 20 | -------------------------------------------------------------------------------- /Samples/MultiCharts.pro: -------------------------------------------------------------------------------- 1 | # 2 | # MultiCharts.pro 3 | # 4 | 5 | TARGET = MultiCharts 6 | 7 | CONFIG += console 8 | CONFIG -= app_bundle 9 | 10 | DEFINES += QT_DEPRECATED_WARNINGS 11 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 12 | 13 | # Set environment values. You may use default values. 14 | # SIMPLE_XLSX_WRITER_PARENTPATH = ../simplexlsx-code/ 15 | include(../QSimpleXlsxWriter/QSimpleXlsxWriter.pri) 16 | 17 | SOURCES += \ 18 | MultiCharts.cpp 19 | 20 | -------------------------------------------------------------------------------- /Samples/Simple.pro: -------------------------------------------------------------------------------- 1 | # 2 | # Simple.pro 3 | # 4 | # QSimpleXlsxWriter https://github.com/QtExcel/QSimpleXlsxWriter 5 | # 6 | 7 | TARGET = Simple 8 | 9 | CONFIG += console 10 | CONFIG -= app_bundle 11 | 12 | DEFINES += QT_DEPRECATED_WARNINGS 13 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 14 | 15 | # Set environment values. You may use default values. 16 | # SIMPLE_XLSX_WRITER_PARENTPATH = ../simplexlsx-code/ 17 | include(../QSimpleXlsxWriter/QSimpleXlsxWriter.pri) 18 | 19 | SOURCES += \ 20 | Simple.cpp 21 | -------------------------------------------------------------------------------- /simplexlsx-code/XLSXColors/XLSXColorLib.h: -------------------------------------------------------------------------------- 1 | #ifndef XLSXCOLORLIB_H_INCLUDED 2 | #define XLSXCOLORLIB_H_INCLUDED 3 | #include 4 | #include "clsRGBColorRecord.h" 5 | namespace SimpleXlsx 6 | { 7 | class 8 | XLSXColorLib{ 9 | std::map lib; 10 | public: 11 | XLSXColorLib(){}; 12 | virtual ~XLSXColorLib(); 13 | void AddColor(const char * id, const clsRGBColorRecord & cl){ lib[id]=cl; }; 14 | const char * GetColor(const char * id) { return lib.at(id).Get(); }; 15 | void Clear() { lib.clear(); }; 16 | }; 17 | extern void make_grayscale10(XLSXColorLib & xlib); 18 | extern void make_excell_like_named_colors(XLSXColorLib & xlib); 19 | } 20 | #endif // XLSXCOLORLIB_H_INCLUDED 21 | -------------------------------------------------------------------------------- /.licrc: -------------------------------------------------------------------------------- 1 | # IMPORTANT!: ALL SECTIONS ARE MANDATORY 2 | [licenses] 3 | # This indicates which are the only licenses that Licensebat will accept. 4 | # The rest will be flagged as not allowed. 5 | accepted = ["MIT", "MSC", "BSD"] 6 | # This will indicate which licenses are not accepted. 7 | # The rest will be accepted, except for the unknown licenses or dependencies without licenses. 8 | # unaccepted = ["LGPL"] 9 | # Note that only one of the previous options can be enabled at once. 10 | # If both of them are informed, only accepted will be considered. 11 | 12 | [dependencies] 13 | ignore_dev_dependencies = true 14 | ignore_optional_dependencies = true 15 | 16 | [behavior] 17 | # False by default, if true, it will only run the checks when one of the dependency files or the .licrc file has been modified. 18 | run_only_on_dependency_modification = true 19 | # False by default, if true, it will never block the build. 20 | do_not_block_pr = true -------------------------------------------------------------------------------- /Samples/DefinedNames.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace SimpleXlsx; 6 | 7 | int main() 8 | { 9 | CWorkbook Book( "Incognito" ); 10 | CWorksheet & Sheet = Book.AddSheet( "Sheet 1" ); 11 | CWorksheet & SecondSheet = Book.AddSheet( "Sheet 2" ); 12 | 13 | Book.AddDefinedName( "HalfRad", 0.5, "Half radian" ).AddDefinedName( "TestSin", "sin(HalfRad)" ); 14 | Book.AddDefinedName( "SingleCell", Sheet, CellCoord( 1, 0 ) ); 15 | Book.AddDefinedName( "RangeCells", Sheet, CellCoord( 1, 0 ), CellCoord( 2, 0 ) ); 16 | Book.AddDefinedName( "TestScope", Sheet, CellCoord( 1, 0 ), "", & SecondSheet ); 17 | 18 | Sheet.AddSimpleRow( "=HalfRad" ).AddSimpleRow( "=TestSin" ); 19 | Sheet.AddSimpleRow( "=SingleCell" ).AddSimpleRow( "=sum(RangeCells)" ); 20 | 21 | SecondSheet.AddSimpleRow( "=TestScope" ); 22 | 23 | if( Book.Save( "DefinedNames.xlsx" ) ) std::cout << "The book has been saved successfully" << std::endl; 24 | else std::cout << "The book saving has been failed" << std::endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018- j2doll 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /simplexlsx-code/XLSXColors/clsRGBColorRecord.h: -------------------------------------------------------------------------------- 1 | #ifndef CLSRGBCOLORRECORD_H 2 | #define CLSRGBCOLORRECORD_H 3 | #include 4 | namespace SimpleXlsx 5 | { 6 | class clsRGBColorRecord 7 | { 8 | public: 9 | clsRGBColorRecord(); 10 | clsRGBColorRecord( const unsigned char gs) { Set(gs);}; 11 | clsRGBColorRecord( const unsigned char r, const unsigned char g, const unsigned char b) { Set(r,g,b);}; 12 | clsRGBColorRecord( const double gs){ Set(gs);}; 13 | clsRGBColorRecord( const char (&sharpn)[7]){ Set(sharpn);}; 14 | virtual ~clsRGBColorRecord(); 15 | clsRGBColorRecord(const clsRGBColorRecord& other); 16 | clsRGBColorRecord& operator=(const clsRGBColorRecord& other); 17 | const char * Get() const {return colstr;}; 18 | void Set(const unsigned char r, const unsigned char g, const unsigned char b); 19 | void Set(const unsigned char chargs); 20 | void Set(const double gs); 21 | void Set(const char (&sharpn)[7]); 22 | protected: 23 | char colstr[7]; 24 | void Copy(const clsRGBColorRecord& other); 25 | private: 26 | }; 27 | }; 28 | #endif // CLSRGBCOLORRECORD_H 29 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # .travis.yml (Travis CI) 2 | # 3 | # QSimpleXlsxWriter 4 | # https://github.com/j2doll/QSimpleXlsxWriter 5 | # 6 | 7 | language: c++ 8 | compiler: gcc 9 | sudo: require 10 | dist: xenial # Ubuntu Xenial 16.04, Trusty 14.04, Precise 12.04 11 | 12 | before_install: 13 | - sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa 14 | - sudo apt-get update -qq 15 | 16 | # zlib 17 | # - sudo apt-get install zlib1g 18 | # - sudo apt-get install zlib1g-dev 19 | 20 | - sudo apt-get install build-essential 21 | 22 | # Qt 5 23 | - sudo apt-get install qtbase5-dev qtdeclarative5-dev 24 | - sudo apt-get install qt5-default qttools5-dev-tools 25 | 26 | install: 27 | 28 | script: 29 | 30 | # lib 31 | - cd QSimpleXlsxWriter 32 | - qmake QSimpleXlsxWriter.pro 33 | - make 34 | 35 | # samples 36 | - cd ../Samples 37 | 38 | - qmake Simple.pro 39 | - make 40 | - make clean 41 | - ./Simple 42 | 43 | - qmake Images.pro 44 | - make 45 | - make clean 46 | - ./Images 47 | 48 | - qmake MultiCharts.pro 49 | - make 50 | - make clean 51 | - ./MultiCharts 52 | 53 | - qmake Scientific.pro 54 | - make 55 | - make clean 56 | - ./Scientific 57 | 58 | -------------------------------------------------------------------------------- /Samples/Images.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | using namespace SimpleXlsx; 6 | 7 | int main() 8 | { 9 | setlocale( LC_ALL, "" ); 10 | 11 | CWorkbook Book( "Incognito" ); 12 | CWorksheet & Sheet = Book.AddSheet( "Images" ); 13 | 14 | Sheet.BeginRow(); 15 | Sheet.AddCell( "Supported image formats:" ); 16 | Sheet.AddEmptyCells( 3 ); 17 | Sheet.AddCell( "Anchored image (try to resize column or row):" ); 18 | Sheet.AddEmptyCells( 5 ); 19 | Sheet.AddCell( "Scaled image:" ); 20 | Sheet.EndRow(); 21 | 22 | Book.AddImage( Sheet, "Image.gif", DrawingPoint( 0, 1 ) ); 23 | Book.AddImage( Sheet, "Image.jpg", DrawingPoint( 0, 4 ) ); 24 | Book.AddImage( Sheet, "Image.png", DrawingPoint( 0, 7 ) ); 25 | Book.AddImage( Sheet, "Image.tif", DrawingPoint( 0, 10 ) ); 26 | 27 | Book.AddImage( Sheet, "Anchored.png", DrawingPoint( 4, 1 ), DrawingPoint( 5, 3 ) ); 28 | 29 | Book.AddImage( Sheet, "Image.png", DrawingPoint( 10, 1 ), 200, 200 ); 30 | 31 | if( Book.Save( "Images.xlsx" ) ) std::cout << "The book has been saved successfully" << std::endl; 32 | else std::cout << "The book saving has been failed" << std::endl; 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /simplexlsx-code/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # After compilation it will destribute a static lib into a lib folder 2 | # and destributes all header files into an include folder. 3 | 4 | cmake_minimum_required(VERSION 2.8) 5 | project(SimpleXlsx) 6 | 7 | if(NOT CMAKE_DEBUG_POSTFIX) 8 | set(CMAKE_DEBUG_POSTFIX d) 9 | endif() 10 | 11 | set(UNICODE false CACHE BOOL "Use Unicode macro") 12 | 13 | if(${UNICODE}) 14 | add_definitions(-DUNICODE -D_UNICODE) 15 | endif() 16 | 17 | file(GLOB MAIN_HDRS 18 | "*.hpp" 19 | "*.h" 20 | ) 21 | file(GLOB XLSX_HDRS 22 | "Xlsx/*.h" 23 | ) 24 | file(GLOB XLSXCOLORS_HDRS 25 | "XLSXColors/*.h" 26 | ) 27 | 28 | file(GLOB ZIP_HDRS 29 | "Zip/*.h" 30 | ) 31 | 32 | file(GLOB SRCS 33 | "*.cpp" 34 | "Xlsx/*.cpp" 35 | "XLSXColors/*.cpp" 36 | "Zip/*.cpp" 37 | ) 38 | 39 | add_library(SimpleXlsx STATIC 40 | ${SRCS} 41 | ${MAIN_HDRS} 42 | ${XLSX_HDRS} 43 | ${XLSXCOLORS_HDRS} 44 | ${ZIP_HDRS} 45 | ) 46 | set_target_properties(SimpleXlsx PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) 47 | 48 | install(TARGETS SimpleXlsx DESTINATION lib) 49 | install(FILES ${MAIN_HDRS} DESTINATION include) 50 | install(FILES ${XLSX_HDRS} DESTINATION include/Xlsx) 51 | install(FILES ${XLSXCOLORS_HDRS} DESTINATION include/XLSXColors) 52 | install(FILES ${ZIP_HDRS} DESTINATION include/Zip) -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/mainpage.dox: -------------------------------------------------------------------------------- 1 | /** 2 | \mainpage The mainpage documentation 3 | 4 | This library represents XLSX files writer for Microsoft Excel 2007 and above. 5 | 6 | The main feature of this library is that it uses C++ standard file streams. On the one hand it results in almost unnoticeable memory and CPU resources consumption while processing (that may be very useful at saving a large data arrays), but on the other hand it makes unfeasible to edit data that were written. 7 | Hence, if using this library the structure of the future report should be known enough. 8 | 9 | The library is written in C++ with using STL functionality and based on the ZIP library (included), which has a free license. 10 | 11 | http://www.codeproject.com/Articles/7530/Zip-Utils-clean-elegant-simple-C-Win32 12 | 13 | Key features: 14 | - Cell styles: fonts, fills, borders, alignment, multirow text, text rotation 15 | - Cell formats: text, numeric, dates and times, custom formats 16 | - Formulae recognition (without formula`s content verification), defined names 17 | - Multi-sheets 18 | - Charts with customizable parameters (on data sheet or separate sheet): linear, bar, scatter 19 | - Images on the worksheet: gif, jpg, jpeg, png, tif, tiff 20 | - Multiplatform: BSD, Linux, Windows 21 | - No external dependencies. 22 | 23 | The Simple DirectMedia Layer library source code is available from: 24 | https://sourceforge.net/projects/simplexlsx/ 25 | 26 | This library is distributed under the terms of the zlib license: 27 | http://www.zlib.net/zlib_license.html 28 | */ -------------------------------------------------------------------------------- /simplexlsx-code/XLSXColors/clsRGBColorRecord.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "clsRGBColorRecord.h" 6 | #include 7 | namespace SimpleXlsx 8 | { 9 | 10 | 11 | clsRGBColorRecord::clsRGBColorRecord() 12 | { 13 | //ctor 14 | snprintf(colstr,sizeof(colstr),"%02X%02X%02X",0,0,0); 15 | 16 | } 17 | 18 | clsRGBColorRecord::~clsRGBColorRecord() 19 | { 20 | //dtor 21 | } 22 | 23 | clsRGBColorRecord::clsRGBColorRecord(const clsRGBColorRecord& other) 24 | { 25 | //copy ctor 26 | Copy(other); 27 | } 28 | 29 | clsRGBColorRecord& clsRGBColorRecord::operator=(const clsRGBColorRecord& rhs) 30 | { 31 | if (this == &rhs) return *this; // handle self assignment 32 | Copy(rhs); 33 | return *this; 34 | } 35 | void clsRGBColorRecord::Copy(const clsRGBColorRecord& p){ 36 | //std::move(p.colstr,p.colstr+sizeof(p.colstr),colstr); 37 | memcpy(colstr,p.colstr,7*sizeof(char)); 38 | }; 39 | 40 | void clsRGBColorRecord::Set(const char (&sharpn)[7]){ 41 | //std::move(sharpn,sharpn+sizeof(sharpn),colstr); 42 | memcpy(colstr,sharpn,7*sizeof(char)); 43 | }; 44 | 45 | void clsRGBColorRecord::Set(const unsigned char r, const unsigned char g, const unsigned char b){ 46 | snprintf(colstr,sizeof(colstr),"%02X%02X%02X",r,g,b); 47 | }; 48 | void clsRGBColorRecord::Set(const unsigned char gs){ 49 | snprintf(colstr,sizeof(colstr),"%02X%02X%02X",gs,gs,gs); 50 | }; 51 | void clsRGBColorRecord::Set(const double dgs){ 52 | unsigned char gs=(255*dgs)*0.01; 53 | Set(gs); 54 | }; 55 | }; 56 | -------------------------------------------------------------------------------- /QSimpleXlsxWriter/QSimpleXlsxWriter.pri: -------------------------------------------------------------------------------- 1 | # 2 | # QSimpleXlsxWriter.pri 3 | # 4 | 5 | CONFIG += c++11 6 | 7 | isEmpty(SIMPLE_XLSX_WRITER_PARENTPATH) { 8 | message( 'SIMPLE_XLSX_WRITER_PARENTPATH is empty. use default value.' ) 9 | SIMPLE_XLSX_WRITER_PARENTPATH = ../simplexlsx-code/ 10 | } else { 11 | message( 'SIMPLE_XLSX_WRITER_PARENTPATH :' ) 12 | message( $${SIMPLE_XLSX_WRITER_PARENTPATH} ) 13 | } 14 | 15 | # simplexlsx-code 16 | 17 | INCLUDEPATH += \ 18 | $${SIMPLE_XLSX_WRITER_PARENTPATH} 19 | 20 | HEADERS += \ 21 | $${SIMPLE_XLSX_WRITER_PARENTPATH}XMLWriter.hpp 22 | $${SIMPLE_XLSX_WRITER_PARENTPATH}UTF8Encoder.hpp 23 | $${SIMPLE_XLSX_WRITER_PARENTPATH}PathManager.hpp 24 | 25 | SOURCES += \ 26 | $${SIMPLE_XLSX_WRITER_PARENTPATH}PathManager.cpp 27 | 28 | # simplexlsx-code/Xlsx 29 | 30 | INCLUDEPATH += \ 31 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx 32 | 33 | HEADERS += \ 34 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Chart.h \ 35 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Chartsheet.h \ 36 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Drawing.h \ 37 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/SimpleXlsxDef.h \ 38 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Workbook.h \ 39 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Worksheet.h \ 40 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/XlsxHeaders.h 41 | 42 | SOURCES += \ 43 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Chart.cpp \ 44 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Chartsheet.cpp \ 45 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Drawing.cpp \ 46 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/SimpleXlsxDef.cpp \ 47 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Workbook.cpp \ 48 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/Worksheet.cpp \ 49 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Xlsx/XlsxHeaders.cpp 50 | 51 | # simplexlsx-code/XLSXColors 52 | 53 | INCLUDEPATH += \ 54 | $${SIMPLE_XLSX_WRITER_PARENTPATH}XLSXColors 55 | 56 | HEADERS += \ 57 | $${SIMPLE_XLSX_WRITER_PARENTPATH}XLSXColors/clsRGBColorRecord.h \ 58 | $${SIMPLE_XLSX_WRITER_PARENTPATH}XLSXColors/XLSXColorLib.h 59 | 60 | SOURCES += \ 61 | $${SIMPLE_XLSX_WRITER_PARENTPATH}XLSXColors/clsRGBColorRecord.cpp \ 62 | $${SIMPLE_XLSX_WRITER_PARENTPATH}XLSXColors/XLSXColorLib.cpp 63 | 64 | # simplexlsx-code/Zip 65 | 66 | INCLUDEPATH += \ 67 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Zip 68 | 69 | HEADERS += \ 70 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Zip/zip.h 71 | 72 | SOURCES += \ 73 | $${SIMPLE_XLSX_WRITER_PARENTPATH}Zip/zip.cpp 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /simplexlsx-code/UTF8Encoder.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef UTF8ENCODER_H 23 | #define UTF8ENCODER_H 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | class UTF8Encoder 30 | { 31 | public: 32 | static inline std::string From_wchar_t( int32_t Code ) 33 | { 34 | assert( ( Code >= 0 ) && "Code can not be negative." ); 35 | if( Code <= 0x7F ) return std::string( 1, static_cast( Code ) ); 36 | else 37 | { 38 | unsigned char FirstByte = 0xC0; //First byte with mask 39 | unsigned char Buffer[ 7 ] = { 0 }; //Buffer for UTF-8 bytes, null-ponter string 40 | char * Ptr = reinterpret_cast( & Buffer[ 5 ] ); //Ptr to Buffer, started from end 41 | unsigned char LastValue = 0x1F; //Max value for implement to the first byte 42 | while( true ) 43 | { 44 | * Ptr = static_cast( ( Code & 0x3F ) | 0x80 ); //Making new value with format 10xxxxxx 45 | Ptr--; //Move Ptr to new position 46 | Code >>= 6; //Shifting Code 47 | if( Code <= LastValue ) break; //if Code can set to FirstByte => break; 48 | LastValue >>= 1; //Make less max value 49 | FirstByte = ( FirstByte >> 1 ) | 0x80; //Modify first byte 50 | } 51 | * Ptr = static_cast( FirstByte | Code ); //Making first byte of UTF-8 sequence 52 | return std::string( Ptr ); 53 | } 54 | } 55 | 56 | static inline std::string From_wstring( const std::wstring & Source ) 57 | { 58 | std::string Result; 59 | for( std::wstring::const_iterator iter = Source.begin(); iter != Source.end(); iter++ ) 60 | Result.append( From_wchar_t( * iter ) ); 61 | return Result; 62 | } 63 | }; 64 | 65 | 66 | #endif // UTF8ENCODER_H 67 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/Chartsheet.h: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XLSX_CHARTSHEET_H 23 | #define XLSX_CHARTSHEET_H 24 | 25 | #include 26 | 27 | #include "SimpleXlsxDef.h" 28 | 29 | // **************************************************************************** 30 | /// @brief The following namespace contains declarations of a number of classes 31 | /// which allow writing .xlsx files with formulae and charts 32 | /// @note All classes inside the namepace are used together, so a separate 33 | /// using will not guarantee stability and reliability 34 | // **************************************************************************** 35 | namespace SimpleXlsx 36 | { 37 | class CChart; 38 | class CDrawing; 39 | class PathManager; 40 | 41 | // **************************************************************************** 42 | /// @brief The class CChartsheet is used for creation sheet with chart. 43 | /// @see EChartTypes supplying types of charts 44 | /// @note All created chartsheets inside workbook will be allocated on its` own sheet 45 | // **************************************************************************** 46 | class CChartsheet : public CSheet 47 | { 48 | public: 49 | //Reference to the Chart 50 | inline CChart & Chart() 51 | { 52 | return m_Chart; 53 | } 54 | 55 | virtual const UniString & GetTitle() const; 56 | 57 | protected: 58 | CChartsheet( size_t index, CChart & chart, CDrawing & drawing, PathManager & pathmanager ); 59 | virtual ~CChartsheet(); 60 | 61 | private: 62 | //Disable copy and assignment 63 | CChartsheet( const CChartsheet & that ); 64 | CChartsheet & operator=( const CChartsheet & ); 65 | 66 | CChart & m_Chart; ///< Reference to chart 67 | CDrawing & m_Drawing; ///< Reference to drawing object 68 | PathManager & m_pathManager; ///< reference to XML PathManager 69 | 70 | bool Save(); 71 | 72 | friend class CWorkbook; 73 | }; 74 | 75 | } // namespace SimpleXlsx 76 | 77 | #endif // XLSX_CHARTSHEET_H 78 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/XlsxHeaders.h: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XLSX_HEADERS_H 23 | #define XLSX_HEADERS_H 24 | 25 | namespace SimpleXlsx 26 | { 27 | extern const char * ns_content_types; 28 | extern const char * content_printer; 29 | extern const char * content_rels; 30 | extern const char * content_xml; 31 | extern const char * content_book; 32 | extern const char * content_sheet; 33 | extern const char * content_theme; 34 | extern const char * content_styles; 35 | extern const char * content_sharedStr; 36 | extern const char * content_comment; 37 | extern const char * content_vml; 38 | extern const char * content_core; 39 | extern const char * content_app; 40 | extern const char * content_chart; 41 | extern const char * content_drawing; 42 | extern const char * content_chartsheet; 43 | extern const char * content_chain; 44 | 45 | extern const char * ns_markup_compatibility; 46 | extern const char * ns_c14; 47 | extern const char * ns_relationships_chart; 48 | 49 | extern const char * ns_relationships; 50 | extern const char * type_book; 51 | extern const char * type_core; 52 | extern const char * type_app; 53 | 54 | extern const char * ns_cp; 55 | extern const char * ns_dc; 56 | extern const char * ns_dcterms; 57 | extern const char * ns_dcmitype; 58 | extern const char * ns_xsi; 59 | extern const char * xsi_type; 60 | 61 | extern const char * ns_doc_prop; 62 | extern const char * ns_vt; 63 | 64 | extern const char * ns_book; 65 | extern const char * ns_book_r; 66 | 67 | extern const char * ns_mc; 68 | extern const char * ns_x14ac; 69 | 70 | extern const char * ns_x14; 71 | 72 | extern const char * type_comments; 73 | extern const char * type_vml; 74 | extern const char * type_sheet; 75 | extern const char * type_style; 76 | extern const char * type_sharedStr; 77 | extern const char * type_theme; 78 | extern const char * type_chain; 79 | extern const char * type_chartsheet; 80 | extern const char * type_chart; 81 | extern const char * type_drawing; 82 | extern const char * type_image; 83 | 84 | extern const char * ns_a; 85 | extern const char * ns_c; 86 | extern const char * ns_xdr; 87 | } 88 | 89 | #endif // XLSX_HEADERS_H 90 | -------------------------------------------------------------------------------- /simplexlsx-code/XLSXColors/XLSXColorLib.cpp: -------------------------------------------------------------------------------- 1 | #include "XLSXColorLib.h" 2 | namespace SimpleXlsx 3 | { 4 | XLSXColorLib::~XLSXColorLib(){}; 5 | 6 | void make_grayscale10(XLSXColorLib & xlib){ 7 | xlib.Clear(); 8 | 9 | xlib.AddColor("Black",clsRGBColorRecord((unsigned char)0)); 10 | xlib.AddColor("Gray10%",clsRGBColorRecord(10.)); 11 | xlib.AddColor("Gray20%",clsRGBColorRecord(20.)); 12 | xlib.AddColor("Gray30%",clsRGBColorRecord(30.)); 13 | xlib.AddColor("Gray40%",clsRGBColorRecord(40.)); 14 | xlib.AddColor("Gray50%",clsRGBColorRecord(50.)); 15 | xlib.AddColor("Gray60%",clsRGBColorRecord(60.)); 16 | xlib.AddColor("Gray70%",clsRGBColorRecord(70.)); 17 | xlib.AddColor("Gray80%",clsRGBColorRecord(80.)); 18 | xlib.AddColor("Gray90%",clsRGBColorRecord(90.)); 19 | xlib.AddColor("White",clsRGBColorRecord((unsigned char)255)); 20 | } 21 | void make_excell_like_named_colors(XLSXColorLib & xlib){ 22 | xlib.Clear(); 23 | xlib.AddColor("Black",clsRGBColorRecord((unsigned char)0)); 24 | xlib.AddColor("Brown",clsRGBColorRecord("993300")); 25 | xlib.AddColor("Olive Green",clsRGBColorRecord("333300")); 26 | xlib.AddColor("Dark Green",clsRGBColorRecord("003300")); 27 | xlib.AddColor("Dark Teal",clsRGBColorRecord("003366")); 28 | xlib.AddColor("Dark Blue",clsRGBColorRecord("000080")); 29 | xlib.AddColor("Indigo",clsRGBColorRecord("333399")); 30 | xlib.AddColor("Dark Red",clsRGBColorRecord("800000")); 31 | xlib.AddColor("Orange",clsRGBColorRecord("FF6600")); 32 | xlib.AddColor("Dark Yellow",clsRGBColorRecord("808000")); 33 | xlib.AddColor("Green",clsRGBColorRecord("008000")); 34 | xlib.AddColor("Teal",clsRGBColorRecord("008080")); 35 | xlib.AddColor("Blue",clsRGBColorRecord("0000FF")); 36 | xlib.AddColor("Blue-Gray",clsRGBColorRecord("666699")); 37 | xlib.AddColor("Red",clsRGBColorRecord("FF0000")); 38 | xlib.AddColor("Light Orange",clsRGBColorRecord("FF9900")); 39 | xlib.AddColor("Lime",clsRGBColorRecord("99CC00")); 40 | xlib.AddColor("Sea Green",clsRGBColorRecord("339966")); 41 | xlib.AddColor("Aqua",clsRGBColorRecord("33CCCC")); 42 | xlib.AddColor("Light Blue",clsRGBColorRecord("3366FF")); 43 | xlib.AddColor("Violet",clsRGBColorRecord("800080")); 44 | xlib.AddColor("Pink",clsRGBColorRecord("FF00FF")); 45 | xlib.AddColor("Gold",clsRGBColorRecord("FFCC00")); 46 | xlib.AddColor("Yellow",clsRGBColorRecord("FFFF00")); 47 | xlib.AddColor("Bright Green",clsRGBColorRecord("00FF00")); 48 | xlib.AddColor("Turquoise",clsRGBColorRecord("00FFFF")); 49 | xlib.AddColor("Sky Blue",clsRGBColorRecord("00CCFF")); 50 | xlib.AddColor("Plum",clsRGBColorRecord("993366")); 51 | xlib.AddColor("Rose",clsRGBColorRecord("FF99CC")); 52 | xlib.AddColor("Tan",clsRGBColorRecord("FFCC99")); 53 | xlib.AddColor("Light Yellow",clsRGBColorRecord("FFFF99")); 54 | xlib.AddColor("Light Green",clsRGBColorRecord("CCFFCC")); 55 | xlib.AddColor("Light Turquoise",clsRGBColorRecord("CCFFFF")); 56 | xlib.AddColor("Pale Blue",clsRGBColorRecord("99CCFF")); 57 | xlib.AddColor("Lavender",clsRGBColorRecord("CC99FF")); 58 | xlib.AddColor("Periwinkle",clsRGBColorRecord("9999FF")); 59 | xlib.AddColor("Dark Purple",clsRGBColorRecord("660066")); 60 | xlib.AddColor("Coral",clsRGBColorRecord("FF8080")); 61 | xlib.AddColor("Ocean Blue",clsRGBColorRecord("0066CC")); 62 | xlib.AddColor("Ice Blue",clsRGBColorRecord("CCCCFF")); 63 | xlib.AddColor("White",clsRGBColorRecord((unsigned char)255)); 64 | xlib.AddColor("Gray",clsRGBColorRecord((unsigned char)127)); 65 | }; 66 | }; 67 | -------------------------------------------------------------------------------- /simplexlsx-code/PathManager.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XLSX_PATHMANAGER_HPP 23 | #define XLSX_PATHMANAGER_HPP 24 | 25 | #include 26 | #include 27 | 28 | namespace SimpleXlsx 29 | { 30 | 31 | class PathManager 32 | { 33 | public: 34 | inline PathManager( const std::string & temp_path ) : m_temp_path( temp_path ) {} 35 | 36 | inline ~PathManager() 37 | { 38 | ClearTemp(); 39 | } 40 | 41 | //Register XML and creating all necessary subdirectories 42 | inline const std::string RegisterXML( const std::string & PathToFile ) 43 | { 44 | return RegisterFile( PathToFile ); 45 | } 46 | 47 | //Creating all necessary subdirectories and copy image file 48 | bool RegisterImage( const std::string & LocalPath, const std::string & XLSX_Path ); 49 | 50 | //Deletes all temporary files and directories which have been created 51 | void ClearTemp(); 52 | 53 | inline const std::vector< std::string > & ContentFiles() const 54 | { 55 | return m_contentFiles; 56 | } 57 | 58 | // *INDENT-OFF* For AStyle tool 59 | 60 | //Encode File Path for the Operation System 61 | static std::string PathEncode( const wchar_t * Path ); 62 | static inline std::string PathEncode( const std::wstring & Path ) { return PathEncode( Path.c_str() ); } 63 | // *INDENT-ON* For AStyle tool 64 | 65 | private: 66 | //Disable copy and assignment 67 | PathManager( const PathManager & that ); 68 | PathManager & operator=( const PathManager & ); 69 | 70 | const std::string & m_temp_path; ///< path to the temporary directory (unique for a book) 71 | std::vector< std::string > m_temp_dirs; ///< a series of temporary subdirectories 72 | std::vector< std::string > m_contentFiles; ///< a series of relative file pathes to be saved inside xlsx archive 73 | 74 | // **************************************************************************** 75 | /// @brief Function to create nested directories` tree 76 | /// @param dirName directories` tree to be created 77 | /// @return Boolean result of the operation 78 | // **************************************************************************** 79 | bool MakeDirectory( const std::string & dirName ); 80 | 81 | //Register file for XLSX and creating all necessary subdirectories 82 | inline const std::string RegisterFile( const std::string & PathToFile ) 83 | { 84 | std::string Result = m_temp_path + PathToFile; 85 | MakeDirectory( Result ); 86 | m_contentFiles.push_back( PathToFile ); 87 | return Result; 88 | } 89 | }; 90 | 91 | } 92 | #endif // XLSX_PATHMANAGER_HPP 93 | -------------------------------------------------------------------------------- /Samples/MultiCharts.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace SimpleXlsx; 12 | 13 | int main() 14 | { 15 | setlocale( LC_ALL, "" ); 16 | 17 | time_t CurrentTime = time( NULL ); 18 | srand( static_cast( CurrentTime ) ); 19 | 20 | CWorkbook Book( "Incognito" ); 21 | 22 | //data sheet to store data to be referenced 23 | CWorksheet & FirstDataSheet = Book.AddSheet( "Data" ); 24 | 25 | std::vector data1, data2; 26 | CellDataDbl cellDbl; 27 | cellDbl.style_id = 0; 28 | 29 | const int DataCellCount = 35; 30 | // fill data sheet with randomly generated numbers 31 | for( int i = 0; i < DataCellCount; i++ ) 32 | { 33 | cellDbl.value = ( rand() % 100 ) / 50.0; 34 | data1.push_back( cellDbl ); 35 | cellDbl.value = 2.0 - cellDbl.value; 36 | data2.push_back( cellDbl ); 37 | } 38 | 39 | FirstDataSheet.AddRow( data1 ).AddRow( data2 ); // data can be added by row or by cell 40 | 41 | // adding chart sheet to the workbook the reference to a newly created object is returned 42 | CChartsheet & ChartSheet = Book.AddChartSheet( "Line Chart", CHART_LINEAR ); 43 | // create series object, that contains most chart settings 44 | CChart::Series ser; 45 | // leave category sequence (X axis) not specified (optional) - MS Excel will generate the default sequence automatically 46 | ser.catSheet = NULL; 47 | 48 | // specify range for values` sequence (Y axis) 49 | ser.valAxisFrom = CellCoord( 1, 0 ); 50 | ser.valAxisTo = CellCoord( 1, DataCellCount ); 51 | ser.valSheet = & FirstDataSheet; // don`t forget to set the pointer to the data sheet 52 | 53 | ser.title = "First Line"; 54 | ser.JoinType = CChart::Series::joinSmooth; 55 | 56 | // add series into the chart (you can add as many series as you wish into the same chart) 57 | ChartSheet.Chart().AddSeries( ser ); 58 | 59 | // second line to the chart 60 | CChart::Series ser2 = ser; 61 | ser2.valAxisFrom = CellCoord( 2, 0 ); 62 | ser2.valAxisTo = CellCoord( 2, DataCellCount ); 63 | ser2.title = "Second Line"; 64 | 65 | // charts in the worksheet 66 | CChart & OnSheetChart = Book.AddChart( FirstDataSheet, DrawingPoint( 3, 3 ), DrawingPoint( 10, 20 ) ); 67 | OnSheetChart.AddSeries( ser ); 68 | OnSheetChart.AddSeries( ser2 ); 69 | OnSheetChart.SetLegendPos( CChart::POS_BOTTOM ); 70 | 71 | CChart & OnSheetChart2 = Book.AddChart( FirstDataSheet, DrawingPoint( 13, 3 ), DrawingPoint( 20, 25 ) ); 72 | OnSheetChart2.AddSeries( ser ); 73 | ser2.Marker.Type = SimpleXlsx::CChart::Series::symDiamond; 74 | OnSheetChart2.AddSeries( ser2 ); 75 | OnSheetChart2.SetLegendPos( CChart::POS_LEFT_ASIDE ); 76 | 77 | CWorksheet & SecondDataSheet = Book.AddSheet( "Data2" ); 78 | for( int i = 0; i < DataCellCount; i++ ) 79 | SecondDataSheet.BeginRow().AddCell( sin( i * 0.5 ) + 1 ).EndRow(); 80 | 81 | CChart::Series ser3; 82 | ser3.catSheet = NULL; 83 | ser3.valAxisFrom = CellCoord( 1, 0 ); 84 | ser3.valAxisTo = CellCoord( DataCellCount, 0 ); 85 | ser3.valSheet = & SecondDataSheet; // don`t forget to set the pointer to the data sheet 86 | ser3.title = "Third Line"; 87 | ser3.JoinType = CChart::Series::joinSmooth; 88 | ser3.LineColor = "00FF00"; 89 | CChart & OnSheetChart3 = Book.AddChart( SecondDataSheet, DrawingPoint( 3, 3 ), DrawingPoint( 20, 25 ) ); 90 | OnSheetChart3.AddSeries( ser3 ); 91 | ChartSheet.Chart().AddSeries( ser3 ); 92 | 93 | Book.SetActiveSheet( ChartSheet ); 94 | 95 | if( Book.Save( "MultiCharts.xlsx" ) ) std::cout << "The book has been saved successfully" << std::endl; 96 | else std::cout << "The book saving has been failed" << std::endl; 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /Samples/main.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | using namespace SimpleXlsx; 11 | 12 | int main( int argc, char * argv[] ) 13 | { 14 | ( void )argc; ( void )argv; 15 | 16 | setlocale( LC_ALL, "" ); 17 | 18 | time_t CurrentTime = time( NULL ); 19 | 20 | CWorkbook book( "Incognito" ); 21 | 22 | std::vector ColWidth; 23 | ColWidth.push_back( ColumnWidth( 0, 3, 20 ) ); 24 | CWorksheet & Sheet = book.AddSheet( "Unicode", ColWidth ); 25 | 26 | Style style; 27 | style.horizAlign = ALIGN_H_CENTER; 28 | style.font.attributes = FONT_BOLD; 29 | size_t CenterStyleIndex = book.AddStyle( style ); 30 | 31 | Sheet.BeginRow(); 32 | Sheet.AddCell( "Common test of Unicode support", CenterStyleIndex ); 33 | Sheet.MergeCells( CellCoord( 1, 0 ), CellCoord( 1, 3 ) ); 34 | Sheet.EndRow(); 35 | 36 | Font TmpFont = book.GetFonts().front(); 37 | TmpFont.attributes = FONT_ITALIC; 38 | Comment Com; 39 | Com.x = 250; 40 | Com.y = 100; 41 | Com.width = 100; 42 | Com.height = 30; 43 | Com.cellRef = CellCoord( 8, 1 ); 44 | Com.isHidden = false; 45 | Com.AddContent( TmpFont, "Comment with custom style" ); 46 | Sheet.AddComment( Com ); 47 | 48 | Sheet.BeginRow(); 49 | Sheet.AddCell( "English language" ); 50 | Sheet.AddCell( "English language" ); 51 | Sheet.EndRow(); 52 | 53 | Sheet.BeginRow(); 54 | Sheet.AddCell( "Russian language" ); 55 | Sheet.AddCell( L"Русский язык" ); 56 | Sheet.EndRow(); 57 | 58 | Sheet.BeginRow(); 59 | Sheet.AddCell( "Chinese language" ); 60 | Sheet.AddCell( L"中文" ); 61 | Sheet.EndRow(); 62 | 63 | Sheet.BeginRow(); 64 | Sheet.AddCell( "French language" ); 65 | Sheet.AddCell( L"le français" ); 66 | Sheet.EndRow(); 67 | 68 | Sheet.BeginRow(); 69 | Sheet.AddCell( "Arabic language" ); 70 | Sheet.AddCell( L"العَرَبِيَّة‎‎" ); 71 | Sheet.EndRow(); 72 | 73 | Sheet.BeginRow(); 74 | Sheet.EndRow(); 75 | 76 | style.fill.patternType = PATTERN_NONE; 77 | style.font.theme = true; 78 | style.horizAlign = ALIGN_H_RIGHT; 79 | style.vertAlign = ALIGN_V_CENTER; 80 | 81 | style.numFormat.numberStyle = NUMSTYLE_MONEY; 82 | 83 | size_t MoneyStyleIndex = book.AddStyle( style ); 84 | 85 | Sheet.BeginRow(); 86 | Sheet.AddCell( "Money symbol" ); 87 | Sheet.AddCell( 123.45, MoneyStyleIndex ); 88 | Sheet.EndRow(); 89 | 90 | style.numFormat.numberStyle = NUMSTYLE_DATETIME; 91 | size_t DateTimeStyleIndex = book.AddStyle( style ); 92 | 93 | Sheet.BeginRow(); 94 | Sheet.AddCell( "Write date/time" ); 95 | Sheet.AddCell( CurrentTime, DateTimeStyleIndex ); 96 | Sheet.EndRow(); 97 | 98 | style.numFormat.formatString = "hh:mm:ss"; 99 | size_t CustomDateTimeStyleIndex = book.AddStyle( style ); 100 | Sheet.BeginRow(); 101 | Sheet.AddCell( "Custom date/time" ); 102 | Sheet.AddCell( CurrentTime, CustomDateTimeStyleIndex ); 103 | Sheet.EndRow(); 104 | 105 | Sheet.BeginRow(); 106 | Sheet.EndRow(); 107 | 108 | Style stPanel; 109 | stPanel.border.top.style = BORDER_THIN; 110 | stPanel.border.bottom.color = "FF000000"; 111 | stPanel.fill.patternType = PATTERN_SOLID; 112 | stPanel.fill.fgColor = "FFCCCCFF"; 113 | size_t PanelStyleIndex = book.AddStyle( stPanel ); 114 | Sheet.BeginRow(); 115 | Sheet.AddCell( "Cells with border", PanelStyleIndex ); 116 | Sheet.AddCell( "", PanelStyleIndex ); 117 | Sheet.AddCell( "", PanelStyleIndex ); 118 | Sheet.AddCell( "", PanelStyleIndex ); 119 | Sheet.EndRow(); 120 | 121 | if( book.Save( "Simple.xlsx" ) ) std::cout << "The book has been saved successfully" << std::endl; 122 | else std::cout << "The book saving has been failed" << std::endl; 123 | 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/Chartsheet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "Chartsheet.h" 23 | 24 | #include "Chart.h" 25 | #include "Drawing.h" 26 | #include "Worksheet.h" 27 | #include "XlsxHeaders.h" 28 | 29 | #include "../PathManager.hpp" 30 | #include "../XMLWriter.hpp" 31 | 32 | namespace SimpleXlsx 33 | { 34 | // **************************************************************************** 35 | /// @brief The class constructor 36 | /// @param index index of a sheet to be created (for example, chart1.xml) 37 | /// @param chart is a reference for correspond chart 38 | /// @param drawing is a references for correspond drawing 39 | /// @param Parent is a pointer to parent CWorkbook 40 | /// @return no 41 | // **************************************************************************** 42 | const UniString &CChartsheet::GetTitle() const 43 | { 44 | return m_Chart.GetTitle(); 45 | } 46 | 47 | CChartsheet::CChartsheet( size_t index, CChart & chart, CDrawing & drawing, PathManager & pathmanager ) : 48 | CSheet( index ), m_Chart( chart ), m_Drawing( drawing ), m_pathManager( pathmanager ) 49 | { 50 | } 51 | 52 | // **************************************************************************** 53 | /// @brief The class destructor (virtual) 54 | /// @return no 55 | // **************************************************************************** 56 | CChartsheet::~CChartsheet() 57 | { 58 | } 59 | 60 | // **************************************************************************** 61 | /// @brief For each chart sheet it creates and saves 2 files: 62 | /// sheetXX.xml, sheetXX.xml.rels, 63 | /// @return Boolean result of the operation 64 | // **************************************************************************** 65 | bool CChartsheet::Save() 66 | { 67 | { 68 | // [- /xl/chartsheets/_rels/sheetX.xml.rels 69 | std::stringstream FileName; 70 | FileName << "/xl/chartsheets/_rels/sheet" << m_index << ".xml.rels"; 71 | 72 | std::stringstream Target; 73 | Target << "../drawings/drawing" << m_Drawing.GetIndex() << ".xml"; 74 | 75 | XMLWriter xmlw( m_pathManager.RegisterXML( FileName.str() ) ); 76 | xmlw.Tag( "Relationships" ).Attr( "xmlns", ns_relationships ); 77 | xmlw.TagL( "Relationship" ).Attr( "Id", "rId1" ).Attr( "Type", type_drawing ).Attr( "Target", Target.str() ).EndL(); 78 | 79 | xmlw.End( "Relationships" ); 80 | // /xl/chartsheets/_rels/sheetX.xml.rels -] 81 | } 82 | 83 | { 84 | // [- /xl/chartsheets/sheetX.xml 85 | std::stringstream FileName; 86 | FileName << "/xl/chartsheets/sheet" << m_index << ".xml"; 87 | 88 | XMLWriter xmlw( m_pathManager.RegisterXML( FileName.str() ) ); 89 | xmlw.Tag( "chartsheet" ).Attr( "xmlns", ns_book ).Attr( "xmlns:r", ns_book_r ).TagL( "sheetPr" ).EndL(); 90 | 91 | xmlw.Tag( "sheetViews" ); 92 | xmlw.TagL( "sheetView" ).Attr( "zoomScale", 85 ).Attr( "workbookViewId", 0 ).Attr( "zoomToFit", 1 ).EndL(); 93 | xmlw.End( "sheetViews" ); 94 | 95 | xmlw.TagL( "pageMargins" ).Attr( "left", 0.7 ).Attr( "right", 0.7 ).Attr( "top", 0.75 ); 96 | xmlw.Attr( "bottom", 0.75 ).Attr( "header", 0.3 ).Attr( "footer", 0.3 ).EndL(); 97 | xmlw.TagL( "drawing" ).Attr( "r:id", "rId1" ).EndL(); 98 | 99 | xmlw.End( "chartsheet" ); 100 | // /xl/chartsheets/sheetX.xml -] 101 | } 102 | return true; 103 | } 104 | 105 | } // namespace SimpleXlsx 106 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/Drawing.h: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XLSX_DRAWING_H 23 | #define XLSX_DRAWING_H 24 | 25 | #include "SimpleXlsxDef.h" 26 | 27 | namespace SimpleXlsx 28 | { 29 | class CChart; 30 | 31 | class PathManager; 32 | class XMLWriter; 33 | 34 | class CDrawing 35 | { 36 | public: 37 | //Index of Drawing 38 | inline size_t GetIndex() const 39 | { 40 | return m_index; 41 | } 42 | 43 | //Is no registered Charts 44 | inline bool IsEmpty() const 45 | { 46 | return m_drawings.empty(); 47 | } 48 | 49 | protected: 50 | CDrawing( size_t index, PathManager & pathmanager ); 51 | virtual ~CDrawing(); 52 | 53 | private: 54 | //Disable copy and assignment 55 | CDrawing( const CDrawing & that ); 56 | CDrawing & operator=( const CDrawing & ); 57 | 58 | size_t m_index; ///< Drawing ID number 59 | PathManager & m_pathManager; ///< reference to XML PathManager 60 | 61 | struct DrawingInfo 62 | { 63 | enum AnchorType 64 | { 65 | absoluteAnchor, //For CChartSheet 66 | twoCellAnchor, //For chart on CWorkSheet 67 | imageOneCellAnchor, //For image on CWorkSheet 68 | imageTwoCellAnchor, //For image on CWorkSheet 69 | }; 70 | 71 | CChart * Chart; 72 | CImage * Image; 73 | AnchorType AType; 74 | DrawingPoint TopLeft; //For drawing on CWorkSheet 75 | DrawingPoint BottomRight; //For drawing on CWorkSheet 76 | }; 77 | 78 | std::vector m_drawings; 79 | 80 | 81 | //Append Chart from Chartsheet 82 | inline void AppendChart( CChart * Chart ) 83 | { 84 | DrawingInfo CInfo = { Chart, NULL, DrawingInfo::absoluteAnchor, DrawingPoint(), DrawingPoint() }; 85 | m_drawings.push_back( CInfo ); 86 | } 87 | 88 | //Append Chart from Worksheet 89 | inline void AppendChart( CChart * Chart, const DrawingPoint & TopLeft, const DrawingPoint & BottomRight ) 90 | { 91 | DrawingInfo CInfo = { Chart, NULL, DrawingInfo::twoCellAnchor, TopLeft, BottomRight }; 92 | m_drawings.push_back( CInfo ); 93 | } 94 | 95 | //Append Image from Worksheet 96 | inline void AppendImage( CImage * Image, const DrawingPoint & TopLeft, uint16_t XPercent, uint16_t YPercent ) 97 | { 98 | DrawingPoint Dimen( uint32_t( Image->Width * XPercent ) * CImage::PointByPixel / 100, 99 | uint32_t( Image->Height * YPercent ) * CImage::PointByPixel / 100 ); 100 | DrawingInfo CInfo = { NULL, Image, DrawingInfo::imageOneCellAnchor, TopLeft, Dimen }; 101 | m_drawings.push_back( CInfo ); 102 | } 103 | inline void AppendImage( CImage * Image, const DrawingPoint & TopLeft, const DrawingPoint & BottomRight ) 104 | { 105 | DrawingInfo CInfo = { NULL, Image, DrawingInfo::imageTwoCellAnchor, TopLeft, BottomRight }; 106 | m_drawings.push_back( CInfo ); 107 | } 108 | 109 | bool Save(); 110 | 111 | void SaveDrawingRels(); 112 | void SaveDrawing(); 113 | void SaveChartSection( XMLWriter & xmlw, CChart * chart, int rId ); 114 | void SaveImageSection( XMLWriter & xmlw, CImage * image, int rId ); 115 | void SaveChartPoint( XMLWriter & xmlw, const char * Tag, const DrawingPoint & Point ); 116 | 117 | friend class CWorkbook; 118 | }; 119 | 120 | } 121 | 122 | #endif // XLSX_DRAWING_H 123 | -------------------------------------------------------------------------------- /Samples/Simple.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #ifdef _WIN32 10 | #include 11 | #endif 12 | 13 | #ifdef QT_CORE_LIB 14 | #include 15 | #endif 16 | 17 | using namespace SimpleXlsx; 18 | 19 | int main() 20 | { 21 | setlocale( LC_ALL, "" ); 22 | time_t CurTime = time( NULL ); 23 | 24 | CWorkbook book( "Incognito" ); 25 | std::vector ColWidth; 26 | ColWidth.push_back( ColumnWidth( 0, 3, 25 ) ); 27 | CWorksheet & Sheet = book.AddSheet( "Unicode", ColWidth ); 28 | 29 | Style style; 30 | style.horizAlign = ALIGN_H_CENTER; 31 | style.font.attributes = FONT_BOLD; 32 | const size_t CenterStyleIndex = book.AddStyle( style ); 33 | 34 | Sheet.BeginRow(); 35 | Sheet.AddCell( "Common test of Unicode support", CenterStyleIndex ); 36 | Sheet.MergeCells( CellCoord( 1, 0 ), CellCoord( 1, 3 ) ); 37 | Sheet.EndRow(); 38 | 39 | Font TmpFont = book.GetFonts().front(); 40 | TmpFont.attributes = FONT_ITALIC; 41 | Comment Com; 42 | Com.x = 300; 43 | Com.y = 100; 44 | Com.width = 100; 45 | Com.height = 30; 46 | Com.cellRef = CellCoord( 8, 1 ); 47 | Com.isHidden = false; 48 | Com.AddContent( TmpFont, "Comment with custom style" ); 49 | Sheet.AddComment( Com ); 50 | 51 | Sheet.BeginRow().AddCell( "English language" ).AddCell( "English language" ).EndRow(); 52 | Sheet.BeginRow().AddCell( "Russian language" ).AddCell( L"Русский язык" ).EndRow(); 53 | Sheet.BeginRow().AddCell( "Chinese language" ).AddCell( L"中文" ).EndRow(); 54 | Sheet.BeginRow().AddCell( "French language" ).AddCell( L"le français" ).EndRow(); 55 | Sheet.BeginRow().AddCell( "Arabic language" ).AddCell( L"العَرَبِيَّة‎‎" ).EndRow(); 56 | 57 | Sheet.AddEmptyRow(); 58 | 59 | style.fill.patternType = PATTERN_NONE; 60 | style.font.theme = true; 61 | style.horizAlign = ALIGN_H_RIGHT; 62 | style.vertAlign = ALIGN_V_CENTER; 63 | 64 | style.numFormat.numberStyle = NUMSTYLE_MONEY; 65 | const size_t MoneyStyleIndex = book.AddStyle( style ); 66 | Sheet.BeginRow().AddCell( "Money symbol" ).AddCell( 123.45, MoneyStyleIndex ).EndRow(); 67 | 68 | Style stPanel; 69 | stPanel.border.top.style = BORDER_THIN; 70 | stPanel.border.bottom.color = "FF000000"; 71 | stPanel.fill.patternType = PATTERN_SOLID; 72 | stPanel.fill.fgColor = "FFCCCCFF"; 73 | const size_t PanelStyleIndex = book.AddStyle( stPanel ); 74 | Sheet.AddEmptyRow().BeginRow(); 75 | Sheet.AddCell( "Cells with border", PanelStyleIndex ); 76 | Sheet.AddCell( "", PanelStyleIndex ).AddCell( "", PanelStyleIndex ).AddCell( "", PanelStyleIndex ); 77 | Sheet.EndRow(); 78 | 79 | style.numFormat.numberStyle = NUMSTYLE_DATETIME; 80 | style.font.attributes = FONT_NORMAL; 81 | style.horizAlign = ALIGN_H_LEFT; 82 | const size_t DateTimeStyleIndex = book.AddStyle( style ); 83 | Sheet.AddEmptyRow().AddSimpleRow( "time_t", CenterStyleIndex ); 84 | Sheet.AddSimpleRow( CellDataTime( CurTime, DateTimeStyleIndex ) ); 85 | 86 | Style stRotated; 87 | stRotated.horizAlign = EAlignHoriz::ALIGN_H_CENTER; 88 | stRotated.vertAlign = EAlignVert::ALIGN_V_CENTER; 89 | stRotated.textRotation = 45; 90 | const size_t RotatedStyleIndex = book.AddStyle( stRotated ); 91 | Sheet.AddSimpleRow( "Rotated text", RotatedStyleIndex, 3, 20 ); 92 | Sheet.MergeCells( CellCoord( 14, 3 ), CellCoord( 19, 3 ) ); 93 | 94 | /* Be careful with the style of date and time. 95 | * If milliseconds are specified, then the style used should take them into account. 96 | * Otherwise, Excel will round milliseconds and may change seconds. 97 | * See example below. */ 98 | style.numFormat.formatString = "yyyy.mm.dd hh:mm:ss.000"; 99 | const size_t CustomDateTimeStyleIndex = book.AddStyle( style ); 100 | Sheet.AddSimpleRow( "Direct date and time", CenterStyleIndex ); 101 | Sheet.AddSimpleRow( CellDataTime( 2020, 1, 1, 0, 0, 0, 500, CustomDateTimeStyleIndex ) ); 102 | Sheet.AddSimpleRow( CellDataTime( 2020, 1, 1, 0, 0, 0, 500, DateTimeStyleIndex ) ); 103 | Sheet.AddSimpleRow( CellDataTime( 2020, 1, 1, 0, 0, 0, 499, CustomDateTimeStyleIndex ) ); 104 | Sheet.AddSimpleRow( CellDataTime( 2020, 1, 1, 0, 0, 0, 499, DateTimeStyleIndex ) ); 105 | 106 | #ifdef _WIN32 107 | Sheet.AddEmptyRow().AddSimpleRow( "Windows SYSTEMTIME", CenterStyleIndex ); 108 | SYSTEMTIME lt; 109 | GetLocalTime( & lt ); 110 | Sheet.AddSimpleRow( CellDataTime( lt, CustomDateTimeStyleIndex ) ); 111 | #endif 112 | 113 | #if defined( QT_VERSION ) && ( QT_VERSION >= 0x040000 ) 114 | Sheet.AddEmptyRow().AddSimpleRow( "Qt QDateTime", CenterStyleIndex ); 115 | const QDateTime CurDT = QDateTime::currentDateTime(); 116 | Sheet.AddSimpleRow( CellDataTime( CurDT, CustomDateTimeStyleIndex ) ); 117 | #endif 118 | 119 | if( book.Save( "Simple.xlsx" ) ) std::cout << "The book has been saved successfully" << std::endl; 120 | else std::cout << "The book saving has been failed" << std::endl; 121 | return 0; 122 | } 123 | -------------------------------------------------------------------------------- /simplexlsx-code/PathManager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | #include "PathManager.hpp" 32 | 33 | #ifdef _WIN32 34 | #include 35 | #include 36 | #else 37 | #include 38 | #include 39 | #include 40 | #include 41 | #endif 42 | 43 | namespace SimpleXlsx 44 | { 45 | 46 | //Creating all necessary subdirectories and copy image file 47 | bool PathManager::RegisterImage( const std::string & LocalPath, const std::string & XLSX_Path ) 48 | { 49 | std::ifstream Source( LocalPath.c_str(), std::ios::binary ); 50 | if( Source.is_open() ) 51 | { 52 | const std::string InternalPath = RegisterFile( XLSX_Path ); 53 | std::ofstream Destination( InternalPath.c_str(), std::ios::binary ); 54 | if( Destination.is_open() ) 55 | { 56 | Destination << Source.rdbuf(); 57 | return true; 58 | } 59 | } 60 | return false; 61 | } 62 | 63 | //Deletes all temporary files and directories which have been created 64 | void PathManager::ClearTemp() 65 | { 66 | for( std::vector< std::string >::const_iterator it = m_contentFiles.begin(); it != m_contentFiles.end(); it++ ) 67 | remove( ( m_temp_path + ( * it ) ).c_str() ); 68 | m_contentFiles.clear(); 69 | for( std::vector< std::string >::const_reverse_iterator it = m_temp_dirs.rbegin(); it != m_temp_dirs.rend(); it++ ) 70 | #ifdef _WIN32 71 | _rmdir( ( * it ).c_str() ); 72 | #else 73 | rmdir( ( *it ).c_str() ); 74 | #endif 75 | m_temp_dirs.clear(); 76 | } 77 | 78 | // **************************************************************************** 79 | /// @brief Function to create nested directories` tree 80 | /// @param dirName directories` tree to be created 81 | /// @return Boolean result of the operation 82 | // **************************************************************************** 83 | bool PathManager::MakeDirectory( const std::string & dirName ) 84 | { 85 | std::string part = ""; 86 | size_t oldPointer = 0; 87 | size_t currPointer = 0; 88 | int32_t res = -1; 89 | 90 | for( size_t i = 0; i < dirName.length(); i++ ) 91 | { 92 | if( ( dirName.at( i ) == '\\' ) || ( dirName.at( i ) == '/' ) ) 93 | { 94 | part += dirName.substr( oldPointer, currPointer - oldPointer ) + "/"; 95 | oldPointer = currPointer + 1; 96 | #ifdef _WIN32 97 | std::replace( part.begin(), part.end(), '/', '\\' ); 98 | res = _mkdir( part.c_str() ); 99 | #else 100 | res = mkdir( part.c_str(), 0777 ); 101 | #endif 102 | if( res == 0 ) m_temp_dirs.push_back( part ); //Remember the created subdirectories 103 | if( ( res == -1 ) && ( errno == ENOENT ) ) return false; 104 | } 105 | currPointer++; 106 | } 107 | return true; 108 | } 109 | 110 | #if ! defined( _WIN32 ) //Linux with Unicode 111 | std::string PathManager::PathEncode( const wchar_t * Path ) 112 | { 113 | mbstate_t MbState; 114 | const wchar_t * Ptr = Path; 115 | //mbrlen( NULL, 0, & MbState ); 116 | std::memset( & MbState, 0, sizeof( MbState ) ); 117 | std::size_t BufSize = wcsrtombs( NULL, & Ptr, 0, & MbState ); 118 | if( ( BufSize == static_cast( -1 ) ) || ( BufSize == 0 ) ) return ""; 119 | std::vector MbVector( BufSize + 1, 0 ); 120 | wcsrtombs( MbVector.data(), & Ptr, BufSize, & MbState ); 121 | MbVector[ BufSize ] = '\0'; 122 | return MbVector.data(); 123 | } 124 | 125 | #else //Windows with Unicode 126 | std::string PathManager::PathEncode( const wchar_t * Path ) 127 | { 128 | int Length = static_cast< int >( wcslen( Path ) ); 129 | int ResultSize = WideCharToMultiByte( CP_ACP, 0, Path, Length, NULL, 0, NULL, NULL ); 130 | std::vector AnsiFileName( ResultSize + 1, 0 ); 131 | WideCharToMultiByte( CP_ACP, 0, Path, Length, AnsiFileName.data(), ResultSize, NULL, NULL ); 132 | return AnsiFileName.data(); 133 | } 134 | #endif 135 | 136 | } 137 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/XlsxHeaders.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "XlsxHeaders.h" 23 | 24 | namespace SimpleXlsx 25 | { 26 | const char * ns_content_types = "http://schemas.openxmlformats.org/package/2006/content-types"; 27 | const char * content_printer = "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings"; 28 | const char * content_rels = "application/vnd.openxmlformats-package.relationships+xml"; 29 | const char * content_xml = "application/xml"; 30 | const char * content_book = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"; 31 | const char * content_sheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"; 32 | const char * content_theme = "application/vnd.openxmlformats-officedocument.theme+xml"; 33 | const char * content_styles = "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"; 34 | const char * content_sharedStr = "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"; 35 | const char * content_comment = "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml"; 36 | const char * content_vml = "application/vnd.openxmlformats-officedocument.vmlDrawing"; 37 | const char * content_core = "application/vnd.openxmlformats-package.core-properties+xml"; 38 | const char * content_app = "application/vnd.openxmlformats-officedocument.extended-properties+xml"; 39 | const char * content_chart = "application/vnd.openxmlformats-officedocument.drawingml.chart+xml"; 40 | const char * content_drawing = "application/vnd.openxmlformats-officedocument.drawing+xml"; 41 | const char * content_chartsheet = "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml"; 42 | const char * content_chain = "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml"; 43 | 44 | const char * ns_markup_compatibility = "http://schemas.openxmlformats.org/markup-compatibility/2006"; 45 | const char * ns_c14 = "http://schemas.microsoft.com/office/drawing/2007/8/2/chart"; 46 | const char * ns_relationships_chart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; 47 | 48 | const char * ns_relationships = "http://schemas.openxmlformats.org/package/2006/relationships"; 49 | const char * type_book = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument"; 50 | const char * type_core = "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties"; 51 | const char * type_app = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties"; 52 | 53 | const char * ns_cp = "http://schemas.openxmlformats.org/package/2006/metadata/core-properties"; 54 | const char * ns_dc = "http://purl.org/dc/elements/1.1/"; 55 | const char * ns_dcterms = "http://purl.org/dc/terms/"; 56 | const char * ns_dcmitype = "http://purl.org/dc/dcmitype/"; 57 | const char * ns_xsi = "http://www.w3.org/2001/XMLSchema-instance"; 58 | const char * xsi_type = "dcterms:W3CDTF"; 59 | 60 | const char * ns_doc_prop = "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties"; 61 | const char * ns_vt = "http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"; 62 | 63 | const char * ns_book = "http://schemas.openxmlformats.org/spreadsheetml/2006/main"; 64 | const char * ns_book_r = "http://schemas.openxmlformats.org/officeDocument/2006/relationships"; 65 | 66 | const char * ns_mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"; 67 | const char * ns_x14ac = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac"; 68 | 69 | const char * ns_x14 = "http://schemas.microsoft.com/office/spreadsheetml/2009/9/main"; 70 | 71 | const char * type_comments = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments"; 72 | const char * type_vml = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing"; 73 | const char * type_sheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet"; 74 | const char * type_style = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"; 75 | const char * type_sharedStr = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings"; 76 | const char * type_theme = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme"; 77 | const char * type_chain = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/calcChain"; 78 | const char * type_chartsheet = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet"; 79 | const char * type_chart = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart"; 80 | const char * type_drawing = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing"; 81 | const char * type_image = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image"; 82 | 83 | const char * ns_a = "http://schemas.openxmlformats.org/drawingml/2006/main"; 84 | const char * ns_c = "http://schemas.openxmlformats.org/drawingml/2006/chart"; 85 | const char * ns_xdr = "http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing"; 86 | } 87 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # QSimpleXlsxWriter 2 | 3 | ## Introduction 4 | 5 | - Use SimpleXlsxWriter in Qt. 6 | - [SimpleXlsxWriter](https://sourceforge.net/projects/simplexlsx/) is C++ library for creating XLSX files for MS Excel 2007 and above. 7 | - Brought to you by: [oxod](https://sourceforge.net/u/oxod/), [programmeralex](https://sourceforge.net/u/programmeralex/) 8 | - The main feature of this library is that it uses C++ standard file streams. On the one hand it results in almost unnoticeable memory and CPU resources consumption while processing (that may be very useful at saving a large data arrays), but on the other hand it makes unfeasible to edit data that were written. Hence, if using this library the structure of the future report should be known enough. 9 | 10 | ## Hello World (Simple.cpp) 11 | 12 | ```cpp 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | using namespace SimpleXlsx; 22 | 23 | int main( int argc, char * argv[] ) 24 | { 25 | ( void )argc; ( void )argv; 26 | 27 | setlocale( LC_ALL, "" ); 28 | 29 | time_t CurrentTime = time( NULL ); 30 | 31 | CWorkbook book( "Incognito" ); 32 | 33 | std::vector ColWidth; 34 | ColWidth.push_back( ColumnWidth( 0, 3, 20 ) ); 35 | CWorksheet & Sheet = book.AddSheet( "Unicode", ColWidth ); 36 | 37 | Style style; 38 | style.horizAlign = ALIGN_H_CENTER; 39 | style.font.attributes = FONT_BOLD; 40 | size_t CenterStyleIndex = book.AddStyle( style ); 41 | 42 | Sheet.BeginRow(); 43 | Sheet.AddCell( "Common test of Unicode support", CenterStyleIndex ); 44 | Sheet.MergeCells( CellCoord( 1, 0 ), CellCoord( 1, 3 ) ); 45 | Sheet.EndRow(); 46 | 47 | Font TmpFont = book.GetFonts().front(); 48 | TmpFont.attributes = FONT_ITALIC; 49 | Comment Com; 50 | Com.x = 250; 51 | Com.y = 100; 52 | Com.width = 100; 53 | Com.height = 30; 54 | Com.cellRef = CellCoord( 8, 1 ); 55 | Com.isHidden = false; 56 | Com.AddContent( TmpFont, "Comment with custom style" ); 57 | Sheet.AddComment( Com ); 58 | 59 | Sheet.BeginRow(); 60 | Sheet.AddCell( "English language" ); 61 | Sheet.AddCell( "English language" ); 62 | Sheet.EndRow(); 63 | 64 | Sheet.BeginRow(); 65 | Sheet.AddCell( "Russian language" ); 66 | Sheet.AddCell( L"Русский язык" ); 67 | Sheet.EndRow(); 68 | 69 | Sheet.BeginRow(); 70 | Sheet.AddCell( "Chinese language" ); 71 | Sheet.AddCell( L"中文" ); 72 | Sheet.EndRow(); 73 | 74 | Sheet.BeginRow(); 75 | Sheet.AddCell( "French language" ); 76 | Sheet.AddCell( L"le français" ); 77 | Sheet.EndRow(); 78 | 79 | Sheet.BeginRow(); 80 | Sheet.AddCell( "Arabic language" ); 81 | Sheet.AddCell( L"العَرَبِيَّة‎‎" ); 82 | Sheet.EndRow(); 83 | 84 | Sheet.BeginRow(); 85 | Sheet.EndRow(); 86 | 87 | style.fill.patternType = PATTERN_NONE; 88 | style.font.theme = true; 89 | style.horizAlign = ALIGN_H_RIGHT; 90 | style.vertAlign = ALIGN_V_CENTER; 91 | 92 | style.numFormat.numberStyle = NUMSTYLE_MONEY; 93 | 94 | size_t MoneyStyleIndex = book.AddStyle( style ); 95 | 96 | Sheet.BeginRow(); 97 | Sheet.AddCell( "Money symbol" ); 98 | Sheet.AddCell( 123.45, MoneyStyleIndex ); 99 | Sheet.EndRow(); 100 | 101 | style.numFormat.numberStyle = NUMSTYLE_DATETIME; 102 | size_t DateTimeStyleIndex = book.AddStyle( style ); 103 | 104 | Sheet.BeginRow(); 105 | Sheet.AddCell( "Write date/time" ); 106 | Sheet.AddCell( CurrentTime, DateTimeStyleIndex ); 107 | Sheet.EndRow(); 108 | 109 | style.numFormat.formatString = "hh:mm:ss"; 110 | size_t CustomDateTimeStyleIndex = book.AddStyle( style ); 111 | Sheet.BeginRow(); 112 | Sheet.AddCell( "Custom date/time" ); 113 | Sheet.AddCell( CurrentTime, CustomDateTimeStyleIndex ); 114 | Sheet.EndRow(); 115 | 116 | Sheet.BeginRow(); 117 | Sheet.EndRow(); 118 | 119 | Style stPanel; 120 | stPanel.border.top.style = BORDER_THIN; 121 | stPanel.border.bottom.color = "FF000000"; 122 | stPanel.fill.patternType = PATTERN_SOLID; 123 | stPanel.fill.fgColor = "FFCCCCFF"; 124 | size_t PanelStyleIndex = book.AddStyle( stPanel ); 125 | Sheet.BeginRow(); 126 | Sheet.AddCell( "Cells with border", PanelStyleIndex ); 127 | Sheet.AddCell( "", PanelStyleIndex ); 128 | Sheet.AddCell( "", PanelStyleIndex ); 129 | Sheet.AddCell( "", PanelStyleIndex ); 130 | Sheet.EndRow(); 131 | 132 | if( book.Save( "Simple.xlsx" ) ) std::cout << "The book has been saved successfully" << std::endl; 133 | else std::cout << "The book saving has been failed" << std::endl; 134 | 135 | return 0; 136 | } 137 | ``` 138 | 139 | ## Test 140 | 141 | | Travis CI | 142 | | :-------: | 143 | | [![Build Status](https://travis-ci.com/QtExcel/QSimpleXlsxWriter.svg?branch=master)](https://travis-ci.com/QtExcel/QSimpleXlsxWriter) | 144 | 145 | ## License and links 146 | - QSimpleXlsxWriter is under MIT license. [https://github.com/QtExcel/QSimpleXlsxWriter](https://github.com/QtExcel/QSimpleXlsxWriter) 147 | - SimpleXlsxWriter is under zlib license. [https://sourceforge.net/projects/simplexlsx/](https://sourceforge.net/projects/simplexlsx/) 148 | - zlib is under zlib license. [https://zlib.net/](https://zlib.net/) 149 | 150 | ## Similar projects 151 | 152 | ### :star: QXlsx [https://github.com/QtExcel/QXlsx](https://github.com/QtExcel/QXlsx) 153 | 154 |

155 | 156 | - QXlsx is excel file(*.xlsx) reader/writer library. 157 | - Because QtXlsx is no longer supported(2014), I created a new project that is based on QtXlsx. (2017-) 158 | - Development language of QXlsx is C++. (with Qt) 159 | - You don't need to use static library or dynamic shared object using QXlsx. 160 | 161 | ### :star: Qxlnt [https://github.com/QtExcel/Qxlnt](https://github.com/QtExcel/Qxlnt) 162 | 163 |

164 | 165 | - Qxlnt is a helper project that allows xlnt to be used in Qt. 166 | - xlnt is a excellent C++ library for using xlsx Excel files. :+1: 167 | - I was looking for a way to make it easy to use in Qt. Of course, cmake is compatible with Qt, but it is not convenient to use. So I created Qxlnt. 168 | 169 | ### :star: Qlibxlsxwriter [https://github.com/QtExcel/Qlibxlsxwriter](https://github.com/QtExcel/Qlibxlsxwriter) 170 | 171 |

172 | 173 | - Qlibxlsxwriter is a helper project that allows libxlsxwriter to be used in Qt. 174 | - libxlsxwriter is a C library for creating Excel XLSX files. :+1: 175 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # C++ objects and libs 2 | *.slo 3 | *.lo 4 | *.o 5 | *.a 6 | *.la 7 | *.lai 8 | *.so 9 | *.dll 10 | *.dylib 11 | 12 | # Qt-es 13 | object_script.*.Release 14 | object_script.*.Debug 15 | *_plugin_import.cpp 16 | /.qmake.cache 17 | /.qmake.stash 18 | *.pro.user 19 | *.pro.user.* 20 | *.qbs.user 21 | *.qbs.user.* 22 | *.moc 23 | moc_*.cpp 24 | moc_*.h 25 | qrc_*.cpp 26 | ui_*.h 27 | *.qmlc 28 | *.jsc 29 | Makefile* 30 | *build-* 31 | 32 | # Qt unit tests 33 | target_wrapper.* 34 | 35 | # QtCreator 36 | *.autosave 37 | 38 | # QtCreator Qml 39 | *.qmlproject.user 40 | *.qmlproject.user.* 41 | 42 | # QtCreator CMake 43 | CMakeLists.txt.user* 44 | 45 | ## Ignore Visual Studio temporary files, build results, and 46 | ## files generated by popular Visual Studio add-ons. 47 | ## 48 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 49 | 50 | # User-specific files 51 | *.rsuser 52 | *.suo 53 | *.user 54 | *.userosscache 55 | *.sln.docstates 56 | 57 | # User-specific files (MonoDevelop/Xamarin Studio) 58 | *.userprefs 59 | 60 | # Build results 61 | [Dd]ebug/ 62 | [Dd]ebugPublic/ 63 | [Rr]elease/ 64 | [Rr]eleases/ 65 | x64/ 66 | x86/ 67 | bld/ 68 | [Bb]in/ 69 | [Oo]bj/ 70 | [Ll]og/ 71 | 72 | # Visual Studio 2015/2017 cache/options directory 73 | .vs/ 74 | # Uncomment if you have tasks that create the project's static files in wwwroot 75 | #wwwroot/ 76 | 77 | # Visual Studio 2017 auto generated files 78 | Generated\ Files/ 79 | 80 | # MSTest test Results 81 | [Tt]est[Rr]esult*/ 82 | [Bb]uild[Ll]og.* 83 | 84 | # NUNIT 85 | *.VisualState.xml 86 | TestResult.xml 87 | 88 | # Build Results of an ATL Project 89 | [Dd]ebugPS/ 90 | [Rr]eleasePS/ 91 | dlldata.c 92 | 93 | # Benchmark Results 94 | BenchmarkDotNet.Artifacts/ 95 | 96 | # .NET Core 97 | project.lock.json 98 | project.fragment.lock.json 99 | artifacts/ 100 | 101 | # StyleCop 102 | StyleCopReport.xml 103 | 104 | # Files built by Visual Studio 105 | *_i.c 106 | *_p.c 107 | *_h.h 108 | *.ilk 109 | *.meta 110 | *.obj 111 | *.iobj 112 | *.pch 113 | *.pdb 114 | *.ipdb 115 | *.pgc 116 | *.pgd 117 | *.rsp 118 | *.sbr 119 | *.tlb 120 | *.tli 121 | *.tlh 122 | *.tmp 123 | *.tmp_proj 124 | *_wpftmp.csproj 125 | *.log 126 | *.vspscc 127 | *.vssscc 128 | .builds 129 | *.pidb 130 | *.svclog 131 | *.scc 132 | 133 | # Chutzpah Test files 134 | _Chutzpah* 135 | 136 | # Visual C++ cache files 137 | ipch/ 138 | *.aps 139 | *.ncb 140 | *.opendb 141 | *.opensdf 142 | *.sdf 143 | *.cachefile 144 | *.VC.db 145 | *.VC.VC.opendb 146 | 147 | # Visual Studio profiler 148 | *.psess 149 | *.vsp 150 | *.vspx 151 | *.sap 152 | 153 | # Visual Studio Trace Files 154 | *.e2e 155 | 156 | # TFS 2012 Local Workspace 157 | $tf/ 158 | 159 | # Guidance Automation Toolkit 160 | *.gpState 161 | 162 | # ReSharper is a .NET coding add-in 163 | _ReSharper*/ 164 | *.[Rr]e[Ss]harper 165 | *.DotSettings.user 166 | 167 | # JustCode is a .NET coding add-in 168 | .JustCode 169 | 170 | # TeamCity is a build add-in 171 | _TeamCity* 172 | 173 | # DotCover is a Code Coverage Tool 174 | *.dotCover 175 | 176 | # AxoCover is a Code Coverage Tool 177 | .axoCover/* 178 | !.axoCover/settings.json 179 | 180 | # Visual Studio code coverage results 181 | *.coverage 182 | *.coveragexml 183 | 184 | # NCrunch 185 | _NCrunch_* 186 | .*crunch*.local.xml 187 | nCrunchTemp_* 188 | 189 | # MightyMoose 190 | *.mm.* 191 | AutoTest.Net/ 192 | 193 | # Web workbench (sass) 194 | .sass-cache/ 195 | 196 | # Installshield output folder 197 | [Ee]xpress/ 198 | 199 | # DocProject is a documentation generator add-in 200 | DocProject/buildhelp/ 201 | DocProject/Help/*.HxT 202 | DocProject/Help/*.HxC 203 | DocProject/Help/*.hhc 204 | DocProject/Help/*.hhk 205 | DocProject/Help/*.hhp 206 | DocProject/Help/Html2 207 | DocProject/Help/html 208 | 209 | # Click-Once directory 210 | publish/ 211 | 212 | # Publish Web Output 213 | *.[Pp]ublish.xml 214 | *.azurePubxml 215 | # Note: Comment the next line if you want to checkin your web deploy settings, 216 | # but database connection strings (with potential passwords) will be unencrypted 217 | *.pubxml 218 | *.publishproj 219 | 220 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 221 | # checkin your Azure Web App publish settings, but sensitive information contained 222 | # in these scripts will be unencrypted 223 | PublishScripts/ 224 | 225 | # NuGet Packages 226 | *.nupkg 227 | # The packages folder can be ignored because of Package Restore 228 | **/[Pp]ackages/* 229 | # except build/, which is used as an MSBuild target. 230 | !**/[Pp]ackages/build/ 231 | # Uncomment if necessary however generally it will be regenerated when needed 232 | #!**/[Pp]ackages/repositories.config 233 | # NuGet v3's project.json files produces more ignorable files 234 | *.nuget.props 235 | *.nuget.targets 236 | 237 | # Microsoft Azure Build Output 238 | csx/ 239 | *.build.csdef 240 | 241 | # Microsoft Azure Emulator 242 | ecf/ 243 | rcf/ 244 | 245 | # Windows Store app package directories and files 246 | AppPackages/ 247 | BundleArtifacts/ 248 | Package.StoreAssociation.xml 249 | _pkginfo.txt 250 | *.appx 251 | 252 | # Visual Studio cache files 253 | # files ending in .cache can be ignored 254 | *.[Cc]ache 255 | # but keep track of directories ending in .cache 256 | !*.[Cc]ache/ 257 | 258 | # Others 259 | ClientBin/ 260 | ~$* 261 | *~ 262 | *.dbmdl 263 | *.dbproj.schemaview 264 | *.jfm 265 | *.pfx 266 | *.publishsettings 267 | orleans.codegen.cs 268 | 269 | # Including strong name files can present a security risk 270 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 271 | #*.snk 272 | 273 | # Since there are multiple workflows, uncomment next line to ignore bower_components 274 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 275 | #bower_components/ 276 | 277 | # RIA/Silverlight projects 278 | Generated_Code/ 279 | 280 | # Backup & report files from converting an old project file 281 | # to a newer Visual Studio version. Backup files are not needed, 282 | # because we have git ;-) 283 | _UpgradeReport_Files/ 284 | Backup*/ 285 | UpgradeLog*.XML 286 | UpgradeLog*.htm 287 | ServiceFabricBackup/ 288 | *.rptproj.bak 289 | 290 | # SQL Server files 291 | *.mdf 292 | *.ldf 293 | *.ndf 294 | 295 | # Business Intelligence projects 296 | *.rdl.data 297 | *.bim.layout 298 | *.bim_*.settings 299 | *.rptproj.rsuser 300 | 301 | # Microsoft Fakes 302 | FakesAssemblies/ 303 | 304 | # GhostDoc plugin setting file 305 | *.GhostDoc.xml 306 | 307 | # Node.js Tools for Visual Studio 308 | .ntvs_analysis.dat 309 | node_modules/ 310 | 311 | # Visual Studio 6 build log 312 | *.plg 313 | 314 | # Visual Studio 6 workspace options file 315 | *.opt 316 | 317 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 318 | *.vbw 319 | 320 | # Visual Studio LightSwitch build output 321 | **/*.HTMLClient/GeneratedArtifacts 322 | **/*.DesktopClient/GeneratedArtifacts 323 | **/*.DesktopClient/ModelManifest.xml 324 | **/*.Server/GeneratedArtifacts 325 | **/*.Server/ModelManifest.xml 326 | _Pvt_Extensions 327 | 328 | # Paket dependency manager 329 | .paket/paket.exe 330 | paket-files/ 331 | 332 | # FAKE - F# Make 333 | .fake/ 334 | 335 | # JetBrains Rider 336 | .idea/ 337 | *.sln.iml 338 | 339 | # CodeRush personal settings 340 | .cr/personal 341 | 342 | # Python Tools for Visual Studio (PTVS) 343 | __pycache__/ 344 | *.pyc 345 | 346 | # Cake - Uncomment if you are using it 347 | # tools/** 348 | # !tools/packages.config 349 | 350 | # Tabs Studio 351 | *.tss 352 | 353 | # Telerik's JustMock configuration file 354 | *.jmconfig 355 | 356 | # BizTalk build output 357 | *.btp.cs 358 | *.btm.cs 359 | *.odx.cs 360 | *.xsd.cs 361 | 362 | # OpenCover UI analysis results 363 | OpenCover/ 364 | 365 | # Azure Stream Analytics local run output 366 | ASALocalRun/ 367 | 368 | # MSBuild Binary and Structured Log 369 | *.binlog 370 | 371 | # NVidia Nsight GPU debugger configuration file 372 | *.nvuser 373 | 374 | # MFractors (Xamarin productivity tool) working folder 375 | .mfractor/ 376 | 377 | # Local History for Visual Studio 378 | .localhistory/ 379 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/Drawing.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "Drawing.h" 23 | 24 | #include "Chart.h" 25 | #include "XlsxHeaders.h" 26 | 27 | #include "../PathManager.hpp" 28 | #include "../XMLWriter.hpp" 29 | 30 | 31 | namespace SimpleXlsx 32 | { 33 | CDrawing::CDrawing( size_t index, PathManager & pathmanager ) : m_index( index ), m_pathManager( pathmanager ) 34 | { 35 | } 36 | 37 | CDrawing::~CDrawing() 38 | { 39 | } 40 | 41 | bool CDrawing::Save() 42 | { 43 | if( ! IsEmpty() ) 44 | { 45 | SaveDrawingRels(); 46 | SaveDrawing(); 47 | } 48 | return true; 49 | } 50 | 51 | // [- /xl/drawings/_rels/drawingX.xml.rels 52 | void CDrawing::SaveDrawingRels() 53 | { 54 | std::stringstream FileName; 55 | FileName << "/xl/drawings/_rels/drawing" << m_index << ".xml.rels"; 56 | 57 | XMLWriter xmlw( m_pathManager.RegisterXML( FileName.str() ) ); 58 | xmlw.Tag( "Relationships" ).Attr( "xmlns", ns_relationships ); 59 | int rId = 1; 60 | for( std::vector::const_iterator it = m_drawings.begin(); it != m_drawings.end(); it++, rId++ ) 61 | { 62 | std::stringstream Target, rIdStream; 63 | const char * TypeString = NULL; 64 | switch( ( * it ).AType ) 65 | { 66 | case DrawingInfo::absoluteAnchor: 67 | case DrawingInfo::twoCellAnchor: 68 | { 69 | TypeString = type_chart; 70 | Target << "../charts/chart" << ( *it ).Chart->GetIndex() << ".xml"; 71 | break; 72 | } 73 | case DrawingInfo::imageOneCellAnchor: 74 | case DrawingInfo::imageTwoCellAnchor: 75 | { 76 | TypeString = type_image; 77 | Target << "../media/" << ( *it ).Image->InternalName; 78 | break; 79 | } 80 | } 81 | rIdStream << "rId" << rId; 82 | 83 | xmlw.TagL( "Relationship" ).Attr( "Id", rIdStream.str() ).Attr( "Type", TypeString ).Attr( "Target", Target.str() ).EndL(); 84 | } 85 | xmlw.End( "Relationships" ); 86 | } 87 | 88 | // [- /xl/drawings/drawingX.xml 89 | void CDrawing::SaveDrawing() 90 | { 91 | std::stringstream FileName; 92 | FileName << "/xl/drawings/drawing" << m_index << ".xml"; 93 | 94 | XMLWriter xmlw( m_pathManager.RegisterXML( FileName.str() ) ); 95 | xmlw.Tag( "xdr:wsDr" ).Attr( "xmlns:xdr", ns_xdr ).Attr( "xmlns:a", ns_a ); 96 | 97 | int rId = 1; 98 | for( std::vector< DrawingInfo >::const_iterator it = m_drawings.begin(); it != m_drawings.end(); it++, rId++ ) 99 | { 100 | switch( ( * it ).AType ) 101 | { 102 | case DrawingInfo::absoluteAnchor: 103 | { 104 | xmlw.Tag( "xdr:absoluteAnchor" ); 105 | xmlw.TagL( "xdr:pos" ).Attr( "x", 0 ).Attr( "y", 0 ).EndL(); 106 | xmlw.TagL( "xdr:ext" ).Attr( "cx", 9312088 ).Attr( "cy", 6084794 ).EndL(); 107 | SaveChartSection( xmlw, ( * it ).Chart, rId ); 108 | xmlw.End( "xdr:absoluteAnchor" ); 109 | break; 110 | } 111 | case DrawingInfo::twoCellAnchor: 112 | { 113 | xmlw.Tag( "xdr:twoCellAnchor" ); 114 | SaveChartPoint( xmlw, "xdr:from", ( * it ).TopLeft ); 115 | SaveChartPoint( xmlw, "xdr:to", ( * it ).BottomRight ); 116 | SaveChartSection( xmlw, ( * it ).Chart, rId ); 117 | xmlw.End( "xdr:twoCellAnchor" ); 118 | break; 119 | } 120 | case DrawingInfo::imageOneCellAnchor: 121 | { 122 | xmlw.Tag( "xdr:oneCellAnchor" ).Attr( "editAs", "oneCell" ); 123 | SaveChartPoint( xmlw, "xdr:from", ( * it ).TopLeft ); 124 | xmlw.TagL( "xdr:ext" ).Attr( "cx", ( * it ).BottomRight.col ).Attr( "cy", ( * it ).BottomRight.row ).EndL(); 125 | SaveImageSection( xmlw, ( * it ).Image, rId ); 126 | xmlw.End( "xdr:oneCellAnchor" ); 127 | break; 128 | } 129 | case DrawingInfo::imageTwoCellAnchor: 130 | { 131 | xmlw.Tag( "xdr:twoCellAnchor" ); 132 | SaveChartPoint( xmlw, "xdr:from", ( * it ).TopLeft ); 133 | SaveChartPoint( xmlw, "xdr:to", ( * it ).BottomRight ); 134 | SaveImageSection( xmlw, ( * it ).Image, rId ); 135 | xmlw.End( "xdr:twoCellAnchor" ); 136 | break; 137 | } 138 | } 139 | } 140 | xmlw.End( "xdr:wsDr" ); 141 | } 142 | 143 | void CDrawing::SaveChartSection( XMLWriter & xmlw, CChart * chart, int rId ) 144 | { 145 | std::stringstream rIdStream; 146 | rIdStream << "rId" << rId; 147 | 148 | xmlw.Tag( "xdr:graphicFrame" ).Attr( "macro", "" ).Tag( "xdr:nvGraphicFramePr" ); 149 | xmlw.TagL( "xdr:cNvPr" ).Attr( "id", rId ).Attr( "name", chart->GetTitle() ).EndL(); 150 | xmlw.Tag( "xdr:cNvGraphicFramePr" ).TagL( "a:graphicFrameLocks" ).Attr( "noGrp", 1 ).EndL().End( "xdr:cNvGraphicFramePr" ); 151 | xmlw.End( "xdr:nvGraphicFramePr" ); 152 | 153 | xmlw.Tag( "xdr:xfrm" ); 154 | xmlw.TagL( "a:off" ).Attr( "x", 0 ).Attr( "y", 0 ).EndL(); 155 | xmlw.TagL( "a:ext" ).Attr( "cx", 0 ).Attr( "cy", 0 ).EndL(); 156 | xmlw.End( "xdr:xfrm" ); 157 | 158 | xmlw.Tag( "a:graphic" ).Tag( "a:graphicData" ).Attr( "uri", ns_c ); 159 | xmlw.TagL( "c:chart" ).Attr( "xmlns:c", ns_c ).Attr( "xmlns:r", ns_book_r ).Attr( "r:id", rIdStream.str() ).EndL(); 160 | xmlw.End( "a:graphicData" ).End( "a:graphic" ); 161 | 162 | xmlw.End( "xdr:graphicFrame" ); 163 | xmlw.TagL( "xdr:clientData" ).EndL(); 164 | } 165 | 166 | void CDrawing::SaveImageSection( XMLWriter & xmlw, CImage * image, int rId ) 167 | { 168 | std::stringstream rIdStream; 169 | rIdStream << "rId" << rId; 170 | 171 | xmlw.Tag( "xdr:pic" ).Tag( "xdr:nvPicPr" ); 172 | xmlw.TagL( "xdr:cNvPr" ).Attr( "id", rId ).Attr( "name", image->InternalName ).EndL(); 173 | xmlw.Tag( "xdr:cNvPicPr" ).TagL( "a:picLocks" ).Attr( "noChangeAspect", 1 ).EndL().End( "xdr:cNvPicPr" ); 174 | xmlw.End( "xdr:nvPicPr" ); 175 | 176 | xmlw.Tag( "xdr:blipFill" ); 177 | xmlw.Tag( "a:blip" ).Attr( "xmlns:r", ns_relationships_chart ).Attr( "r:embed", rIdStream.str() ); 178 | xmlw.End( "a:blip" ); 179 | xmlw.Tag( "a:stretch" ).TagL( "a:fillRect" ).EndL().End( "a:stretch" ); 180 | xmlw.End( "xdr:blipFill" ); 181 | 182 | xmlw.Tag( "xdr:spPr" ); 183 | xmlw.Tag( "a:prstGeom" ).Attr( "prst", "rect" ).TagL( "a:avLst" ).EndL().End( "a:prstGeom" ); 184 | xmlw.End( "xdr:spPr" ); 185 | 186 | xmlw.End( "xdr:pic" ); 187 | 188 | xmlw.TagL( "xdr:clientData" ).EndL(); 189 | } 190 | 191 | void CDrawing::SaveChartPoint( XMLWriter & xmlw, const char * Tag, const DrawingPoint & Point ) 192 | { 193 | xmlw.Tag( Tag ); 194 | xmlw.TagOnlyContent( "xdr:col", Point.col ); 195 | xmlw.TagOnlyContent( "xdr:colOff", Point.colOff ); 196 | xmlw.TagOnlyContent( "xdr:row", Point.row ); 197 | xmlw.TagOnlyContent( "xdr:rowOff", Point.rowOff ); 198 | xmlw.End( Tag ); 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /Samples/Scientific.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace SimpleXlsx; 11 | 12 | static void AddLineChart( CWorkbook & book, CWorksheet & sheet1, 13 | XLSXColorLib & cl_lib, XLSXColorLib & gs10_lib ) 14 | { 15 | // create series object, that contains most chart settings 16 | CChart::Series ser; 17 | // adding chart to the workbook the reference to a newly created object is returned 18 | CChartsheet & chart_sheet = book.AddChartSheet( "Line Chart", CHART_LINEAR ); 19 | // leave category sequence (X axis) not specified (optional) - MS Excel will generate the default sequence automatically 20 | ser.catSheet = NULL; 21 | 22 | // specify range for values` sequence (Y axis) 23 | ser.valSheet = & sheet1; // don`t forget to set the pointer to the data sheet 24 | ser.valAxisFrom = CellCoord( 1, 1 ); 25 | ser.valAxisTo = CellCoord( 50, 1 ); 26 | ser.JoinType = CChart::Series::joinSmooth; 27 | ser.DashType = CChart::Series::dashSolid; 28 | ser.LineColor = gs10_lib.GetColor( "Black" ); 29 | 30 | ser.Marker.Type = CChart::Series::symCircle; 31 | ser.Marker.Size = 10; 32 | ser.Marker.FillColor = cl_lib.GetColor( "Gold" ); 33 | ser.Marker.LineColor = cl_lib.GetColor( "Plum" ); 34 | ser.Marker.LineWidth = 1.; 35 | ser.title = "Line series test"; 36 | 37 | // add series into the chart (you can add as many series as you wish into the same chart) 38 | chart_sheet.Chart().AddSeries( ser ); 39 | } 40 | 41 | static void AddScatterChart( CWorkbook & book, CWorksheet & sheet, CWorksheet & sheet1, 42 | XLSXColorLib & cl_lib, XLSXColorLib & gs10_lib ) 43 | { 44 | // create series object, that contains most chart settings 45 | CChart::Series ser; 46 | // adding chart to the workbook the reference to a newly created object is returned 47 | CChartsheet & chart_sheet = book.AddChartSheet( "Scatter Chart", CHART_SCATTER ); 48 | CChart & chart = chart_sheet.Chart(); 49 | 50 | // for scatter charts it is obligatory to specify both category (X axis) and values (Y axis) sequences 51 | ser.catSheet = & sheet; 52 | ser.catAxisFrom = CellCoord( 1, 0 ); 53 | ser.catAxisTo = CellCoord( 18, 0 ); 54 | 55 | ser.valSheet = & sheet; 56 | ser.valAxisFrom = CellCoord( 1, 3 ); 57 | ser.valAxisTo = CellCoord( 18, 3 ); 58 | 59 | ser.JoinType = CChart::Series::joinSmooth; // determines whether series will be a smoothed or straight-lined curve 60 | ser.Marker.Type = CChart::Series::symNone; // if true add diamond marks in each node of the sequence set 61 | 62 | // add series into the chart (you can add as many series as you wish into the same chart) 63 | ser.title = "Log Line"; 64 | chart.AddSeries( ser ); 65 | 66 | ser.JoinType = CChart::Series::joinNone; 67 | ser.Marker.Type = CChart::Series::symCircle; 68 | ser.Marker.Size = 10; 69 | ser.Marker.FillColor = cl_lib.GetColor( "Gold" ); 70 | ser.Marker.LineColor = cl_lib.GetColor( "Plum" ); 71 | ser.Marker.LineWidth = 1.; 72 | 73 | // add series into the chart (you can add as many series as you wish into the same chart) 74 | ser.title = "Log Mark"; 75 | chart.AddSeries( ser ); 76 | 77 | ser.catAxisFrom = CellCoord( 1, 0 ); 78 | ser.catAxisTo = CellCoord( 18, 0 ); 79 | ser.catSheet = & sheet; 80 | 81 | ser.valAxisFrom = CellCoord( 1, 2 ); 82 | ser.valAxisTo = CellCoord( 18, 2 ); 83 | ser.valSheet = & sheet; 84 | 85 | ser.JoinType = CChart::Series::joinLine; 86 | ser.Marker.Type = CChart::Series::symNone; 87 | 88 | ser.DashType = CChart::Series::dashDot; 89 | 90 | // add series into the chart (you can add as many series as you wish into the same chart) 91 | ser.title = "sin Line"; 92 | chart.AddSeries( ser ); 93 | 94 | ser.JoinType = CChart::Series::joinNone; // determines whether series will be joined, and if so- smoothed or straight-lined curve will be drawn 95 | ser.Marker.Type = CChart::Series::symSquare; // if true add diamond marks in each node of the sequence set 96 | ser.Marker.Size = 3; 97 | ser.Marker.FillColor = gs10_lib.GetColor( "Gray80%" ); 98 | ser.Marker.LineColor = cl_lib.GetColor( "Blue" ); 99 | ser.Marker.LineWidth = 0.75; 100 | 101 | // add series into the chart (you can add as many series as you wish into the same chart) 102 | ser.title = "sin Mark"; 103 | chart.AddSeries( ser ); 104 | 105 | ser.catSheet = & sheet1; 106 | ser.catAxisFrom = CellCoord( 1, 0 ); 107 | ser.catAxisTo = CellCoord( 50, 0 ); 108 | 109 | ser.valSheet = & sheet1; 110 | ser.valAxisFrom = CellCoord( 1, 1 ); 111 | ser.valAxisTo = CellCoord( 50, 1 ); 112 | 113 | // optional parameters 114 | ser.JoinType = CChart::Series::joinLine; 115 | ser.Marker.Type = CChart::Series::symNone; 116 | ser.LineWidth = 0.5; 117 | ser.DashType = CChart::Series::dashSolid; 118 | ser.LineColor = gs10_lib.GetColor( "Black" ); 119 | 120 | ser.title = "Cos Line"; 121 | chart.AddSeries( ser ); 122 | 123 | ser.Marker.Type = CChart::Series::symTriangle; 124 | ser.Marker.Size = 7; 125 | ser.Marker.FillColor = cl_lib.GetColor( "Lime" ); 126 | ser.Marker.LineColor = cl_lib.GetColor( "Black" ); 127 | ser.Marker.LineWidth = 0.33; 128 | ser.JoinType = CChart::Series::joinNone; 129 | 130 | // add series into the chart (you can add as many series as you wish into the same chart) 131 | ser.title = "Cos Mark"; 132 | chart.AddSeries( ser ); 133 | 134 | // optional parameters to set 135 | chart.SetLegendPos( CChart::POS_RIGHT ); 136 | chart.SetXAxisGrid( CChart::GRID_MAJOR_N_MINOR ); 137 | chart.SetYAxisGrid( CChart::GRID_MAJOR_N_MINOR ); 138 | chart.SetYAxisCross( CChart::CROSS_MIN ); 139 | chart.SetXAxisCross( CChart::CROSS_MIN ); 140 | chart.SetXAxisName( L"\u03D1, sec" ); 141 | chart.SetYAxisName( L"\u046C, \u03A9 /cm\u00B2 " ); 142 | 143 | chart.SetDiagrammName( "Scatter curves` chart" ); 144 | } 145 | 146 | static void AddBarChart( CWorkbook & book, CWorksheet & sheet ) 147 | { 148 | // create series object, that contains most chart settings 149 | CChart::Series ser; 150 | CChartsheet & chart_sheet = book.AddChartSheet( "Bar Chart", CHART_BAR ); 151 | CChart & chart = chart_sheet.Chart(); 152 | 153 | // leave category sequence (X axis) not specified (optional) - MS Excel will generate the default sequence automatically 154 | ser.catSheet = NULL; 155 | // specify range for values` sequence (Y axis) 156 | ser.valAxisFrom = CellCoord( 1, 2 ); 157 | ser.valAxisTo = CellCoord( 18, 2 ); 158 | ser.valSheet = & sheet; // don`t forget to set the pointer to the data sheet 159 | ser.title = "Bar series test"; 160 | ser.dataLabels.showPercent = true; 161 | 162 | // optionally it is possible to set some additional parameters for bar chart 163 | chart.SetBarDirection( CChart::BAR_DIR_HORIZONTAL ); 164 | chart.SetBarGrouping( CChart::BAR_GROUP_CLUSTERED ); 165 | chart.SetTableDataState( CChart::TBL_DATA ); 166 | chart.SetXAxisToCat(); // Switch X axis to cat - nothing about "categorical axis", just specific mode, default is false; 167 | // add series into the chart (you can add as many series as you wish into the same chart) 168 | chart.AddSeries( ser ); 169 | } 170 | 171 | static void AddPieChart( CWorkbook & book, CWorksheet & sheet ) 172 | { 173 | // create series object, that contains most chart settings 174 | CChart::Series ser; 175 | CChartsheet & chart_sheet = book.AddChartSheet( "Pie Chart", CHART_PIE ); 176 | CChart & chart = chart_sheet.Chart(); 177 | 178 | // leave category sequence (X axis) not specified (optional) - MS Excel will generate the default sequence automatically 179 | ser.catSheet = NULL; 180 | // specify range for values` sequence (Y axis) 181 | ser.valAxisFrom = CellCoord( 1, 2 ); 182 | ser.valAxisTo = CellCoord( 18, 2 ); 183 | ser.valSheet = & sheet; // don`t forget to set the pointer to the data sheet 184 | ser.title = "Pie series test"; 185 | ser.dataLabels.showPercent = true; 186 | 187 | chart.SetPieFirstSliceAng( 90 ); 188 | // add series into the chart (you can add as many series as you wish into the same chart) 189 | chart.AddSeries( ser ); 190 | } 191 | 192 | int main() 193 | { 194 | // main object - workbook 195 | CWorkbook book( "me" ); 196 | 197 | // data sheet to store data to be referenced 198 | CWorksheet & sheet = book.AddSheet( "Data" ); 199 | CWorksheet & sheet1 = book.AddSheet( "Data1" ); 200 | 201 | for( int i = 0; i < 20; i++ ) 202 | { 203 | /* addition cell-by-cell may be useful if there are different data types in one row 204 | to perform it the code will look like:*/ 205 | sheet.BeginRow(); 206 | sheet.AddCell( i ); 207 | sheet.AddCell( i * i ); 208 | sheet.AddCell( sin( i ) ); 209 | sheet.AddCell( log( i + 1 ) ); 210 | sheet.EndRow(); 211 | } 212 | 213 | for( int i = 0; i < 50; i++ ) 214 | { 215 | /* addition cell-by-cell may be useful if there are different data types in one row 216 | to perform it the code will look like:*/ 217 | sheet1.BeginRow().AddCell( i ).AddCell( cos( i ) ).EndRow(); 218 | } 219 | // init color libs. 220 | XLSXColorLib cl_lib, gs10_lib; 221 | make_excell_like_named_colors( cl_lib ); 222 | make_grayscale10( gs10_lib ); 223 | 224 | AddLineChart( book, sheet1, cl_lib, gs10_lib ); 225 | AddScatterChart( book, sheet, sheet1, cl_lib, gs10_lib ); 226 | AddBarChart( book, sheet ); 227 | AddPieChart( book, sheet ); 228 | 229 | // at the end save created workbook wherever you need 230 | if( book.Save( "Scientific.xlsx" ) ) std::cout << "The book has been saved successfully" << std::endl; 231 | else std::cout << "The book saving has been failed" << std::endl; 232 | return 0; 233 | } 234 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/SimpleXlsxDef.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include "SimpleXlsxDef.h" 23 | 24 | void SimpleXlsx::Font::Clear() 25 | { 26 | size = 11; 27 | name = "Calibri"; 28 | theme = true; 29 | color = ""; 30 | attributes = FONT_NORMAL; 31 | } 32 | 33 | bool SimpleXlsx::Font::operator==( const SimpleXlsx::Font & _font ) const 34 | { 35 | return ( ( size == _font.size ) && ( name == _font.name ) && ( theme == _font.theme ) && 36 | ( color == _font.color ) && ( attributes == _font.attributes ) ); 37 | } 38 | 39 | void SimpleXlsx::Fill::Clear() 40 | { 41 | patternType = PATTERN_NONE; 42 | fgColor = ""; 43 | bgColor = ""; 44 | } 45 | 46 | bool SimpleXlsx::Fill::operator==( const SimpleXlsx::Fill & _fill ) const 47 | { 48 | return ( ( patternType == _fill.patternType ) && ( fgColor == _fill.fgColor ) && ( bgColor == _fill.bgColor ) ); 49 | } 50 | 51 | void SimpleXlsx::Border::Clear() 52 | { 53 | isDiagonalUp = false; 54 | isDiagonalDown = false; 55 | 56 | left.Clear(); 57 | right.Clear(); 58 | bottom.Clear(); 59 | top.Clear(); 60 | } 61 | 62 | bool SimpleXlsx::Border::operator==( const SimpleXlsx::Border & _border ) const 63 | { 64 | return ( ( isDiagonalUp == _border.isDiagonalUp ) && ( isDiagonalDown == _border.isDiagonalDown ) && 65 | ( left == _border.left ) && ( right == _border.right ) && 66 | ( bottom == _border.bottom ) && ( top == _border.top ) ); 67 | } 68 | 69 | void SimpleXlsx::NumFormat::Clear() 70 | { 71 | id = 164; 72 | formatString = ""; 73 | 74 | numberStyle = NUMSTYLE_GENERAL; 75 | positiveColor = NUMSTYLE_COLOR_DEFAULT; 76 | negativeColor = NUMSTYLE_COLOR_DEFAULT; 77 | zeroColor = NUMSTYLE_COLOR_DEFAULT; 78 | showThousandsSeparator = false; 79 | numberOfDigitsAfterPoint = 2; 80 | } 81 | 82 | bool SimpleXlsx::NumFormat::operator==( const SimpleXlsx::NumFormat & _num ) const 83 | { 84 | return ( ( formatString == _num.formatString ) && 85 | ( numberStyle == _num.numberStyle ) && ( numberOfDigitsAfterPoint == _num.numberOfDigitsAfterPoint ) && 86 | ( positiveColor == _num.positiveColor ) && ( negativeColor == _num.negativeColor ) && 87 | ( zeroColor == _num.zeroColor ) && ( showThousandsSeparator == _num.showThousandsSeparator ) ); 88 | } 89 | 90 | void SimpleXlsx::Style::Clear() 91 | { 92 | font.Clear(); 93 | fill.Clear(); 94 | border.Clear(); 95 | horizAlign = ALIGN_H_NONE; 96 | vertAlign = ALIGN_V_NONE; 97 | wrapText = false; 98 | textRotation = 0; 99 | } 100 | 101 | std::string SimpleXlsx::CellCoord::ToString() const 102 | { 103 | CellCoord::TConvBuf Buffer; 104 | return std::string( ToString< false >( Buffer ) ); 105 | } 106 | 107 | char * SimpleXlsx::CellCoord::ToString( SimpleXlsx::CellCoord::TConvBuf & Buffer ) const 108 | { 109 | return ToString< false >( Buffer ); 110 | } 111 | 112 | std::string SimpleXlsx::CellCoord::ToStringAbs() const 113 | { 114 | CellCoord::TConvBuf Buffer; 115 | return std::string( ToString< true >( Buffer ) ); 116 | } 117 | 118 | char * SimpleXlsx::CellCoord::ToStringAbs( SimpleXlsx::CellCoord::TConvBuf & Buffer ) const 119 | { 120 | return ToString< true >( Buffer ); 121 | } 122 | 123 | 124 | 125 | double SimpleXlsx::CellDataTime::From_time_t( time_t val ) 126 | { 127 | const int64_t secondsFrom1900to1970 = 2208988800u; 128 | const double excelOneSecond = 0.0000115740740740741; 129 | struct tm * t = localtime( & val ); 130 | 131 | time_t timeSinceEpoch = t->tm_sec + t->tm_min * 60 + t->tm_hour * 3600 + t->tm_yday * 86400 + 132 | ( t->tm_year - 70 ) * 31536000 + ( ( t->tm_year - 69 ) / 4 ) * 86400 - 133 | ( ( t->tm_year - 1 ) / 100 ) * 86400 + ( ( t->tm_year + 299 ) / 400 ) * 86400; 134 | 135 | return excelOneSecond * ( secondsFrom1900to1970 + timeSinceEpoch ) + 2; 136 | } 137 | 138 | double SimpleXlsx::CellDataTime::FromGregorian( uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t millisecond ) 139 | { 140 | const bool IsLeapYear = ( ( year & 0x0003 ) == 0 ) && ( year % 400 != 0 ); 141 | const uint8_t DM[ 12 ] = { 31, uint8_t( IsLeapYear ? 29 : 28 ), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 142 | const double excelOneSecond = 0.0000115740740740741; 143 | assert( ( year >= 1900 ) && ( year < 10000 ) ); // Excel restrictions 144 | assert( ( month >= 1 ) && ( month <= 12 ) && ( day >= 1 ) && ( day <= DM[ month - 1 ] ) ); 145 | assert( ( hour <= 23 ) && ( minute <= 59 ) && ( second <= 59 ) && ( millisecond <= 999 ) ); 146 | int PrevMonthDays = 0; 147 | for( int i = 0; i < month - 1; ++i ) 148 | PrevMonthDays += DM[ i ]; 149 | const int64_t YearsSince1900 = year - 1900; 150 | const int64_t LeapYears = ( YearsSince1900 - 1 ) / 4 + ( YearsSince1900 != 0 ? 1 : 0 ); 151 | double TotalSeconds = second + minute * 60 + hour * 3600 + YearsSince1900 * 31536000 + ( PrevMonthDays + day - 1 + LeapYears ) * 86400; 152 | return excelOneSecond * ( TotalSeconds + millisecond / 1000.0 ) + 1.0; // + 1.0 for 1900.01.01 153 | } 154 | 155 | void SimpleXlsx::Comment::Clear() 156 | { 157 | contents.clear(); 158 | cellRef.Clear(); 159 | fillColor = "#FFEFD5"; // papaya whip 160 | isHidden = true; 161 | x = y = 50; 162 | width = height = 100; 163 | } 164 | 165 | 166 | SimpleXlsx::StyleList::StyleList() 167 | { 168 | m_fmtLastId = BUILT_IN_STYLES_NUMBER; 169 | 170 | m_borders.clear(); 171 | m_fonts.clear(); 172 | m_fills.clear(); 173 | m_nums.clear(); 174 | m_styleIndexes.clear(); 175 | m_stylePos.clear(); 176 | } 177 | 178 | size_t SimpleXlsx::StyleList::Add( const SimpleXlsx::Style & style ) 179 | { 180 | std::vector styleLinks( STYLE_LINK_NUMBER ); 181 | 182 | // Check border existance 183 | bool addItem = true; 184 | for( size_t i = 0; i < m_borders.size(); i++ ) 185 | { 186 | if( m_borders[i] == style.border ) 187 | { 188 | addItem = false; 189 | styleLinks[STYLE_LINK_BORDER] = i; 190 | break; 191 | } 192 | } 193 | 194 | // Add border if it is not in collection yet 195 | if( addItem ) 196 | { 197 | m_borders.push_back( style.border ); 198 | styleLinks[STYLE_LINK_BORDER] = m_borders.size() - 1; 199 | } 200 | 201 | // Check font existance 202 | addItem = true; 203 | for( size_t i = 0; i < m_fonts.size(); i++ ) 204 | { 205 | if( m_fonts[i] == style.font ) 206 | { 207 | addItem = false; 208 | styleLinks[STYLE_LINK_FONT] = i; 209 | break; 210 | } 211 | } 212 | 213 | // Add font if it is not in collection yet 214 | if( addItem ) 215 | { 216 | m_fonts.push_back( style.font ); 217 | styleLinks[STYLE_LINK_FONT] = m_fonts.size() - 1; 218 | } 219 | 220 | // Check fill existance 221 | addItem = true; 222 | for( size_t i = 0; i < m_fills.size(); i++ ) 223 | { 224 | if( m_fills[i] == style.fill ) 225 | { 226 | addItem = false; 227 | styleLinks[STYLE_LINK_FILL] = i; 228 | break; 229 | } 230 | } 231 | 232 | // Add fill if it is not in collection yet 233 | if( addItem ) 234 | { 235 | m_fills.push_back( style.fill ); 236 | styleLinks[STYLE_LINK_FILL] = m_fills.size() - 1; 237 | } 238 | 239 | // Check number format existance 240 | addItem = true; 241 | for( size_t i = 0; i < m_nums.size(); i++ ) 242 | { 243 | if( m_nums[i] == style.numFormat ) 244 | { 245 | addItem = false; 246 | styleLinks[STYLE_LINK_NUM_FORMAT] = m_nums[ i ].id; 247 | break; 248 | } 249 | } 250 | 251 | // Add number format if it is not in collection yet 252 | if( addItem ) 253 | { 254 | if( style.numFormat.id >= BUILT_IN_STYLES_NUMBER ) 255 | { 256 | styleLinks[STYLE_LINK_NUM_FORMAT] = m_fmtLastId; 257 | style.numFormat.id = m_fmtLastId++; 258 | } 259 | else 260 | { 261 | styleLinks[STYLE_LINK_NUM_FORMAT] = m_nums.size(); 262 | } 263 | 264 | m_nums.push_back( style.numFormat ); 265 | } 266 | 267 | // Check style combination existance 268 | for( size_t i = 0; i < m_styleIndexes.size(); i++ ) 269 | { 270 | if( ( m_styleIndexes[i] == styleLinks ) && 271 | ( m_stylePos[i].horizAlign == style.horizAlign ) && 272 | ( m_stylePos[i].vertAlign == style.vertAlign ) && 273 | ( m_stylePos[i].wrapText == style.wrapText ) && 274 | ( m_stylePos[i].textRotation == style.textRotation ) ) 275 | return i; 276 | } 277 | 278 | StylePosInfo pos; 279 | pos.horizAlign = style.horizAlign; 280 | pos.vertAlign = style.vertAlign; 281 | pos.wrapText = style.wrapText; 282 | pos.textRotation = style.textRotation; 283 | m_stylePos.push_back( pos ); 284 | 285 | m_styleIndexes.push_back( styleLinks ); 286 | return m_styleIndexes.size() - 1; 287 | } 288 | 289 | 290 | SimpleXlsx::CSheet::~CSheet() {} 291 | 292 | -------------------------------------------------------------------------------- /simplexlsx-code/Readme.txt: -------------------------------------------------------------------------------- 1 | This library represents XLSX files writer for Microsoft Excel 2007 and above. 2 | 3 | The main feature of this library is that it uses C++ standard file streams. On the one hand it results in almost unnoticeable memory and CPU resources consumption while processing (that may be very useful at saving a large data arrays), but on the other hand it makes unfeasible to edit data that were written. 4 | Hence, if using this library the structure of the future report should be known enough. 5 | 6 | The library is written in C++ with using STL functionality and based on the ZIP library (included), which has a free license. 7 | 8 | http://www.codeproject.com/Articles/7530/Zip-Utils-clean-elegant-simple-C-Win32 9 | 10 | Key features: 11 | - Cell styles: fonts, fills, borders, alignment, multirow text, text rotation 12 | - Cell formats: text, numeric, dates and times, custom formats 13 | - Formulae recognition (without formula`s content verification), defined names 14 | - Multi-sheets 15 | - Charts with customizable parameters (on data sheet or separate sheet): linear, bar, scatter, pie 16 | - Images on the worksheet: gif, jpg, jpeg, png, tif, tiff 17 | - Multiplatform: BSD, Linux, macOS, Windows 18 | - Unicode support 19 | - No external dependencies 20 | 21 | The SimpleXlsxWriter source code is available from: 22 | https://sourceforge.net/projects/simplexlsx/ 23 | 24 | This library is distributed under the terms of the zlib license: 25 | http://www.zlib.net/zlib_license.html 26 | 27 | 2020-02-05 Version 0.34 28 | - The CellDataTime class has been redesigned to be able to set the date and time in various ways (thanks to E.Naumovich). 29 | - Added defined names (thanks to E.Naumovich). 30 | - Added functions AddEmptyRow, AddEmptyRows and AddSimpleRow to CWorksheet class. 31 | - Reworked getting currency symbol under Windows. 32 | - Added text rotation to cell style. 33 | - Added SimpleXlsxDef.cpp. 34 | - Updated examples. 35 | 36 | 2019-12-15 Version 0.33 37 | Change log: 38 | - Fixed the precision of saving floating point numbers (thanks for this work to Norbert Wołowiec). 39 | - Added Pie chart (thanks to W Semmelink). 40 | - Updated examples (thanks to W Semmelink). 41 | - Added references to self in class methods of CWorkbook, CWorksheet and CChart. 42 | - CWorksheet::AddCell( time_t ) method has been removed due to a conflict types. CWorksheet::AddCell( CellDataTime ) method remained. 43 | - Added macOS support. 44 | 45 | 2018-11-03 Version 0.32 46 | Change log: 47 | - Added field "count" in xml for style indexes (thanks for this work to mt1710). 48 | 49 | 2018-10-02 Version 0.31 50 | Change log: 51 | - Refactoring code for possibility to make mixed debug/release compilation of the library and of the main program (thanks to E.Naumovich). 52 | 53 | 2018-07-21 Version 0.30 54 | Change log: 55 | - Fixed bug with the number format in the cells (thanks to bcianyo). 56 | 57 | 2018-07-05 Version 0.29 58 | Change log: 59 | - Added CChart::SetEmptyCellsDisplayingMethod method for select how chart display empty cells (thanks for this work to Norbert Wołowiec). 60 | - Added CChart::SetShowDataFromHiddenCells method for display data from hidden rows and columns (thanks for this work to Norbert Wołowiec). 61 | - Added CChart::SetPlotAreaFill*** and CChart::SetChartAreaFill*** methods for filling in chart (thanks to Norbert Wołowiec). 62 | - To CChart::Series was added fill style specified for a bar chart (thanks to Norbert Wołowiec). 63 | - Fixed error with secondary axis in scatter chart (thanks to Knut Buttnase). 64 | 65 | 2018-04-16 Version 0.28 66 | Change log: 67 | - Unicode support without using _UNICODE and _T() macros. The file "tchar.h" was deleted. 68 | - The UniString helper class was added for simultaneous and transparent work with std::string and std::wstring. 69 | - Added method Comment::AddContent. 70 | - Updated examples. 71 | - Fixed sprintf specifier for correct work in Visual Studio 2010 (thanks to Sergey). 72 | 73 | 2018-02-13 Version 0.27 74 | Change log: 75 | - Added CMakeLists.txt (thanks for this work to Thomas Bechmann). 76 | - The type of row height changed to double type (previously uint32_t) according to ISO/IEC 29500-1: 2016 section 18.3.1.73 (thanks for this work to Thomas Bechmann). 77 | - Added CWorksheet::AddCell method with an unsigned long as a parameter (thanks for this work to Thomas Bechmann). 78 | 79 | 2018-02-08 Version 0.26 80 | Change log: 81 | - Fixed compilation in Visual Studio 2017 (thanks for this work to jordi73). 82 | - Specified license type - zlib. 83 | 84 | 2018-01-04 Version 0.25 85 | Change log: 86 | - Saving empty cells with format (borders, fill...) (thanks for this work to E.Naumovich). 87 | - Adding images to a worksheet by CWorkbook::AddImage in two ways: with a binding on two cells (anchored) or scaling on axes X and Y (in percent). Supported image formats (via file extension): gif, jpg, jpeg, png, tif, tiff (thanks for idea to Henrique Aschenbrenner and E.Naumovich). 88 | - Minor bug fixes. 89 | - Updated examples. 90 | 91 | 2017-12-02 Version 0.24 92 | Change log: 93 | - Added checking of sheet names: length up to 31 characters and forbidden characters "/\[]*:?" are replaced with '_' (Excel restrictions) 94 | 95 | 2017-05-09 Version 0.23 96 | Change log: 97 | - Improved scatter charts to more "scientific" appearance, including color and symbol selection and width of the lines (thanks for this work to E.Naumovich). 98 | - Creating charts in the worksheets by CWorkbook::AddChart. For chart sheets must be used CWorkbook::AddChartSheet (thanks for idea to Aso). 99 | - Now the sheets are arranged in order of creation. Using CWorkbook::SetActiveSheet can be set the active sheet (by default the first sheet). 100 | - CWorkbook::m_styleList was moved to private. Now must be used CWorkbook::AddStyle() and CWorkbook::GetFonts(). 101 | - Many internal changes. 102 | - Added examples to the archive. 103 | 104 | 2017-02-22 Version 0.22 105 | Change log: 106 | - Support for the TDM-GCC 64-bit compiler (thanks to Eduardo Baena). 107 | - Minor bug fixes. 108 | 109 | 2017-01-28 Version 0.21 110 | Change log: 111 | - XmlWriter is rewritten to work with Unicode, implemented writing of strings in UTF-8. 112 | - Rewrote all the code to work with the new XmlWriter. All string constants for XML stored in the type const char *, which allows speed up the work and reduce the size of the executable file for the Unicode version. 113 | - Minimal use _stprintf functions, which is replaced by _tstringstream for the safety (no fixed buffer length). 114 | - Fixed bugs in the charts module, because of what Excel can not open the file or display it correctly. Compatibility is also upgraded to Office 2010 because of the charts. 115 | - For fields valAxisFrom and valAxisTo (from CChartsheet::Series) made standard numbering for rows (from 1) 116 | - For CWorkbook you can specify the name of the author. If not specified, the current user name is queried from the Operation system. 117 | - Many functions AddCell of the CWorksheet class can take the "raw" data without the need to create wrapper classes (for example, without CellDataStr or CellDataInt). 118 | 119 | 2013-08-31 Version 0.20 120 | Change log: 121 | - Minor bug fixes 122 | 123 | 2013-04-13 Version 0.19 124 | Change log: 125 | - Numeric, dates and times styling 126 | Most general formats are available. It is also possible to create custom formats 127 | Some information about how to create a format is here: 128 | http://office.microsoft.com/en-us/excel-help/create-or-delete-a-custom-number-format-HP001216503.aspx 129 | - Minor bug fixes 130 | - Makefile to build the project as a library (by Eduardo Zacarias) 131 | 132 | 2012-12-16 Version 0.18 133 | Change log: 134 | - Comments functionality added; 135 | - Font name bug fix 136 | - Borders functionality changed; 137 | - Sheet orientation feature added; 138 | - Some additional features in Chartsheet. 139 | 140 | 2012-10-31 Version 0.17 141 | Change log: 142 | - Creation time format bug fix. 143 | 144 | 2012-10-26 Version 0.16 145 | Change log: 146 | - Temporary directory location bug fix; 147 | - Creation time format bug fix. 148 | 149 | 2012-10-02 Version 0.15 150 | Change log: 151 | - Linux are supported now (tested on Ubuntu with GCC 4.6.3) 152 | - ZIP library ported (under Linux only compressing of files is available) 153 | 154 | 2012-09-21 Version 0.14 155 | Change log (bug fix): 156 | - Overflow in shared strings; 157 | 158 | 2012-09-21 Version 0.13 159 | Change log (bug fix): 160 | - It is enough to include just 'Xlsx/Workbook.h' instead of three files; 161 | - AddCell(); 162 | - Unique directory for each new book; 163 | - Temporary files are deleted after book saving even if saving is failed; 164 | - In Worksheet/Chartsheet classes` objects 'ok' flag is set to false after saving (since stream either closed or data corrupt at another trying); 165 | - Some minor changes inside; 166 | 167 | 2012-09-09 Version 0.12 168 | Change log: 169 | - Proper (without repetitions) shared strings implemented; 170 | - Bug fix - wrong span range for row; 171 | - Bug fix - nonsense style id by default 172 | 173 | 2012-09-01 Version 0.11 174 | Change log: 175 | - AddCell() method to easier addition of empty cell added. 176 | 177 | 2012-08-05 Version 0.1 178 | First draft of the library. 179 | 180 | Main features for data sheets formatting: 181 | - adjustable height for each row; 182 | - adjustable width for columns. Can be specified only at sheet creation; 183 | - frozen panes; 184 | - page title designation; 185 | - data can be added by row, by cell or by cell groups; 186 | - cells merging; 187 | - formulae recognition (without formula`s content verification); 188 | - styles support (fonts, fills, borders, alignment, multirow text); 189 | 190 | Main features for chart sheet configuration: 191 | - supported chart types: linear, bar, scatter; 192 | - customizable settings: legend presence and position, axes` labels; 193 | - data table (for linear and bar chart types); 194 | - additional axes pair (the type defines independently from main chart type); 195 | - data source can set for both X and Y axes for both main and additional axes pairs; 196 | - curve`s smoothness, node`s mark; 197 | - grid settings for each axis; 198 | - minimum and maximum values for each axis. 199 | -------------------------------------------------------------------------------- /simplexlsx-code/Zip/zip.h: -------------------------------------------------------------------------------- 1 | #ifndef _zip_H 2 | #define _zip_H 3 | 4 | // ZIP functions -- for creating zip files 5 | // This file is a repackaged form of the Info-Zip source code available 6 | // at www.info-zip.org. The original copyright notice may be found in 7 | // zip.cpp. The repackaging was done by Lucian Wischik to simplify and 8 | // extend its use in Windows/C++. Also to add encryption and unicode. 9 | 10 | #ifndef _WIN32 11 | #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name 12 | #define HANDLE void* 13 | #endif // _WIN32 14 | 15 | #ifndef _unzip_H 16 | DECLARE_HANDLE(HZIP); 17 | #endif 18 | // An HZIP identifies a zip file that is being created 19 | 20 | typedef unsigned long ZRESULT; 21 | // return codes from any of the zip functions. Listed later. 22 | 23 | 24 | 25 | HZIP CreateZip(const char *fn, const char *password); 26 | HZIP CreateZip(void *buf,unsigned int len, const char *password); 27 | HZIP CreateZipHandle(HANDLE h, const char *password); 28 | // CreateZip - call this to start the creation of a zip file. 29 | // As the zip is being created, it will be stored somewhere: 30 | // to a pipe: CreateZipHandle(hpipe_write); 31 | // in a file (by handle): CreateZipHandle(hfile); 32 | // in a file (by name): CreateZip("c:\\test.zip"); 33 | // in memory: CreateZip(buf, len); 34 | // or in pagefile memory: CreateZip(0, len); 35 | // The final case stores it in memory backed by the system paging file, 36 | // where the zip may not exceed len bytes. This is a bit friendlier than 37 | // allocating memory with new[]: it won't lead to fragmentation, and the 38 | // memory won't be touched unless needed. That means you can give very 39 | // large estimates of the maximum-size without too much worry. 40 | // As for the password, it lets you encrypt every file in the archive. 41 | // (This api doesn't support per-file encryption.) 42 | // Note: because pipes don't allow random access, the structure of a zipfile 43 | // created into a pipe is slightly different from that created into a file 44 | // or memory. In particular, the compressed-size of the item cannot be 45 | // stored in the zipfile until after the item itself. (Also, for an item added 46 | // itself via a pipe, the uncompressed-size might not either be known until 47 | // after.) This is not normally a problem. But if you try to unzip via a pipe 48 | // as well, then the unzipper will not know these things about the item until 49 | // after it has been unzipped. Therefore: for unzippers which don't just write 50 | // each item to disk or to a pipe, but instead pre-allocate memory space into 51 | // which to unzip them, then either you have to create the zip not to a pipe, 52 | // or you have to add items not from a pipe, or at least when adding items 53 | // from a pipe you have to specify the length. 54 | // Note: for windows-ce, you cannot close the handle until after CloseZip. 55 | // but for real windows, the zip makes its own copy of your handle, so you 56 | // can close yours anytime. 57 | 58 | 59 | ZRESULT ZipAdd(HZIP hz, const char *dstzn, const char *fn); 60 | ZRESULT ZipAdd(HZIP hz, const char *dstzn, void *src, unsigned int len); 61 | ZRESULT ZipAddHandle(HZIP hz,const char *dstzn, HANDLE h); 62 | ZRESULT ZipAddHandle(HZIP hz,const char *dstzn, HANDLE h, unsigned int len); 63 | ZRESULT ZipAddFolder(HZIP hz,const char *dstzn); 64 | // ZipAdd - call this for each file to be added to the zip. 65 | // dstzn is the name that the file will be stored as in the zip file. 66 | // The file to be added to the zip can come 67 | // from a pipe: ZipAddHandle(hz,"file.dat", hpipe_read); 68 | // from a file: ZipAddHandle(hz,"file.dat", hfile); 69 | // from a filen: ZipAdd(hz,"file.dat", "c:\\docs\\origfile.dat"); 70 | // from memory: ZipAdd(hz,"subdir\\file.dat", buf,len); 71 | // (folder): ZipAddFolder(hz,"subdir"); 72 | // Note: if adding an item from a pipe, and if also creating the zip file itself 73 | // to a pipe, then you might wish to pass a non-zero length to the ZipAddHandle 74 | // function. This will let the zipfile store the item's size ahead of the 75 | // compressed item itself, which in turn makes it easier when unzipping the 76 | // zipfile from a pipe. 77 | 78 | ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len); 79 | // ZipGetMemory - If the zip was created in memory, via ZipCreate(0,len), 80 | // then this function will return information about that memory block. 81 | // buf will receive a pointer to its start, and len its length. 82 | // Note: you can't add any more after calling this. 83 | 84 | ZRESULT CloseZip(HZIP hz); 85 | // CloseZip - the zip handle must be closed with this function. 86 | 87 | unsigned int FormatZipMessage(ZRESULT code, char *buf,unsigned int len); 88 | // FormatZipMessage - given an error code, formats it as a string. 89 | // It returns the length of the error message. If buf/len points 90 | // to a real buffer, then it also writes as much as possible into there. 91 | 92 | 93 | 94 | // These are the result codes: 95 | #define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned, 96 | #define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage. 97 | // The following come from general system stuff (e.g. files not openable) 98 | #define ZR_GENMASK 0x0000FF00 99 | #define ZR_NODUPH 0x00000100 // couldn't duplicate the handle 100 | #define ZR_NOFILE 0x00000200 // couldn't create/open the file 101 | #define ZR_NOALLOC 0x00000300 // failed to allocate some resource 102 | #define ZR_WRITE 0x00000400 // a general error writing to the file 103 | #define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip 104 | #define ZR_MORE 0x00000600 // there's still more data to be unzipped 105 | #define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile 106 | #define ZR_READ 0x00000800 // a general error reading the file 107 | // The following come from mistakes on the part of the caller 108 | #define ZR_CALLERMASK 0x00FF0000 109 | #define ZR_ARGS 0x00010000 // general mistake with the arguments 110 | #define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't 111 | #define ZR_MEMSIZE 0x00030000 // the memory size is too small 112 | #define ZR_FAILED 0x00040000 // the thing was already failed when you called this function 113 | #define ZR_ENDED 0x00050000 // the zip creation has already been closed 114 | #define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken 115 | #define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped 116 | #define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip 117 | // The following come from bugs within the zip library itself 118 | #define ZR_BUGMASK 0xFF000000 119 | #define ZR_NOTINITED 0x01000000 // initialisation didn't work 120 | #define ZR_SEEK 0x02000000 // trying to seek in an unseekable file 121 | #define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed 122 | #define ZR_FLATE 0x05000000 // an internal error in the de/inflation code 123 | 124 | 125 | 126 | 127 | 128 | 129 | // e.g. 130 | // 131 | // (1) Traditional use, creating a zipfile from existing files 132 | // HZIP hz = CreateZip("c:\\simple1.zip",0); 133 | // ZipAdd(hz,"znsimple.bmp", "c:\\simple.bmp"); 134 | // ZipAdd(hz,"znsimple.txt", "c:\\simple.txt"); 135 | // CloseZip(hz); 136 | // 137 | // (2) Memory use, creating an auto-allocated mem-based zip file from various sources 138 | // HZIP hz = CreateZip(0,100000, 0); 139 | // // adding a conventional file... 140 | // ZipAdd(hz,"src1.txt", "c:\\src1.txt"); 141 | // // adding something from memory... 142 | // char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F); 143 | // ZipAdd(hz,"file.dat", buf,1000); 144 | // // adding something from a pipe... 145 | // HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,NULL,0); 146 | // HANDLE hthread = CreateThread(0,0,ThreadFunc,(void*)hwrite,0,0); 147 | // ZipAdd(hz,"unz3.dat", hread,1000); // the '1000' is optional. 148 | // WaitForSingleObject(hthread,INFINITE); 149 | // CloseHandle(hthread); CloseHandle(hread); 150 | // ... meanwhile DWORD WINAPI ThreadFunc(void *dat) 151 | // { HANDLE hwrite = (HANDLE)dat; 152 | // char buf[1000]={17}; 153 | // DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL); 154 | // CloseHandle(hwrite); 155 | // return 0; 156 | // } 157 | // // and now that the zip is created, let's do something with it: 158 | // void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen); 159 | // HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); 160 | // DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL); 161 | // CloseHandle(hfz); 162 | // CloseZip(hz); 163 | // 164 | // (3) Handle use, for file handles and pipes 165 | // HANDLE hzread,hzwrite; CreatePipe(&hzread,&hzwrite,0,0); 166 | // HANDLE hthread = CreateThread(0,0,ZipReceiverThread,(void*)hzread,0,0); 167 | // HZIP hz = CreateZipHandle(hzwrite,0); 168 | // // ... add to it 169 | // CloseZip(hz); 170 | // CloseHandle(hzwrite); 171 | // WaitForSingleObject(hthread,INFINITE); 172 | // CloseHandle(hthread); 173 | // ... meanwhile DWORD WINAPI ZipReceiverThread(void *dat) 174 | // { HANDLE hread = (HANDLE)dat; 175 | // char buf[1000]; 176 | // while (true) 177 | // { DWORD red; ReadFile(hread,buf,1000,&red,NULL); 178 | // // ... and do something with this zip data we're receiving 179 | // if (red==0) break; 180 | // } 181 | // CloseHandle(hread); 182 | // return 0; 183 | // } 184 | 185 | 186 | 187 | // Now we indulge in a little skullduggery so that the code works whether 188 | // the user has included just zip or both zip and unzip. 189 | // Idea: if header files for both zip and unzip are present, then presumably 190 | // the cpp files for zip and unzip are both present, so we will call 191 | // one or the other of them based on a dynamic choice. If the header file 192 | // for only one is present, then we will bind to that particular one. 193 | ZRESULT CloseZipZ(HZIP hz); 194 | unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len); 195 | bool IsZipHandleZ(HZIP hz); 196 | #ifdef _unzip_H 197 | #undef CloseZip 198 | #define CloseZip(hz) (IsZipHandleZ(hz)?CloseZipZ(hz):CloseZipU(hz)) 199 | #else 200 | #define CloseZip CloseZipZ 201 | #define FormatZipMessage FormatZipMessageZ 202 | #endif 203 | 204 | 205 | 206 | #endif 207 | -------------------------------------------------------------------------------- /simplexlsx-code/XMLWriter.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XMLWRITER_H 23 | #define XMLWRITER_H 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | namespace SimpleXlsx 33 | { 34 | 35 | class XMLWriter 36 | { 37 | public: 38 | inline XMLWriter( const std::string & FileName ) : m_TagOpen( false ), m_SelfClosed( true ) 39 | { 40 | Init( FileName ); 41 | } 42 | 43 | inline ~XMLWriter() 44 | { 45 | EndAll(); 46 | DebugCheckIsLightTagOpened(); 47 | } 48 | 49 | inline bool IsOk() const 50 | { 51 | return m_OStream.is_open(); 52 | } 53 | 54 | //Returns the current precision of floating point 55 | std::streamsize GetFloatPrecision() 56 | { 57 | return m_OStream.precision(); 58 | } 59 | 60 | //Set the current precision for floating point. 61 | //Returns the precision before the call this function. 62 | std::streamsize SetFloatPrecision( std::streamsize NewPrecision ) 63 | { 64 | return m_OStream.precision( NewPrecision ); 65 | } 66 | 67 | //Light version without using stack of Tag Names. 68 | //No internal elements/tags or content string. Only attributes accepted. 69 | //Must be used with EndL. 70 | inline XMLWriter & TagL( const char * TagName ) 71 | { 72 | assert( TagName != NULL ); 73 | DebugCheckAndIncLightTag(); 74 | CloseOpenedTag(); 75 | m_OStream << '<' << TagName; 76 | m_TagOpen = true; 77 | m_SelfClosed = false; 78 | return * this; 79 | } 80 | 81 | //Light version without using stack of Tag Names. 82 | //No internal elements/tags or content string. Only attributes accepted. 83 | //Must be used with TagL. 84 | inline XMLWriter & EndL() 85 | { 86 | DebugCheckAndDecLightTag(); 87 | m_OStream << "/>"; 88 | m_TagOpen = false; 89 | return * this; 90 | } 91 | 92 | inline XMLWriter & Tag( const char * TagName ) 93 | { 94 | assert( TagName != NULL ); 95 | CloseOpenedTag(); 96 | DebugCheckIsLightTagOpened(); 97 | m_OStream << '<' << TagName; 98 | m_TagOpen = true; 99 | m_SelfClosed = true; 100 | m_Tags.push( TagName ); 101 | return * this; 102 | } 103 | 104 | inline XMLWriter & End( const char * TagName = NULL ) 105 | { 106 | assert( ! m_Tags.empty() ); 107 | DebugCheckIsLightTagOpened(); 108 | if( m_SelfClosed ) m_OStream << "/>"; 109 | else m_OStream << "'; 110 | #ifndef NDEBUG 111 | if( TagName != NULL ) 112 | { 113 | if( m_Tags.top() != TagName ) 114 | std::cerr << "Wrong TagName for End: " << TagName << ". Wanted: " << m_Tags.top() << std::endl; 115 | assert( m_Tags.top() == TagName ); 116 | } 117 | #else 118 | ( void )TagName; 119 | #endif 120 | m_Tags.pop(); 121 | m_TagOpen = false; 122 | m_SelfClosed = false; 123 | return * this; 124 | } 125 | 126 | inline XMLWriter & EndAll() 127 | { 128 | while( ! m_Tags.empty() ) 129 | this->End(); 130 | return * this; 131 | } 132 | 133 | inline XMLWriter & TagOnlyContent( const char * TagName, const char * ContentString ) 134 | { 135 | assert( TagName != NULL ); 136 | CloseOpenedTag(); 137 | DebugCheckIsLightTagOpened(); 138 | m_OStream << '<' << TagName << '>'; 139 | WriteStringEscape( ContentString ); 140 | m_OStream << "'; 141 | m_SelfClosed = false; 142 | return * this; 143 | } 144 | 145 | inline XMLWriter & TagOnlyContent( const char * TagName, const std::string & ContentString ) 146 | { 147 | return TagOnlyContent( TagName, ContentString.c_str() ); 148 | } 149 | 150 | //TagOnlyContent() template for all streamable types 151 | template 152 | inline XMLWriter & TagOnlyContent( const char * TagName, _T Value ) 153 | { 154 | CloseOpenedTag(); 155 | DebugCheckIsLightTagOpened(); 156 | m_OStream << '<' << TagName << '>' << Value << "'; 157 | m_SelfClosed = false; 158 | return *this; 159 | } 160 | 161 | template 162 | inline XMLWriter & TagOnlyContent( const char * TagName, _T * Value ); 163 | 164 | //Fast writing an attribute for the current Tag 165 | inline XMLWriter & Attr( const char * AttrName, const char * String ) 166 | { 167 | assert( AttrName != NULL ); 168 | assert( m_TagOpen ); 169 | m_OStream << ' ' << AttrName << "=\"" << String << '"'; 170 | return * this; 171 | } 172 | 173 | //Write an attribute for the current Tag 174 | inline XMLWriter & Attr( const char * AttrName, char * String ) 175 | { 176 | return AttrInt( AttrName, String ); 177 | } 178 | 179 | //Attr() overload for std::string type 180 | inline XMLWriter & Attr( const char * AttrName, const std::string & String ) 181 | { 182 | return AttrInt( AttrName, String.c_str() ); 183 | } 184 | 185 | //Attr() function template for all streamable types 186 | template 187 | inline XMLWriter & Attr( const char * AttrName, _T Value ) 188 | { 189 | assert( AttrName != NULL ); 190 | assert( m_TagOpen ); 191 | m_OStream.put( ' ' ); 192 | m_OStream << AttrName << "=\"" << Value; 193 | m_OStream.put( '"' ); 194 | return *this; 195 | } 196 | 197 | template 198 | inline XMLWriter & Attr( const char * AttrName, _T * Value ); 199 | 200 | //Write an content for the current Tag 201 | inline XMLWriter & Cont( const char * String ) 202 | { 203 | CloseOpenedTag(); 204 | DebugCheckIsLightTagOpened(); 205 | WriteStringEscape( String ); 206 | m_SelfClosed = false; 207 | return * this; 208 | } 209 | 210 | //Write an content for the current Tag 211 | inline XMLWriter & Cont( char * String ) 212 | { 213 | return Cont( static_cast( String ) ); 214 | } 215 | 216 | //Content() overload for std::string type 217 | inline XMLWriter & Cont( const std::string & String ) 218 | { 219 | return Cont( String.c_str() ); 220 | } 221 | 222 | //Content() template for all streamable types 223 | template 224 | inline XMLWriter & Cont( _T Value ) 225 | { 226 | CloseOpenedTag(); 227 | DebugCheckIsLightTagOpened(); 228 | m_OStream << Value; 229 | m_SelfClosed = false; 230 | return *this; 231 | } 232 | 233 | template 234 | inline XMLWriter & Cont( _T * Value ); 235 | 236 | private: 237 | bool m_TagOpen, m_SelfClosed; 238 | std::ofstream m_OStream; 239 | std::stack m_Tags; 240 | 241 | inline void Init( const std::string & FileName ) 242 | { 243 | assert( ! FileName.empty() ); 244 | #ifndef NDEBUG 245 | m_LightTagCounter = 0; 246 | #endif 247 | m_OStream.open( FileName.c_str(), std::ios_base::out ); 248 | m_OStream.imbue( std::locale( "C" ) ); 249 | SetFloatPrecision( std::numeric_limits::digits10 + 1 ); 250 | m_OStream << "\n"; 251 | } 252 | 253 | inline void CloseOpenedTag() 254 | { 255 | if( ! m_TagOpen ) return; 256 | m_OStream.put( '>' ); 257 | m_TagOpen = false; 258 | } 259 | 260 | inline void WriteStringEscape( const char * String ) 261 | { 262 | for( ; * String; String++ ) 263 | switch( * String ) 264 | { 265 | case '&' : m_OStream << "&"; break; 266 | case '<' : m_OStream << "<"; break; 267 | case '>' : m_OStream << ">"; break; 268 | case '\'' : m_OStream << "'"; break; 269 | case '"' : m_OStream << """; break; 270 | default : m_OStream.put( * String ); break; 271 | } 272 | } 273 | 274 | //Write an attribute for the current Tag 275 | inline XMLWriter & AttrInt( const char * AttrName, const char * String ) 276 | { 277 | assert( AttrName != NULL ); 278 | assert( m_TagOpen ); 279 | m_OStream << ' ' << AttrName << "=\""; 280 | WriteStringEscape( String ); 281 | m_OStream.put( '"' ); 282 | return * this; 283 | } 284 | 285 | //Debug version for checking TagL and EndL 286 | #ifdef NDEBUG 287 | inline void DebugCheckAndIncLightTag() {} 288 | inline void DebugCheckAndDecLightTag() {} 289 | inline void DebugCheckIsLightTagOpened() {} 290 | #else 291 | intptr_t m_LightTagCounter; 292 | 293 | inline void DebugCheckAndIncLightTag() 294 | { 295 | assert( m_LightTagCounter == 0 ); 296 | m_LightTagCounter++; 297 | } 298 | 299 | inline void DebugCheckAndDecLightTag() 300 | { 301 | assert( m_LightTagCounter == 1 ); 302 | m_LightTagCounter--; 303 | } 304 | inline void DebugCheckIsLightTagOpened() 305 | { 306 | assert( m_LightTagCounter == 0 ); 307 | } 308 | #endif 309 | }; 310 | } 311 | 312 | #endif // XMLWRITER_H 313 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/Workbook.h: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XLSX_WORKBOOK_H 23 | #define XLSX_WORKBOOK_H 24 | 25 | #include "SimpleXlsxDef.h" 26 | 27 | #include "Chartsheet.h" 28 | #include "Worksheet.h" 29 | 30 | namespace SimpleXlsx 31 | { 32 | class CChart; 33 | class CDrawing; 34 | 35 | class PathManager; 36 | class XMLWriter; 37 | 38 | // **************************************************************************** 39 | /// @brief The class CWorkbook is used to manage creation, population and saving .xlsx files 40 | // **************************************************************************** 41 | class CWorkbook 42 | { 43 | std::string m_temp_path; ///< path to the temporary directory (unique for a book) 44 | std::vector m_worksheets; ///< a series of data sheets 45 | std::vector m_chartsheets; ///< a series of chart sheets 46 | std::vector m_charts; ///< a series of charts 47 | std::vector m_drawings; ///< a series of drawings 48 | std::vector m_images; ///< a series of images 49 | std::map m_sharedStrings;///< 50 | std::vector m_comments; ///< 51 | 52 | size_t m_commLastId; ///< m_commLastId comments counter 53 | UniString m_UserName; 54 | size_t m_sheetId; ///< Current sheet sequence number (for sheets ordering) 55 | size_t m_activeSheetIndex; ///< Index of active (opened) sheet 56 | 57 | StyleList m_styleList; ///< All registered styles 58 | mutable std::string m_currencySymbol; ///< 59 | 60 | PathManager * m_pathManager; ///< 61 | 62 | struct DefinedName 63 | { 64 | const SimpleXlsx::CSheet * CSheet, * ScopeSheet; 65 | std::string Comment, PostFix; 66 | 67 | inline DefinedName( double AConstant, const UniString & AComment, const SimpleXlsx::CSheet * AScopeSheet ) : 68 | CSheet( NULL ), ScopeSheet( AScopeSheet ), Comment( AComment ) 69 | { 70 | std::ostringstream ConvStream; 71 | ConvStream << AConstant; 72 | PostFix = ConvStream.str(); 73 | } 74 | inline DefinedName( const SimpleXlsx::CSheet & ASrcSheet, const CellCoord & Cell, const UniString & AComment, const SimpleXlsx::CSheet * AScopeSheet ) : 75 | CSheet( & ASrcSheet ), ScopeSheet( AScopeSheet ), Comment( AComment ), PostFix( "!" + Cell.ToStringAbs() ) {} 76 | inline DefinedName( const SimpleXlsx::CSheet & ASrcSheet, const CellCoord & CellFrom, const CellCoord & CellTo, 77 | const UniString & AComment, const SimpleXlsx::CSheet * AScopeSheet ) : 78 | CSheet( & ASrcSheet ), ScopeSheet( AScopeSheet ), Comment( AComment ), PostFix( "!" + CellFrom.ToStringAbs() + ":" + CellTo.ToStringAbs() ) {} 79 | inline DefinedName( const UniString & Formula, const size_t FromPos, const UniString & AComment, const SimpleXlsx::CSheet * AScopeSheet ) : 80 | CSheet( NULL ), ScopeSheet( AScopeSheet ), Comment( AComment ), 81 | PostFix( FromPos == 0 ? Formula.toStdString() : Formula.toStdString().substr( FromPos ) ) {} 82 | 83 | inline std::string GetFormula() const 84 | { 85 | if( CSheet == NULL ) 86 | return PostFix; 87 | return '\'' + CSheet->GetTitle().toStdString() + '\'' + PostFix; 88 | } 89 | }; 90 | std::map< std::string, DefinedName > m_definedNames; 91 | 92 | public: 93 | // @section Constructors / destructor 94 | CWorkbook( const UniString & UserName = "" ); 95 | virtual ~CWorkbook(); 96 | 97 | // @section User interface 98 | 99 | //Adds another data sheet into the workbook 100 | inline CWorksheet & AddSheet( const std::string & title ) 101 | { 102 | return CreateSheet( NormalizeSheetName( title ) ); 103 | } 104 | inline CWorksheet & AddSheet( const std::wstring & title ) 105 | { 106 | return CreateSheet( NormalizeSheetName( title ) ); 107 | } 108 | inline CWorksheet & AddSheet( const std::string & title, const std::vector & colWidths ) 109 | { 110 | return CreateSheet( NormalizeSheetName( title ), colWidths ); 111 | } 112 | inline CWorksheet & AddSheet( const std::wstring & title, const std::vector & colWidths ) 113 | { 114 | return CreateSheet( NormalizeSheetName( title ), colWidths ); 115 | } 116 | inline CWorksheet & AddSheet( const std::string & title, uint32_t frozenWidth, uint32_t frozenHeight ) 117 | { 118 | return CreateSheet( NormalizeSheetName( title ), frozenWidth, frozenHeight ); 119 | } 120 | inline CWorksheet & AddSheet( const std::wstring & title, uint32_t frozenWidth, uint32_t frozenHeight ) 121 | { 122 | return CreateSheet( NormalizeSheetName( title ), frozenWidth, frozenHeight ); 123 | } 124 | inline CWorksheet & AddSheet( const std::string & title, uint32_t frozenWidth, uint32_t frozenHeight, 125 | const std::vector & colWidths ) 126 | { 127 | return CreateSheet( NormalizeSheetName( title ), frozenWidth, frozenHeight, colWidths ); 128 | } 129 | inline CWorksheet & AddSheet( const std::wstring & title, uint32_t frozenWidth, uint32_t frozenHeight, 130 | const std::vector & colWidths ) 131 | { 132 | return CreateSheet( NormalizeSheetName( title ), frozenWidth, frozenHeight, colWidths ); 133 | } 134 | 135 | //Adds chart into the data sheet 136 | CChart & AddChart( CWorksheet & sheet, DrawingPoint TopLeft, DrawingPoint BottomRight, EChartTypes type = CHART_LINEAR ); 137 | 138 | //Adds sheet with single chart 139 | inline CChartsheet & AddChartSheet( const std::string & title, EChartTypes type = CHART_LINEAR ) 140 | { 141 | assert( type != CHART_NONE ); 142 | return CreateChartSheet( NormalizeSheetName( title ), type ); 143 | } 144 | inline CChartsheet & AddChartSheet( const std::wstring & title, EChartTypes type = CHART_LINEAR ) 145 | { 146 | assert( type != CHART_NONE ); 147 | return CreateChartSheet( NormalizeSheetName( title ), type ); 148 | } 149 | 150 | //Adds image into the data sheet. Supported image formats: gif, jpg, png, tif. 151 | //If the same image is added several times, then in XLSX will be copied only once. 152 | //Returns true if the image is added. False if the file is unavailable or the format does not supported. 153 | bool AddImage( CWorksheet & sheet, const std::string & filename, DrawingPoint TopLeft, DrawingPoint BottomRight ); 154 | bool AddImage( CWorksheet & sheet, const std::wstring & filename, DrawingPoint TopLeft, DrawingPoint BottomRight ); 155 | //Overloaded method. The size of the image is set by the scale along X and Y axes, in percent. 156 | bool AddImage( CWorksheet & sheet, const std::string & filename, DrawingPoint TopLeft, uint16_t XScale, uint16_t YScale ); 157 | bool AddImage( CWorksheet & sheet, const std::wstring & filename, DrawingPoint TopLeft, uint16_t XScale, uint16_t YScale ); 158 | inline bool AddImage( CWorksheet & sheet, const std::string & filename, DrawingPoint TopLeft, uint16_t XYScale = 100 ) 159 | { 160 | return AddImage( sheet, filename, TopLeft, XYScale, XYScale ); 161 | } 162 | inline bool AddImage( CWorksheet & sheet, const std::wstring & filename, DrawingPoint TopLeft, uint16_t XYScale = 100 ) 163 | { 164 | return AddImage( sheet, filename, TopLeft, XYScale, XYScale ); 165 | } 166 | 167 | // *INDENT-OFF* For AStyle tool 168 | //Adds a new style into collection if it is not exists yet. 169 | //Return style index that should be used at data appending to a data sheet. 170 | inline size_t AddStyle( const Style & style ) { return m_styleList.Add( style ); } 171 | //Vector with exist fonts 172 | inline const std::vector & GetFonts() const { return m_styleList.GetFonts(); } 173 | 174 | //Get active (opened) sheet 175 | inline size_t GetActiveSheetIndex() const { return m_activeSheetIndex; } 176 | //Set active (opened) sheet (start from 0). 177 | inline CWorkbook & SetActiveSheet( size_t index ) { m_activeSheetIndex = index; return * this; } 178 | inline CWorkbook & SetActiveSheet( const CSheet & sheet ) { m_activeSheetIndex = sheet.GetIndex() - 1; return * this; } 179 | // *INDENT-ON* For AStyle tool 180 | 181 | // Adding a descriptive name to represent a constant value. 182 | CWorkbook & AddDefinedName( const UniString & Name, double Constant, const UniString & Comment = "", const CSheet * ScopeSheet = NULL ); 183 | // Adding a descriptive name to represent a single cell. 184 | CWorkbook & AddDefinedName( const UniString & Name, const CSheet & SrcSheet, const CellCoord & Cell, const UniString & Comment = "", const CSheet * ScopeSheet = NULL ); 185 | // Adding a descriptive name to represent a range of cells. 186 | CWorkbook & AddDefinedName( const UniString & Name, const CSheet & SrcSheet, const CellCoord & CellFrom, const CellCoord & CellTo, 187 | const UniString & Comment = "", const CSheet * ScopeSheet = NULL ); 188 | // Adding a descriptive name to represent a formula. 189 | CWorkbook & AddDefinedName( const UniString & Name, const UniString & Formula, const UniString & Comment = "", const CSheet * ScopeSheet = NULL ); 190 | 191 | //Save current workbook 192 | bool Save( const std::string & filename ); 193 | bool Save( const std::wstring & filename ); 194 | 195 | private: 196 | //Disable copy and assignment 197 | CWorkbook( const CWorkbook & that ); 198 | CWorkbook & operator=( const CWorkbook & ); 199 | 200 | CWorksheet & CreateSheet( const UniString & title ); 201 | CWorksheet & CreateSheet( const UniString & title, const std::vector & colWidths ); 202 | CWorksheet & CreateSheet( const UniString & title, uint32_t frozenWidth, uint32_t frozenHeight ); 203 | CWorksheet & CreateSheet( const UniString & title, uint32_t frozenWidth, uint32_t frozenHeight, 204 | const std::vector & colWidths ); 205 | CWorksheet & InitWorkSheet( CWorksheet * sheet, const UniString & title ); 206 | 207 | CChartsheet & CreateChartSheet( const UniString & title, EChartTypes type ); 208 | CDrawing * CreateDrawing(); 209 | CImage * CreateImage( const std::string & filename ); 210 | 211 | template< typename string_type > 212 | string_type NormalizeSheetName( const string_type & title ) 213 | { 214 | string_type Result = title; 215 | for( typename string_type::iterator it = Result.begin(); it != Result.end(); it++ ) 216 | if( ( * it == '\\' ) || ( * it == '/' ) || 217 | ( * it == '[' ) || ( * it == ']' ) || 218 | ( * it == '*' ) || ( * it == ':' ) || 219 | ( * it == '?' ) ) 220 | { 221 | Result.replace( it, it + 1, 1, '_' ); 222 | } 223 | if( Result.length() > 31 ) Result.resize( 31 ); // 31 - is a max length of sheet name 224 | return Result; 225 | } 226 | 227 | bool SaveCore(); 228 | bool SaveContentType(); 229 | bool SaveApp(); 230 | bool SaveTheme(); 231 | bool SaveStyles(); 232 | bool SaveChain(); 233 | bool SaveComments(); 234 | bool SaveSharedStrings(); 235 | bool SaveWorkbook(); 236 | 237 | bool SaveCommentList( const std::vector & comments ); 238 | void AddComment( XMLWriter & xmlw, const Comment & comment ) const; 239 | void AddCommentDrawing( XMLWriter & xmlw, const Comment & comment ); 240 | void AddNumberFormats( XMLWriter & xmlw ) const; 241 | void AddFonts( XMLWriter & xmlw ) const; 242 | void AddFills( XMLWriter & xmlw ) const; 243 | void AddBorders( XMLWriter & xmlw ) const; 244 | void AddBorder( XMLWriter & xmlw, const char * borderName, Border::BorderItem border ) const; 245 | void AddFontInfo( XMLWriter & xmlw, const Font & font, const char * FontTagName, int32_t Charset ) const; 246 | void AddImagesExtensions( XMLWriter & xmlw ) const; 247 | 248 | std::string GetFormatCodeString( const NumFormat & fmt ) const; 249 | static std::string GetFormatCodeColor( ENumericStyleColor color ); 250 | static std::string CurrencySymbol(); 251 | }; 252 | 253 | } // namespace SimpleXlsx 254 | 255 | #endif // XLSX_WORKBOOK_H 256 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/Worksheet.h: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XLSX_WORKSHEET_H 23 | #define XLSX_WORKSHEET_H 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "SimpleXlsxDef.h" 31 | 32 | namespace SimpleXlsx 33 | { 34 | class CDrawing; 35 | 36 | class PathManager; 37 | class XMLWriter; 38 | 39 | // **************************************************************************** 40 | /// @brief The class CWorksheet is used for creation and population 41 | /// .xlsx file sheet table with data 42 | // **************************************************************************** 43 | class CWorksheet : public CSheet 44 | { 45 | public: 46 | enum EPageOrientation 47 | { 48 | PAGE_PORTRAIT = 0, 49 | PAGE_LANDSCAPE 50 | }; 51 | 52 | private: 53 | XMLWriter * m_XMLWriter; ///< xml output stream 54 | std::vectorm_calcChain; ///< list of cells with formulae 55 | std::map * m_sharedStrings; ///< pointer to the list of string supposed to be into shared area 56 | std::vector * m_comments; ///< pointer to the vector of comments 57 | std::list m_mergedCells; ///< list of merged cells` ranges (e.g. A1:B2) 58 | std::string m_autoFilter; ///< autofilter range (e.g. A1:B2) 59 | UniString m_title; ///< page title 60 | bool m_withFormula; ///< indicates whether the sheet contains formulae 61 | bool m_withComments; ///< indicates whether the sheet contains any comments 62 | bool m_isOk; ///< indicates initialization successfulness 63 | bool m_isDataPresented; ///< indicates whether the sheet contains a data 64 | uint32_t m_row_index; ///< since data add row-by-row it contains current row to write 65 | bool m_row_opened; ///< indicates whether row tag is opened 66 | uint32_t m_current_column; ///< used at separate row generation - last cell column number to be added 67 | uint32_t m_offset_column; ///< used at entire row addition (implicit parameter for AddCell method) 68 | 69 | EPageOrientation m_page_orientation; ///< defines page orientation for printing 70 | 71 | PathManager & m_pathManager; ///< reference to XML PathManager 72 | CDrawing & m_Drawing; ///< Reference to drawing object 73 | 74 | public: 75 | // *INDENT-OFF* For AStyle tool 76 | 77 | // @section SEC_INTERNAL Interclass internal interface methods 78 | inline bool IsThereComment() const { return m_withComments; } 79 | inline bool IsThereFormula() const { return m_withFormula; } 80 | inline const CWorksheet & GetCalcChain( std::vector & chain ) const { chain = m_calcChain; return * this; } 81 | 82 | // @section SEC_USER User interface 83 | virtual const UniString & GetTitle() const { return m_title; } 84 | inline CWorksheet & SetTitle( const UniString & title ) { if( ! title.empty() ) m_title = title; return * this; } 85 | 86 | inline CWorksheet & SetPageOrientation( EPageOrientation orient ) { m_page_orientation = orient; return * this; } 87 | 88 | // *INDENT-ON* For AStyle tool 89 | 90 | CWorksheet & AddComment( const Comment & comment ) 91 | { 92 | if( m_comments == NULL ) 93 | return * this; 94 | m_comments->push_back( comment ); 95 | m_comments->back().sheetIndex = m_index; 96 | m_withComments = true; 97 | return * this; 98 | } 99 | 100 | // *INDENT-OFF* For AStyle tool 101 | 102 | CWorksheet & BeginRow( double height = 0.0 ); 103 | CWorksheet & EndRow(); 104 | 105 | inline CWorksheet & AddCell() { m_current_column++; return * this; } 106 | inline CWorksheet & AddEmptyCells( uint32_t Count ) { m_current_column += Count; return * this; } 107 | 108 | CWorksheet & AddCell( const char * value, size_t style_id = 0 ); 109 | CWorksheet & AddCell( const std::string & value, size_t style_id = 0 ) { return AddCell( value.c_str(), style_id ); } 110 | inline CWorksheet & AddCell( const CellDataStr & data ) { return AddCell( data.value, data.style_id ); } 111 | CWorksheet & AddCell( const std::wstring & value, size_t style_id = 0 ) { return AddCell( UTF8Encoder::From_wstring( value ), style_id ); } 112 | inline CWorksheet & AddCells( const std::vector & data ); 113 | 114 | CWorksheet & AddCell( const CellDataTime & data ); 115 | inline CWorksheet & AddCells( const std::vector & data ); 116 | 117 | CWorksheet & AddCell( int32_t value, size_t style_id = 0 ); 118 | inline CWorksheet & AddCell( const CellDataInt & data ) { return AddCell( data.value, data.style_id ); } 119 | inline CWorksheet & AddCells( const std::vector & data ) { return AddCellsTempl( data ); } 120 | 121 | CWorksheet & AddCell( uint32_t value, size_t style_id = 0 ); 122 | inline CWorksheet & AddCell( const CellDataUInt & data ) { return AddCell( data.value, data.style_id ); } 123 | inline CWorksheet & AddCells( const std::vector & data ) { return AddCellsTempl( data ); } 124 | 125 | CWorksheet & AddCell( int64_t value, size_t style_id = 0 ); 126 | CWorksheet & AddCell( uint64_t value, size_t style_id = 0 ); 127 | 128 | CWorksheet & AddCell( float value, size_t style_id = 0 ); 129 | inline CWorksheet & AddCell( const CellDataFlt & data ) { return AddCell( data.value, data.style_id ); } 130 | inline CWorksheet & AddCells( const std::vector & data ) { return AddCellsTempl( data ); } 131 | 132 | CWorksheet & AddCell( double value, size_t style_id = 0 ); 133 | inline CWorksheet & AddCell( const CellDataDbl & data ) { return AddCell( data.value, data.style_id ); } 134 | inline CWorksheet & AddCells( const std::vector & data ) { return AddCellsTempl( data ); } 135 | 136 | CWorksheet & AddRow( const std::vector & data, uint32_t offset = 0, double height = 0.0 ) { return AddRowTempl( data, offset, height ); } 137 | CWorksheet & AddRow( const std::vector & data, uint32_t offset = 0, double height = 0.0 ) { return AddRowTempl( data, offset, height ); } 138 | CWorksheet & AddRow( const std::vector & data, uint32_t offset = 0, double height = 0.0 ) { return AddRowTempl( data, offset, height ); } 139 | CWorksheet & AddRow( const std::vector & data, uint32_t offset = 0, double height = 0.0 ) { return AddRowTempl( data, offset, height ); } 140 | CWorksheet & AddRow( const std::vector & data, uint32_t offset = 0, double height = 0.0 ) { return AddRowTempl( data, offset, height ); } 141 | CWorksheet & AddRow( const std::vector & data, uint32_t offset = 0, double height = 0.0 ) { return AddRowTempl( data, offset, height ); } 142 | 143 | CWorksheet & AddEmptyRow( double height = 0.0 ) { return BeginRow( height ).EndRow(); } 144 | CWorksheet & AddEmptyRows( size_t count, double height = 0.0 ) { for( size_t i = 0; i < count; ++i ) AddEmptyRow( height ); return * this; } 145 | 146 | CWorksheet & AddSimpleRow( const CellDataStr & val, uint32_t offset = 0, double height = 0.0 ) { return AddSimpleRow( val.value, val.style_id, offset, height ); } 147 | CWorksheet & AddSimpleRow( const CellDataInt & val, uint32_t offset = 0, double height = 0.0 ) { return AddSimpleRow( val.value, val.style_id, offset, height ); } 148 | CWorksheet & AddSimpleRow( const CellDataUInt & val, uint32_t offset = 0, double height = 0.0 ) { return AddSimpleRow( val.value, val.style_id, offset, height ); } 149 | CWorksheet & AddSimpleRow( const CellDataFlt & val, uint32_t offset = 0, double height = 0.0 ) { return AddSimpleRow( val.value, val.style_id, offset, height ); } 150 | CWorksheet & AddSimpleRow( const CellDataDbl & val, uint32_t offset = 0, double height = 0.0 ) { return AddSimpleRow( val.value, val.style_id, offset, height ); } 151 | 152 | CWorksheet & AddSimpleRow( const CellDataTime & val, uint32_t offset = 0, double height = 0.0 ) 153 | { 154 | return BeginRow( height ).AddEmptyCells( offset ).AddCell( val ).EndRow(); 155 | } 156 | 157 | CWorksheet & AddSimpleRow( const char * val, size_t style_id = 0, uint32_t offset = 0, double height = 0.0 ) 158 | { 159 | return BeginRow( height ).AddEmptyCells( offset ).AddCell( val, style_id ).EndRow(); 160 | } 161 | 162 | template< typename T > 163 | CWorksheet & AddSimpleRow( const T & val, size_t style_id = 0, uint32_t offset = 0, double height = 0.0 ) 164 | { 165 | return BeginRow( height ).AddEmptyCells( offset ).AddCell( val, style_id ).EndRow(); 166 | } 167 | 168 | CWorksheet & MergeCells( CellCoord cellFrom, CellCoord cellTo ); 169 | 170 | CWorksheet & AutoFilter( CellCoord cellTopLeft, CellCoord cellBottomRight); 171 | 172 | const CWorksheet & GetCurrentCellCoord( CellCoord & currCell ) const; 173 | inline uint32_t CurrentRowIndex() const { return m_row_index; } 174 | inline uint32_t CurrentColumnIndex() const { return m_current_column; } 175 | 176 | // *INDENT-ON* For AStyle tool 177 | 178 | bool IsOk() const 179 | { 180 | return m_isOk; 181 | } 182 | 183 | protected: 184 | CWorksheet( size_t index, CDrawing & drawing, PathManager & pathmanager ); 185 | CWorksheet( size_t index, const std::vector & colHeights, CDrawing & drawing, PathManager & pathmanager ); 186 | CWorksheet( size_t index, uint32_t width, uint32_t height, CDrawing & drawing, PathManager & pathmanager ); 187 | CWorksheet( size_t index, uint32_t width, uint32_t height, const std::vector & colHeights, 188 | CDrawing & drawing, PathManager & pathmanager ); 189 | virtual ~CWorksheet(); 190 | 191 | private: 192 | //Disable copy and assignment 193 | CWorksheet( const CWorksheet & ); 194 | CWorksheet & operator=( const CWorksheet & ); 195 | 196 | bool Save(); 197 | 198 | // *INDENT-OFF* For AStyle tool 199 | inline void SetSharedStr( std::map * share ) { m_sharedStrings = share; } 200 | inline void SetComments( std::vector * share ) { m_comments = share; } 201 | // *INDENT-ON* For AStyle tool 202 | 203 | void Init( uint32_t frozenWidth, uint32_t frozenHeight, const std::vector & colHeights ); 204 | void AddFrozenPane( uint32_t width, uint32_t height ); 205 | 206 | template 207 | CWorksheet & AddCellsTempl( const std::vector & data ); 208 | 209 | void AddRowHeader( std::size_t Size, double Height ); 210 | void AddRowFooter() const; 211 | 212 | template 213 | CWorksheet & AddRowTempl( const std::vector & data, uint32_t offset, double height ); 214 | 215 | bool SaveSheetRels(); 216 | 217 | inline std::string GetCellCoordStrAndIncColumn() 218 | { 219 | std::string Result = CellCoord( m_row_index, m_offset_column + m_current_column ).ToString(); 220 | m_current_column++; 221 | return Result; 222 | } 223 | 224 | friend class CWorkbook; 225 | }; 226 | 227 | template 228 | inline CWorksheet & CWorksheet::AddCellsTempl( const std::vector & data ) 229 | { 230 | for( typename std::vector::const_iterator it = data.begin(); it != data.end(); it++ ) 231 | AddCell( it->value, it->style_id ); 232 | return * this; 233 | } 234 | 235 | // **************************************************************************** 236 | /// @brief Appends another row into the sheet 237 | /// @param data reference to the vector of 238 | /// @param offset the offset from the row begining (0 by default) 239 | /// @param height row height (default if 0) 240 | /// @return Reference to this object 241 | // **************************************************************************** 242 | template 243 | CWorksheet & CWorksheet::AddRowTempl( const std::vector & data, uint32_t offset, double height ) 244 | { 245 | m_offset_column = offset; 246 | AddRowHeader( data.size(), height ); 247 | m_current_column = 0; 248 | AddCells( data ); 249 | AddRowFooter(); 250 | 251 | m_offset_column = 0; 252 | return * this; 253 | } 254 | 255 | // **************************************************************************** 256 | /// @brief Adds a group of cells into a row 257 | /// @param data reference to the vector of CellDataStr 258 | /// @return Reference to this object 259 | // **************************************************************************** 260 | inline CWorksheet & CWorksheet::AddCells( const std::vector & data ) 261 | { 262 | for( size_t i = 0; i < data.size(); i++ ) 263 | AddCell( data[i] ); 264 | return * this; 265 | } 266 | 267 | // **************************************************************************** 268 | /// @brief Adds a group of cells into a row 269 | /// @param data reference to the vector of CellDataTime 270 | /// @return Reference to this object 271 | // **************************************************************************** 272 | inline CWorksheet & CWorksheet::AddCells( const std::vector & data ) 273 | { 274 | for( size_t i = 0; i < data.size(); i++ ) 275 | AddCell( data[i] ); 276 | return * this; 277 | } 278 | } // namespace SimpleXlsx 279 | 280 | #endif // XLSX_WORKSHEET_H 281 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/Worksheet.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #include 23 | #include 24 | 25 | #include "Worksheet.h" 26 | #include "XlsxHeaders.h" 27 | #include "Drawing.h" 28 | 29 | #include "../PathManager.hpp" 30 | #include "../XMLWriter.hpp" 31 | 32 | namespace SimpleXlsx 33 | { 34 | // **************************************************************************** 35 | /// @brief Appends another a group of cells into a row 36 | /// @param data template data value 37 | /// @param style style index 38 | /// @return no 39 | // **************************************************************************** 40 | template 41 | static CWorksheet & AddCellRoutineTempl( T data, size_t style, const std::string & CellCoord, XMLWriter & xmlw, CWorksheet * WorkSheet ) 42 | { 43 | xmlw.Tag( "c" ).Attr( "r", CellCoord ); 44 | if( style != 0 ) // default style is not necessary to sign explicitly 45 | xmlw.Attr( "s", style ); 46 | xmlw.TagOnlyContent( "v", data ).End( "c" ); 47 | return * WorkSheet; 48 | } 49 | 50 | 51 | // **************************************************************************** 52 | /// @brief The class constructor 53 | /// @param index index of a sheet to be created (for example, sheet1.xml) 54 | /// @return no 55 | /// @note The constructor creates an instance with specified sheetX.xml filename 56 | /// and without any frozen panes 57 | // **************************************************************************** 58 | CWorksheet::CWorksheet( size_t index, CDrawing & drawing, PathManager & pathmanager ) : CSheet( index ), m_pathManager( pathmanager ), m_Drawing( drawing ) 59 | { 60 | std::vector colWidths; 61 | Init( 0, 0, colWidths ); 62 | } 63 | 64 | // **************************************************************************** 65 | /// @brief The class constructor to create sheet with frozen pane 66 | /// @param index index of a sheet to be created (for example, sheet1.xml) 67 | /// @param width frozen pane with 68 | /// @param height frozen pane height 69 | /// @return no 70 | // **************************************************************************** 71 | CWorksheet::CWorksheet( size_t index, uint32_t width, uint32_t height, 72 | CDrawing & drawing, PathManager & pathmanager ) : CSheet( index ), m_pathManager( pathmanager ), m_Drawing( drawing ) 73 | { 74 | std::vector colWidths; 75 | Init( width, height, colWidths ); 76 | } 77 | 78 | // **************************************************************************** 79 | /// @brief The class constructor 80 | /// @param index index of a sheet to be created (for example, sheet1.xml) 81 | /// @param colWidths list of pairs colNumber:Width 82 | /// @return no 83 | /// @note The constructor creates an instance with specified sheetX.xml filename 84 | /// and without any frozen panes 85 | // **************************************************************************** 86 | CWorksheet::CWorksheet( size_t index, const std::vector & colWidths, 87 | CDrawing & drawing, PathManager & pathmanager ) : CSheet( index ), m_pathManager( pathmanager ), m_Drawing( drawing ) 88 | { 89 | Init( 0, 0, colWidths ); 90 | } 91 | 92 | // **************************************************************************** 93 | /// @brief The class constructor to create sheet with frozen pane 94 | /// @param index index of a sheet to be created (for example, sheet1.xml) 95 | /// @param width frozen pane with 96 | /// @param height frozen pane height 97 | /// @param colWidths list of pairs colNumber:Width 98 | /// @return no 99 | // **************************************************************************** 100 | CWorksheet::CWorksheet( size_t index, uint32_t width, uint32_t height, const std::vector & colWidths, 101 | CDrawing & drawing, PathManager & pathmanager ) : CSheet( index ), m_pathManager( pathmanager ), m_Drawing( drawing ) 102 | { 103 | Init( width, height, colWidths ); 104 | } 105 | 106 | // **************************************************************************** 107 | /// @brief The class destructor (virtual) 108 | /// @return no 109 | // **************************************************************************** 110 | CWorksheet::~CWorksheet() 111 | { 112 | delete m_XMLWriter; 113 | } 114 | 115 | // **************************************************************************** 116 | /// @brief Initializes internal variables and creates a header of a sheet xml tree 117 | /// @param frozenWidth frozen pane with 118 | /// @param frozenHeight frozen pane height 119 | /// @param colWidths list of pairs colNumber:Width 120 | /// @return no 121 | // **************************************************************************** 122 | void CWorksheet::Init( uint32_t frozenWidth, uint32_t frozenHeight, const std::vector & colWidths ) 123 | { 124 | m_isOk = true; 125 | m_row_opened = false; 126 | m_current_column = 0; 127 | m_offset_column = 0; 128 | m_title = "Sheet 1"; 129 | m_withFormula = false; 130 | m_withComments = false; 131 | m_calcChain.clear(); 132 | m_sharedStrings = NULL; 133 | m_comments = NULL; 134 | m_mergedCells.clear(); 135 | m_row_index = 0; 136 | m_page_orientation = PAGE_PORTRAIT; 137 | 138 | std::stringstream FileName; 139 | FileName << "/xl/worksheets/sheet" << m_index << ".xml"; 140 | m_XMLWriter = new XMLWriter( m_pathManager.RegisterXML( FileName.str() ) ); 141 | if( ( m_XMLWriter == NULL ) || ! m_XMLWriter->IsOk() ) 142 | { 143 | m_isOk = false; 144 | return; 145 | } 146 | 147 | m_XMLWriter->Tag( "worksheet" ).Attr( "xmlns", ns_book ).Attr( "xmlns:r", ns_book_r ).Attr( "xmlns:mc", ns_mc ).Attr( "mc:Ignorable", "x14ac" ).Attr( "xmlns:x14ac", ns_x14ac ); 148 | m_XMLWriter->TagL( "dimension" ).Attr( "ref", "A1" ).EndL(); 149 | m_XMLWriter->Tag( "sheetViews" ).Tag( "sheetView" ).Attr( "tabSelected", 0 ).Attr( "workbookViewId", 0 ); 150 | if( frozenWidth != 0 || frozenHeight != 0 ) 151 | AddFrozenPane( frozenWidth, frozenHeight ); 152 | m_XMLWriter->End( "sheetView" ).End( "sheetViews" ); 153 | 154 | m_XMLWriter->TagL( "sheetFormatPr" ).Attr( "defaultRowHeight", 15 ).Attr( "x14ac:dyDescent", 0.25 ).EndL(); 155 | if( ! colWidths.empty() ) 156 | { 157 | m_XMLWriter->Tag( "cols" ); 158 | for( std::vector::const_iterator it = colWidths.begin(); it != colWidths.end(); it++ ) 159 | m_XMLWriter->TagL( "col" ).Attr( "min", it->colFrom + 1 ).Attr( "max", it->colTo + 1 ).Attr( "width", it->width ).EndL(); 160 | m_XMLWriter->End( "cols" ); 161 | } 162 | m_XMLWriter->Tag( "sheetData" ); // open sheetData tag 163 | } 164 | 165 | // **************************************************************************** 166 | /// @brief Generates a header for another row 167 | /// @param height row height (default if 0) 168 | /// @return Reference to this object 169 | // **************************************************************************** 170 | CWorksheet & CWorksheet::BeginRow( double height ) 171 | { 172 | if( m_row_opened ) 173 | m_XMLWriter->End( "row" ); 174 | m_XMLWriter->Tag( "row" ).Attr( "r", ++m_row_index ).Attr( "x14ac:dyDescent", 0.25 ); 175 | 176 | if( height > 0.0 ) 177 | m_XMLWriter->Attr( "ht", height ).Attr( "customHeight", 1 ); 178 | 179 | m_current_column = 0; 180 | m_row_opened = true; 181 | return * this; 182 | } 183 | 184 | // **************************************************************************** 185 | /// @brief Closes previously began row 186 | /// @return Reference to this object 187 | // **************************************************************************** 188 | CWorksheet & CWorksheet::EndRow() 189 | { 190 | if( ! m_row_opened ) 191 | return * this; 192 | m_XMLWriter->End( "row" ); 193 | m_row_opened = false; 194 | return * this; 195 | } 196 | 197 | // **************************************************************************** 198 | /// @brief Add string-formatted cell with specified style 199 | /// @param data reference to data 200 | /// @return Reference to this object 201 | // **************************************************************************** 202 | CWorksheet & CWorksheet::AddCell( const char * value, size_t style_id ) 203 | { 204 | if( value[ 0 ] != '\0' ) 205 | { 206 | const std::string szCoord = CellCoord( m_row_index, m_offset_column + m_current_column ).ToString(); 207 | m_XMLWriter->Tag( "c" ).Attr( "r", szCoord ); 208 | 209 | if( style_id != 0 ) 210 | m_XMLWriter->Attr( "s", style_id ); // default style is not necessary to sign explisitly 211 | 212 | if( value[ 0 ] == '=' ) 213 | { 214 | m_XMLWriter->TagOnlyContent( "f", value + 1 ); 215 | 216 | m_withFormula = true; 217 | m_calcChain.push_back( szCoord ); 218 | } 219 | else 220 | { 221 | assert( m_sharedStrings != NULL ); 222 | uint64_t str_index = 0; 223 | std::string StdStrVal( value ); 224 | std::map::iterator it = m_sharedStrings->find( StdStrVal ); 225 | if( it == m_sharedStrings->end() ) 226 | { 227 | str_index = m_sharedStrings->size(); 228 | ( *m_sharedStrings )[ StdStrVal ] = str_index; 229 | } 230 | else str_index = it->second; 231 | m_XMLWriter->Attr( "t", "s" ).TagOnlyContent( "v", str_index ); 232 | } 233 | m_XMLWriter->End( "c" ); 234 | } 235 | /// empty cell with style --- 236 | else if( style_id != 0 ) 237 | { 238 | CellCoord::TConvBuf Buffer; 239 | const char * szCoord = CellCoord( m_row_index, m_offset_column + m_current_column ).ToString( Buffer ); 240 | m_XMLWriter->Tag( "c" ).Attr( "r", szCoord ).Attr( "s", style_id ).End( "c" ); 241 | } 242 | /// empty cell with style --- 243 | m_current_column++; 244 | return * this; 245 | } 246 | 247 | // **************************************************************************** 248 | /// @brief Add time-formatted cell with specified style 249 | /// @param data reference to data 250 | /// @return Reference to this object 251 | // **************************************************************************** 252 | CWorksheet & CWorksheet::AddCell( const CellDataTime & data ) 253 | { 254 | return AddCellRoutineTempl( data.XlsxValue(), data.style_id, GetCellCoordStrAndIncColumn(), * m_XMLWriter, this ); 255 | } 256 | 257 | CWorksheet & CWorksheet::AddCell( int32_t value, size_t style_id ) 258 | { 259 | return AddCellRoutineTempl( value, style_id, GetCellCoordStrAndIncColumn(), * m_XMLWriter, this ); 260 | } 261 | 262 | CWorksheet & CWorksheet::AddCell( uint32_t value, size_t style_id ) 263 | { 264 | return AddCellRoutineTempl( value, style_id, GetCellCoordStrAndIncColumn(), * m_XMLWriter, this ); 265 | } 266 | 267 | CWorksheet & CWorksheet::AddCell( int64_t value, size_t style_id ) 268 | { 269 | return AddCellRoutineTempl( value, style_id, GetCellCoordStrAndIncColumn(), * m_XMLWriter, this ); 270 | } 271 | 272 | CWorksheet & CWorksheet::AddCell( uint64_t value, size_t style_id ) 273 | { 274 | return AddCellRoutineTempl( value, style_id, GetCellCoordStrAndIncColumn(), * m_XMLWriter, this ); 275 | } 276 | 277 | CWorksheet & CWorksheet::AddCell( float value, size_t style_id ) 278 | { 279 | return AddCellRoutineTempl( value, style_id, GetCellCoordStrAndIncColumn(), * m_XMLWriter, this ); 280 | } 281 | 282 | CWorksheet & CWorksheet::AddCell( double value, size_t style_id ) 283 | { 284 | return AddCellRoutineTempl( value, style_id, GetCellCoordStrAndIncColumn(), * m_XMLWriter, this ); 285 | } 286 | 287 | // **************************************************************************** 288 | /// @brief Internal initializatino method adds frozen pane`s information into sheet 289 | /// @param width frozen pane width (in number of cells) 290 | /// @param height frozen pane height (in number of cells) 291 | /// @return no 292 | // **************************************************************************** 293 | void CWorksheet::AddFrozenPane( uint32_t width, uint32_t height ) 294 | { 295 | m_XMLWriter->Tag( "pane" ); 296 | if( width != 0 ) m_XMLWriter->Attr( "xSplit", width ); 297 | if( height != 0 ) m_XMLWriter->Attr( "ySplit", height ); 298 | 299 | const std::string szCoord = CellCoord( height + 1, width ).ToString(); 300 | m_XMLWriter->Attr( "topLeftCell", szCoord ); 301 | 302 | const char * ActivePane = "activePane"; 303 | if( ( width != 0 ) && ( height != 0 ) ) m_XMLWriter->Attr( ActivePane, "bottomRight" ); 304 | else if( ( width == 0 ) && ( height != 0 ) ) m_XMLWriter->Attr( ActivePane, "bottomLeft" ); 305 | else if( ( width != 0 ) && ( height == 0 ) ) m_XMLWriter->Attr( ActivePane, "topRight" ); 306 | 307 | m_XMLWriter->Attr( "state", "frozen" ).End( "pane" ); 308 | 309 | if( ( width > 0 ) && ( height > 0 ) ) 310 | { 311 | CellCoord::TConvBuf Buffer; 312 | const char * szCoordTR = CellCoord( height, width ).ToString( Buffer ); 313 | m_XMLWriter->TagL( "selection" ).Attr( "pane", "topRight" ).Attr( "activeCell", szCoordTR ).Attr( "sqref", szCoordTR ).EndL(); 314 | const char * szCoordBL = CellCoord( height + 1, width - 1 ).ToString( Buffer ); 315 | m_XMLWriter->TagL( "selection" ).Attr( "pane", "bottomLeft" ).Attr( "activeCell", szCoordBL ).Attr( "sqref", szCoordBL ).EndL(); 316 | m_XMLWriter->TagL( "selection" ).Attr( "pane", "bottomRight" ).Attr( "activeCell", szCoord ).Attr( "sqref", szCoord ).EndL(); 317 | } 318 | else if( width > 0 ) 319 | { 320 | m_XMLWriter->TagL( "selection" ).Attr( "pane", "topRight" ).Attr( "activeCell", szCoord ).Attr( "sqref", szCoord ).EndL(); 321 | } 322 | else if( height > 0 ) 323 | m_XMLWriter->TagL( "selection" ).Attr( "pane", "bottomLeft" ).Attr( "activeCell", szCoord ).Attr( "sqref", szCoord ).EndL(); 324 | } 325 | 326 | void CWorksheet::AddRowHeader( std::size_t Size, double Height ) 327 | { 328 | std::stringstream Spans; 329 | Spans << m_offset_column + 1 << ':' << Size + m_offset_column + 1; 330 | m_XMLWriter->Tag( "row" ).Attr( "r", ++m_row_index ).Attr( "spans", Spans.str() ).Attr( "x14ac:dyDescent", 0.25 ); 331 | if( Height > 0 ) 332 | m_XMLWriter->Attr( "ht", Height ).Attr( "customHeight", 1 ); 333 | } 334 | 335 | void CWorksheet::AddRowFooter() const 336 | { 337 | m_XMLWriter->End( "row" ); 338 | } 339 | 340 | // **************************************************************************** 341 | /// @brief Appends merged cells range into the sheet 342 | /// @param cellFrom (row value from 1, col value from 0) 343 | /// @param cellTo (row value from 1, col value from 0) 344 | /// @return Reference to this object 345 | // **************************************************************************** 346 | CWorksheet & CWorksheet::MergeCells( CellCoord cellFrom, CellCoord cellTo ) 347 | { 348 | if( ( cellFrom.row != 0 ) && ( cellTo.row != 0 ) ) 349 | { m_mergedCells.push_back( cellFrom.ToString() + ':' + cellTo.ToString() ); } 350 | return * this; 351 | } 352 | 353 | // **************************************************************************** 354 | /// @brief Adds an auto filter to the top row of the given area 355 | /// @param cellTopLeft (row value from 1, col value from 0) 356 | /// @param cellBottomRight (row value from 1, col value from 0) 357 | /// @return Reference to this object 358 | // **************************************************************************** 359 | CWorksheet& CWorksheet::AutoFilter(CellCoord cellTopLeft, CellCoord cellBottomRight) { 360 | // 361 | m_autoFilter = cellTopLeft.ToString() + ':' + cellBottomRight.ToString(); 362 | return * this; 363 | } 364 | 365 | // **************************************************************************** 366 | /// @brief Receives next to write cell`s coordinates 367 | /// @param currCell (row value from 1, col value from 0) 368 | /// @return Reference to this object 369 | // **************************************************************************** 370 | const CWorksheet & CWorksheet::GetCurrentCellCoord( CellCoord & currCell ) const 371 | { 372 | currCell.row = m_row_index; 373 | currCell.col = m_current_column; 374 | return * this; 375 | } 376 | 377 | // **************************************************************************** 378 | /// @brief Saves current xml document into a file with preset name 379 | /// @return Boolean result of the operation 380 | // **************************************************************************** 381 | bool CWorksheet::Save() 382 | { 383 | m_XMLWriter->End( "sheetData" ); // close sheetData tag 384 | 385 | if( ! m_mergedCells.empty() ) 386 | { 387 | m_XMLWriter->Tag( "mergeCells" ).Attr( "count", m_mergedCells.size() ); 388 | for( std::list::const_iterator it = m_mergedCells.begin(); it != m_mergedCells.end(); it++ ) 389 | m_XMLWriter->TagL( "mergeCell" ).Attr( "ref", * it ).EndL(); 390 | m_XMLWriter->End( "mergeCells" ); 391 | } 392 | 393 | if( !m_autoFilter.empty() ) { 394 | m_XMLWriter->Tag( "autoFilter" ).Attr( "ref", m_autoFilter); 395 | m_XMLWriter->End( "autoFilter" ); 396 | } 397 | 398 | 399 | std::string sOrient; 400 | if( m_page_orientation == PAGE_PORTRAIT ) { sOrient = "portrait"; } 401 | else if( m_page_orientation == PAGE_LANDSCAPE ) { sOrient = "landscape"; } 402 | 403 | m_XMLWriter->TagL( "pageMargins" ).Attr( "left", 0.7 ).Attr( "right", 0.7 ).Attr( "top", 0.75 ); 404 | /* */m_XMLWriter->Attr( "bottom", 0.75 ).Attr( "header", 0.3 ).Attr( "footer", 0.3 ).EndL(); 405 | m_XMLWriter->TagL( "pageSetup" ).Attr( "paperSize", 9 ).Attr( "orientation", sOrient ).EndL(); // A4 paper size 406 | 407 | size_t rId = 1; 408 | if( ! m_Drawing.IsEmpty() ) 409 | { 410 | std::stringstream rIdStream; 411 | rIdStream << "rId" << rId; 412 | m_XMLWriter->TagL( "drawing" ).Attr( "r:id", rIdStream.str() ).EndL(); 413 | rId++; 414 | } 415 | if( m_withComments ) 416 | { 417 | std::stringstream rIdStream; 418 | rIdStream << "rId" << rId; 419 | m_XMLWriter->TagL( "legacyDrawing" ).Attr( "r:id", rIdStream.str() ).EndL(); 420 | rId += 2; 421 | } 422 | 423 | m_XMLWriter->End( "worksheet" ); 424 | 425 | // by deleting the stream the end of file writes and closes the stream 426 | delete m_XMLWriter; 427 | m_XMLWriter = NULL; 428 | 429 | if( ( rId != 1 ) && ! SaveSheetRels() ) { return false; } 430 | 431 | m_isOk = false; 432 | return true; 433 | } 434 | 435 | // **************************************************************************** 436 | /// @brief Saves current sheet relations file 437 | /// @return no 438 | // **************************************************************************** 439 | bool CWorksheet::SaveSheetRels() 440 | { 441 | // [- zip/xl/worksheets/_rels/sheetN.xml.rels 442 | std::stringstream FileName; 443 | FileName << "/xl/worksheets/_rels/sheet" << m_index << ".xml.rels"; 444 | 445 | XMLWriter xmlw( m_pathManager.RegisterXML( FileName.str() ) ); 446 | xmlw.Tag( "Relationships" ).Attr( "xmlns", ns_relationships ); 447 | size_t rId = 1; 448 | if( ! m_Drawing.IsEmpty() ) 449 | { 450 | std::stringstream rIdStream, Drawing; 451 | rIdStream << "rId" << rId; 452 | Drawing << "../drawings/drawing" << m_index << ".xml"; 453 | xmlw.TagL( "Relationship" ).Attr( "Id", rIdStream.str() ).Attr( "Type", type_drawing ).Attr( "Target", Drawing.str() ).EndL(); 454 | rId++; 455 | } 456 | if( m_withComments ) 457 | { 458 | std::stringstream Vml, Comments, rIdVml, rIdComments; 459 | Vml << "../drawings/vmlDrawing" << m_index << ".vml"; 460 | Comments << "../comments" << m_index << ".xml"; 461 | rIdVml << "rId" << rId; 462 | rIdComments << "rId" << rId + 1; 463 | rId += 2; 464 | xmlw.TagL( "Relationship" ).Attr( "Id", rIdVml.str() ).Attr( "Type", type_vml ).Attr( "Target", Vml.str() ).EndL(); 465 | xmlw.TagL( "Relationship" ).Attr( "Id", rIdComments.str() ).Attr( "Type", type_comments ).Attr( "Target", Comments.str() ).EndL(); 466 | } 467 | 468 | xmlw.End( "Relationships" ); 469 | 470 | // zip/xl/worksheets/_rels/sheetN.xml.rels -] 471 | return true; 472 | } 473 | 474 | } // namespace SimpleXlsx 475 | -------------------------------------------------------------------------------- /simplexlsx-code/Xlsx/SimpleXlsxDef.h: -------------------------------------------------------------------------------- 1 | /* 2 | SimpleXlsxWriter 3 | Copyright (C) 2012-2020 Pavel Akimov , Alexandr Belyak 4 | 5 | This software is provided 'as-is', without any express or implied 6 | warranty. In no event will the authors be held liable for any damages 7 | arising from the use of this software. 8 | 9 | Permission is granted to anyone to use this software for any purpose, 10 | including commercial applications, and to alter it and redistribute it 11 | freely, subject to the following restrictions: 12 | 13 | 1. The origin of this software must not be misrepresented; you must not 14 | claim that you wrote the original software. If you use this software 15 | in a product, an acknowledgment in the product documentation would be 16 | appreciated but is not required. 17 | 2. Altered source versions must be plainly marked as such, and must not be 18 | misrepresented as being the original software. 19 | 3. This notice may not be removed or altered from any source distribution. 20 | */ 21 | 22 | #ifndef XLSX_SIMPLE_XLSX_DEF_H 23 | #define XLSX_SIMPLE_XLSX_DEF_H 24 | 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #ifdef _WIN32 37 | #include 38 | #endif 39 | 40 | #ifdef QT_CORE_LIB 41 | #include 42 | #endif 43 | 44 | #include "../UTF8Encoder.hpp" 45 | 46 | #define SIMPLE_XLSX_VERSION "0.34" 47 | 48 | namespace SimpleXlsx 49 | { 50 | // Helper class for simultaneous work with std::string and std::wstring 51 | class UniString 52 | { 53 | public: 54 | UniString() {} 55 | 56 | UniString( const char * Str ) : m_string( Str ), m_wstring( m_string.begin(), m_string.end() ) {} 57 | UniString( const std::string & Str ) : m_string( Str ), m_wstring( m_string.begin(), m_string.end() ) {} 58 | 59 | UniString( const wchar_t * Str ) : m_wstring( Str ) 60 | { 61 | m_string = UTF8Encoder::From_wstring( m_wstring ); 62 | } 63 | UniString( const std::wstring & Str ) : m_wstring( Str ) 64 | { 65 | m_string = UTF8Encoder::From_wstring( m_wstring ); 66 | } 67 | 68 | // *INDENT-OFF* For AStyle tool 69 | inline bool empty() const { return m_string.empty(); } 70 | 71 | inline operator const std::string & () const { return m_string; } 72 | inline operator const std::wstring & () const { return m_wstring; } 73 | 74 | inline const std::string & toStdString() const { return m_string; } 75 | inline const std::wstring & toStdWString() const { return m_wstring; } 76 | 77 | inline bool operator==( const std::string & other ) const { return m_string == other; } 78 | inline bool operator!=( const std::string & other ) const { return !( *this == other ); } 79 | inline bool operator==( const std::wstring & other ) const { return m_wstring == other; } 80 | inline bool operator!=( const std::wstring & other ) const { return !( *this == other ); } 81 | inline bool operator==( const UniString & other ) const { return *this == other.m_string; } 82 | inline bool operator!=( const UniString & other ) const { return !( *this == other ); } 83 | // *INDENT-ON* For AStyle tool 84 | 85 | UniString & operator=( const char * other ) 86 | { 87 | m_string = other; 88 | m_wstring = std::wstring( m_string.begin(), m_string.end() ); 89 | return * this; 90 | } 91 | UniString & operator=( const std::string & other ) 92 | { 93 | m_string = other; 94 | m_wstring = std::wstring( m_string.begin(), m_string.end() ); 95 | return * this; 96 | } 97 | UniString & operator=( const wchar_t * other ) 98 | { 99 | m_wstring = other; 100 | m_string = UTF8Encoder::From_wstring( other ); 101 | return * this; 102 | } 103 | UniString & operator=( const std::wstring & other ) 104 | { 105 | m_wstring = other; 106 | m_string = UTF8Encoder::From_wstring( other ); 107 | return * this; 108 | } 109 | 110 | friend std::ostream & operator<<( std::ostream & os, const UniString & str ); 111 | 112 | private: 113 | std::string m_string; 114 | std::wstring m_wstring; 115 | }; 116 | 117 | inline std::ostream & operator<<( std::ostream & os, const UniString & str ) 118 | { 119 | os << str.m_string; 120 | return os; 121 | } 122 | 123 | /// @brief Possible chart types 124 | enum EChartTypes 125 | { 126 | CHART_NONE = -1, 127 | CHART_LINEAR = 0, 128 | CHART_BAR, 129 | CHART_SCATTER, 130 | CHART_PIE, 131 | }; 132 | 133 | /// @brief Possible border attributes 134 | enum EBorderStyle 135 | { 136 | BORDER_NONE = 0, 137 | BORDER_THIN, 138 | BORDER_MEDIUM, 139 | BORDER_DASHED, 140 | BORDER_DOTTED, 141 | BORDER_THICK, 142 | BORDER_DOUBLE, 143 | BORDER_HAIR, 144 | BORDER_MEDIUM_DASHED, 145 | BORDER_DASH_DOT, 146 | BORDER_MEDIUM_DASH_DOT, 147 | BORDER_DASH_DOT_DOT, 148 | BORDER_MEDIUM_DASH_DOT_DOT, 149 | BORDER_SLANT_DASH_DOT 150 | }; 151 | 152 | /// @brief Additional font attributes 153 | enum EFontAttributes 154 | { 155 | FONT_NORMAL = 0, 156 | FONT_BOLD = 1, 157 | FONT_ITALIC = 2, 158 | FONT_UNDERLINED = 4, 159 | FONT_STRIKE = 8, 160 | FONT_OUTLINE = 16, 161 | FONT_SHADOW = 32, 162 | FONT_CONDENSE = 64, 163 | FONT_EXTEND = 128, 164 | }; 165 | 166 | /// @brief Fill`s pattern type enumeration 167 | enum EPatternType 168 | { 169 | PATTERN_NONE = 0, 170 | PATTERN_SOLID, 171 | PATTERN_MEDIUM_GRAY, 172 | PATTERN_DARK_GRAY, 173 | PATTERN_LIGHT_GRAY, 174 | PATTERN_DARK_HORIZ, 175 | PATTERN_DARK_VERT, 176 | PATTERN_DARK_DOWN, 177 | PATTERN_DARK_UP, 178 | PATTERN_DARK_GRID, 179 | PATTERN_DARK_TRELLIS, 180 | PATTERN_LIGHT_HORIZ, 181 | PATTERN_LIGHT_VERT, 182 | PATTERN_LIGHT_DOWN, 183 | PATTERN_LIGHT_UP, 184 | PATTERN_LIGHT_GRID, 185 | PATTERN_LIGHT_TRELLIS, 186 | PATTERN_GRAY_125, 187 | PATTERN_GRAY_0625 188 | }; 189 | 190 | /// @brief Text horizontal alignment enumerations 191 | enum EAlignHoriz 192 | { 193 | ALIGN_H_NONE = 0, 194 | ALIGN_H_LEFT, 195 | ALIGN_H_CENTER, 196 | ALIGN_H_RIGHT 197 | }; 198 | 199 | /// @brief Text vertical alignment enumerations 200 | enum EAlignVert 201 | { 202 | ALIGN_V_NONE = 0, 203 | ALIGN_V_TOP, 204 | ALIGN_V_CENTER, 205 | ALIGN_V_BOTTOM 206 | }; 207 | 208 | /// @brief Number styling most general enumeration 209 | enum ENumericStyle 210 | { 211 | NUMSTYLE_GENERAL = 0, 212 | NUMSTYLE_NUMERIC, 213 | NUMSTYLE_PERCENTAGE, 214 | NUMSTYLE_EXPONENTIAL, 215 | NUMSTYLE_FINANCIAL, 216 | NUMSTYLE_MONEY, 217 | NUMSTYLE_DATE, 218 | NUMSTYLE_TIME, 219 | NUMSTYLE_DATETIME, 220 | }; 221 | 222 | /// @brief Number can be colored differently depending on whether it positive or negavite or zero 223 | enum ENumericStyleColor 224 | { 225 | NUMSTYLE_COLOR_DEFAULT = 0, 226 | NUMSTYLE_COLOR_BLACK, 227 | NUMSTYLE_COLOR_GREEN, 228 | NUMSTYLE_COLOR_WHITE, 229 | NUMSTYLE_COLOR_BLUE, 230 | NUMSTYLE_COLOR_MAGENTA, 231 | NUMSTYLE_COLOR_YELLOW, 232 | NUMSTYLE_COLOR_CYAN, 233 | NUMSTYLE_COLOR_RED 234 | }; 235 | 236 | /// @brief Font describes a font that can be added into final document stylesheet 237 | /// @see EFontAttributes 238 | class Font 239 | { 240 | public: 241 | UniString name; ///< font name (there is no enumeration or preset values, it should be used carefully) 242 | std::string color; ///< color format: AARRGGBB - (alpha, red, green, blue). If empty default theme is used 243 | int32_t size; ///< font size 244 | int32_t attributes; ///< combination of additinal font flags (EFontAttributes) 245 | bool theme; ///< theme if true then color is not taken into account 246 | 247 | public: 248 | Font() 249 | { 250 | Clear(); 251 | } 252 | 253 | void Clear(); 254 | 255 | bool operator==( const Font & _font ) const; 256 | }; 257 | 258 | /// @brief Fill describes a fill that can be added into final document stylesheet 259 | /// @note Current version describes the pattern fill only 260 | /// @see EPatternType 261 | class Fill 262 | { 263 | public: 264 | EPatternType patternType; ///< patternType 265 | std::string fgColor; ///< fgColor foreground color format: AARRGGBB - (alpha, red, green, blue). Can be left unset 266 | std::string bgColor; ///< bgColor background color format: AARRGGBB - (alpha, red, green, blue). Can be left unset 267 | 268 | public: 269 | Fill() : patternType( PATTERN_NONE ), fgColor( "" ), bgColor( "" ) {} 270 | 271 | void Clear(); 272 | 273 | bool operator==( const Fill & _fill ) const; 274 | }; 275 | 276 | /// @brief Border describes a border style that can be added into final document stylesheet 277 | /// @see EBorderStyle 278 | class Border 279 | { 280 | public: 281 | /// @brief BorderItem describes border items (e.g. left, right, bottom, top, diagonal sides) 282 | struct BorderItem 283 | { 284 | EBorderStyle style; ///< style border style 285 | std::string color; ///< colour border colour format: AARRGGBB - (alpha, red, green, blue). Can be left unset 286 | 287 | BorderItem() : style( BORDER_NONE ), color( "" ) {} 288 | 289 | void Clear() 290 | { 291 | style = BORDER_NONE; 292 | color = ""; 293 | } 294 | 295 | bool operator==( const BorderItem & _borderItem ) const 296 | { 297 | return ( ( color == _borderItem.color ) && ( style == _borderItem.style ) ); 298 | } 299 | }; 300 | 301 | public: 302 | BorderItem left; ///< left left side style 303 | BorderItem right; ///< right right side style 304 | BorderItem bottom; ///< bottom bottom side style 305 | BorderItem top; ///< top top side style 306 | BorderItem diagonal; ///< diagonal diagonal side style 307 | bool isDiagonalUp; ///< isDiagonalUp indicates whether this diagonal border should be used 308 | bool isDiagonalDown; ///< isDiagonalDown indicates whether this diagonal border should be used 309 | 310 | public: 311 | Border() 312 | { 313 | Clear(); 314 | } 315 | 316 | void Clear(); 317 | 318 | bool operator==( const Border & _border ) const; 319 | }; 320 | 321 | /// @brief NumFormat helps to create a customized number format 322 | class NumFormat 323 | { 324 | public: 325 | mutable size_t id; ///< id internal format number (must not be changed manually) 326 | 327 | std::string formatString; ///< formatString final format form. If set manually, then all other options are ignored 328 | 329 | ENumericStyle numberStyle; ///< numberStyle most general style definition from enumeration 330 | ENumericStyleColor positiveColor; ///< positiveColor positive numbers color (switched off by default) 331 | ENumericStyleColor negativeColor; ///< negativeColor negative numbers color (switched off by default) 332 | ENumericStyleColor zeroColor; ///< zeroColor zero color (switched off by default) 333 | bool showThousandsSeparator; ///< thousandsSeparator specifies whether to show thousands separator 334 | size_t numberOfDigitsAfterPoint; ///< numberOfDigitsAfterPoint number of digits after point 335 | 336 | public: 337 | NumFormat() 338 | { 339 | Clear(); 340 | } 341 | 342 | void Clear(); 343 | 344 | bool operator==( const NumFormat & _num ) const; 345 | }; 346 | 347 | /// @brief Cell coordinate structure 348 | class CellCoord 349 | { 350 | static const uint8_t ColStrOffset = 11; 351 | 352 | public: 353 | typedef char TConvBuf[ 24 ]; // Max string for $Col$Row\0 354 | static const uint32_t MaxRows = 1048576, MaxCols = 16384; // Excel limits 355 | uint32_t row; ///< row (starts from 1) 356 | uint32_t col; ///< col (starts from 0) 357 | 358 | CellCoord() : row( 1 ), col( 0 ) {} 359 | CellCoord( uint32_t _r, uint32_t _c ) : row( _r ), col( _c ) {} 360 | 361 | void Clear() 362 | { 363 | row = 1; 364 | col = 0; 365 | } 366 | 367 | // Transforms the row and the column numerics from uint32_t to coordinate string format 368 | std::string ToString() const; 369 | char * ToString( TConvBuf & Buffer ) const; 370 | // Transforms the row and the column numerics from uint32_t to coordinate string format with '$' symbols 371 | std::string ToStringAbs() const; 372 | char * ToStringAbs( TConvBuf & Buffer ) const; 373 | 374 | private: 375 | template< bool AbsColAndRow > 376 | inline char * ToString( char * Buffer ) const 377 | { 378 | const int32_t iAlphLen = 26; 379 | const char * szAlph = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 380 | 381 | Buffer[ CellCoord::ColStrOffset ] = szAlph[ col % iAlphLen ]; 382 | char * StartPtr = Buffer + CellCoord::ColStrOffset; 383 | int32_t div = col / iAlphLen; 384 | while( div != 0 ) 385 | { 386 | div--; 387 | StartPtr--; 388 | * StartPtr = szAlph[ div % iAlphLen ]; 389 | div /= iAlphLen; 390 | } 391 | if( AbsColAndRow ) 392 | { 393 | StartPtr--; 394 | * StartPtr = '$'; 395 | Buffer[ CellCoord::ColStrOffset + 1 ] = '$'; 396 | } 397 | sprintf( Buffer + CellCoord::ColStrOffset + ( AbsColAndRow ? 2 : 1 ), "%u", row ); 398 | return StartPtr; 399 | } 400 | }; 401 | 402 | /// @brief Column width structure 403 | class ColumnWidth 404 | { 405 | public: 406 | uint32_t colFrom; ///< column range from (starts from 0) 407 | uint32_t colTo; ///< column range to (starts from 0) 408 | float width; ///< specified width 409 | 410 | public: 411 | ColumnWidth() : colFrom( 0 ), colTo( 0 ), width( 15 ) {} 412 | ColumnWidth( uint32_t min, uint32_t max, float w ) : colFrom( min ), colTo( max ), width( w ) {} 413 | }; 414 | 415 | class CellDataStr 416 | { 417 | public: 418 | std::string value; 419 | size_t style_id; 420 | 421 | public: 422 | CellDataStr() : value( "" ), style_id( 0 ) {} 423 | CellDataStr( const char * pStr ) : value( pStr ), style_id( 0 ) {} 424 | CellDataStr( const std::string & _str ) : value( _str ), style_id( 0 ) {} 425 | CellDataStr( const std::string & _str, size_t _style_id ) : value( _str ), style_id( _style_id ) {} 426 | 427 | CellDataStr & operator=( const CellDataStr & obj ) 428 | { 429 | value = obj.value; 430 | style_id = obj.style_id; 431 | return *this; 432 | } 433 | 434 | CellDataStr & operator=( const char * pStr ) 435 | { 436 | value = pStr; 437 | return *this; 438 | } 439 | 440 | CellDataStr & operator=( const std::string & _str ) 441 | { 442 | value = _str; 443 | return *this; 444 | } 445 | 446 | CellDataStr( const std::wstring & _str ) : value( UTF8Encoder::From_wstring( _str ) ), style_id( 0 ) {} 447 | CellDataStr( const std::wstring & _str, size_t _style_id ) : value( UTF8Encoder::From_wstring( _str ) ), style_id( _style_id ) {} 448 | 449 | CellDataStr & operator=( const wchar_t * pStr ) 450 | { 451 | value = UTF8Encoder::From_wstring( pStr ); 452 | return *this; 453 | } 454 | 455 | CellDataStr & operator=( const std::wstring & _str ) 456 | { 457 | value = UTF8Encoder::From_wstring( _str ); 458 | return *this; 459 | } 460 | }; ///< cell data:style pair 461 | 462 | class CellDataTime 463 | { 464 | public: 465 | size_t style_id; 466 | 467 | inline CellDataTime() : style_id( 0 ), m_xlsx_val( 0.0 ) {} 468 | inline CellDataTime( time_t _val, size_t _style_id = 0 ) : style_id( _style_id ), m_xlsx_val( From_time_t( _val ) ) {} 469 | 470 | // Year must be in the range 1900 to 9999, month must be in the range 1 to 12, and day must be in the range 1 to 31. 471 | // Hour must be in the range 0 to 23, minute and second must be in the range 0 to 59, and millisecond must be in the range 0 to 999. 472 | inline CellDataTime( uint16_t year, uint16_t month, uint16_t day, size_t _style_id = 0 ) : 473 | style_id( _style_id ), m_xlsx_val( FromGregorian( year, month, day, 0, 0, 0 ) ) {} 474 | inline CellDataTime( uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t millisecond = 0, size_t _style_id = 0 ) : 475 | style_id( _style_id ), m_xlsx_val( FromGregorian( year, month, day, hour, minute, second, millisecond ) ) {} 476 | 477 | inline CellDataTime & operator=( const CellDataTime & obj ) 478 | { 479 | style_id = obj.style_id; 480 | m_xlsx_val = obj.m_xlsx_val; 481 | return *this; 482 | } 483 | 484 | inline CellDataTime & operator=( time_t _val ) 485 | { 486 | return SetDateTime( _val ); 487 | } 488 | 489 | inline CellDataTime & SetDateTime( time_t val ) 490 | { 491 | m_xlsx_val = From_time_t( val ); 492 | return * this; 493 | } 494 | // Year must be in the range 1900 to 9999, month must be in the range 1 to 12, and day must be in the range 1 to 31. 495 | // Hour must be in the range 0 to 23, minute and second must be in the range 0 to 59, and millisecond must be in the range 0 to 999. 496 | inline CellDataTime & SetDateTime( uint16_t year, uint8_t month, uint8_t day, 497 | uint8_t hour = 0, uint8_t minute = 0, uint8_t second = 0, uint16_t millisecond = 0 ) 498 | { 499 | m_xlsx_val = FromGregorian( year, month, day, hour, minute, second, millisecond ); 500 | return * this; 501 | } 502 | 503 | inline double XlsxValue() const 504 | { 505 | return m_xlsx_val; 506 | } 507 | 508 | #ifdef _WIN32 509 | inline CellDataTime( const SYSTEMTIME & win_st, size_t _style_id = 0 ) : style_id( _style_id ), m_xlsx_val( FromWinSystemTime( win_st ) ) {} 510 | 511 | // *INDENT-OFF* For AStyle tool 512 | inline CellDataTime & SetDateTime( const SYSTEMTIME & win_st ) { m_xlsx_val = FromWinSystemTime( win_st ); return * this; } 513 | inline CellDataTime & operator=( const SYSTEMTIME & win_st ) { return SetDateTime( win_st ); } 514 | // *INDENT-ON* For AStyle tool 515 | #endif 516 | 517 | #if defined( QT_VERSION ) && ( QT_VERSION >= 0x040000 ) 518 | inline CellDataTime( const QTime & t, size_t _style_id = 0 ) : style_id( _style_id ), m_xlsx_val( FromQTime( t ) ) {} 519 | inline CellDataTime( const QDate & d, size_t _style_id = 0 ) : style_id( _style_id ), m_xlsx_val( FromQDate( d ) ) {} 520 | inline CellDataTime( const QDateTime & dt, size_t _style_id = 0 ) : style_id( _style_id ), m_xlsx_val( FromQDateTime( dt ) ) {} 521 | 522 | // *INDENT-OFF* For AStyle tool 523 | inline CellDataTime & SetTime( const QTime & t ) { m_xlsx_val = FromQTime( t ); return * this; } 524 | inline CellDataTime & SetDate( const QDate & d ) { m_xlsx_val = FromQDate( d ); return * this; } 525 | inline CellDataTime & SetDateTime( const QDateTime & dt ) { m_xlsx_val = FromQDateTime( dt ); return * this; } 526 | 527 | inline CellDataTime & operator=( const QTime & t ) { return SetTime( t ); } 528 | inline CellDataTime & operator=( const QDate & d ) { return SetDate( d ); } 529 | inline CellDataTime & operator=( const QDateTime & dt ) { return SetDateTime( dt ); } 530 | // *INDENT-ON* For AStyle tool 531 | #endif 532 | 533 | private: 534 | double m_xlsx_val; 535 | 536 | static double From_time_t( time_t val ); 537 | // Year must be in the range 1900 to 9999, month must be in the range 1 to 12, and day must be in the range 1 to 31. 538 | // Hour must be in the range 0 to 23, minute and second must be in the range 0 to 59, and millisecond must be in the range 0 to 999. 539 | static double FromGregorian( uint16_t year, uint16_t month, uint16_t day, uint16_t hour, uint16_t minute, uint16_t second, uint16_t millisecond = 0 ); 540 | 541 | #ifdef _WIN32 542 | static inline double FromWinSystemTime( const SYSTEMTIME & win_st ) 543 | { 544 | return FromGregorian( win_st.wYear, win_st.wMonth, win_st.wDay, win_st.wHour, win_st.wMinute, win_st.wSecond, win_st.wMilliseconds ); 545 | } 546 | #endif 547 | 548 | #if defined( QT_VERSION ) && ( QT_VERSION >= 0x040000 ) 549 | static inline double FromQTime( const QTime & t ) 550 | { 551 | assert( t.isValid() ); 552 | return FromGregorian( 1900, 1, 1, t.hour(), t.minute(), t.second(), t.msec() ); 553 | } 554 | static inline double FromQDate( const QDate & d ) 555 | { 556 | assert( d.isValid() ); 557 | return FromGregorian( d.year(), d.month(), d.day(), 0, 0, 0 ); 558 | } 559 | static inline double FromQDateTime( const QDateTime & dt ) 560 | { 561 | assert( dt.isValid() ); 562 | const QDate d = dt.date(); 563 | const QTime t = dt.time(); 564 | return FromGregorian( d.year(), d.month(), d.day(), t.hour(), t.minute(), t.second(), t.msec() ); 565 | } 566 | #endif 567 | }; ///< cell data:style pair 568 | 569 | class CellDataInt 570 | { 571 | public: 572 | int32_t value; 573 | size_t style_id; 574 | 575 | public: 576 | CellDataInt() : value( 0 ), style_id( 0 ) {} 577 | CellDataInt( int32_t _val ) : value( _val ), style_id( 0 ) {} 578 | CellDataInt( int32_t _val, size_t _style_id ) : value( _val ), style_id( _style_id ) {} 579 | 580 | CellDataInt & operator=( const CellDataInt & obj ) 581 | { 582 | value = obj.value; 583 | style_id = obj.style_id; 584 | return *this; 585 | } 586 | 587 | CellDataInt & operator=( int32_t _val ) 588 | { 589 | value = _val; 590 | return *this; 591 | } 592 | }; ///< cell data:style pair 593 | class CellDataUInt 594 | { 595 | public: 596 | uint32_t value; 597 | size_t style_id; 598 | 599 | public: 600 | CellDataUInt() : value( 0 ), style_id( 0 ) {} 601 | CellDataUInt( uint32_t _val ) : value( _val ), style_id( 0 ) {} 602 | CellDataUInt( uint32_t _val, size_t _style_id ) : value( _val ), style_id( _style_id ) {} 603 | 604 | CellDataUInt & operator=( const CellDataUInt & obj ) 605 | { 606 | value = obj.value; 607 | style_id = obj.style_id; 608 | return *this; 609 | } 610 | 611 | CellDataUInt & operator=( uint32_t _val ) 612 | { 613 | value = _val; 614 | return *this; 615 | } 616 | }; ///< cell data:style pair 617 | class CellDataDbl 618 | { 619 | public: 620 | double value; 621 | size_t style_id; 622 | 623 | public: 624 | CellDataDbl() : value( 0.0 ), style_id( 0 ) {} 625 | CellDataDbl( double _val ) : value( _val ), style_id( 0 ) {} 626 | CellDataDbl( double _val, size_t _style_id ) : value( _val ), style_id( _style_id ) {} 627 | 628 | CellDataDbl & operator=( const CellDataDbl & obj ) 629 | { 630 | value = obj.value; 631 | style_id = obj.style_id; 632 | return *this; 633 | } 634 | 635 | CellDataDbl & operator=( double _val ) 636 | { 637 | value = _val; 638 | return *this; 639 | } 640 | }; ///< cell data:style pair 641 | class CellDataFlt 642 | { 643 | public: 644 | float value; 645 | size_t style_id; 646 | 647 | public: 648 | CellDataFlt() : value( 0.0 ), style_id( 0 ) {} 649 | CellDataFlt( float _val ) : value( _val ), style_id( 0 ) {} 650 | CellDataFlt( float _val, size_t _style_id ) : value( _val ), style_id( _style_id ) {} 651 | 652 | CellDataFlt & operator=( const CellDataFlt & obj ) 653 | { 654 | value = obj.value; 655 | style_id = obj.style_id; 656 | return *this; 657 | } 658 | 659 | CellDataFlt & operator=( float _val ) 660 | { 661 | value = _val; 662 | return *this; 663 | } 664 | }; ///< cell data:style pair 665 | 666 | /// @brief This structure describes comment item that can added to a cell 667 | struct Comment 668 | { 669 | size_t sheetIndex; ///< sheetIndex internal page index (must not be changed manually) 670 | std::list > contents; ///< contents set of contents with specified fonts 671 | CellCoord cellRef; ///< cellRef reference to the cell 672 | std::string fillColor; ///< fillColor comment box background colour (format: #RRGGBB) 673 | bool isHidden; ///< isHidden determines if comments box is hidden 674 | int x; ///< x absolute position in pt (can be left unset) 675 | int y; ///< y absolute position in pt (can be left unset) 676 | int width; ///< width width in pt (can be left unset) 677 | int height; ///< height height in pt (can be left unset) 678 | 679 | Comment() 680 | { 681 | Clear(); 682 | } 683 | 684 | void Clear(); 685 | 686 | void AddContent( const Font & afont, const UniString & astring ) 687 | { 688 | contents.push_back( std::pair( afont, astring ) ); 689 | } 690 | 691 | bool operator < ( const Comment & _comm ) const 692 | { 693 | return ( sheetIndex < _comm.sheetIndex ); 694 | } 695 | }; 696 | 697 | /// @brief Style describes a set of styling parameter that can be used into final document 698 | /// @see EBorder 699 | /// @see EAlignHoriz 700 | /// @see EAlignVert 701 | class Style 702 | { 703 | public: 704 | Font font; ///< font structure object describes font 705 | Fill fill; ///< fill structure object describes fill 706 | Border border; ///< border combination of border attributes 707 | NumFormat numFormat; ///< numFormat structure object describes numeric cell representation 708 | EAlignHoriz horizAlign; ///< horizAlign cell content horizontal alignment value 709 | EAlignVert vertAlign; ///< vertAlign cell content vertical alignment value 710 | bool wrapText; ///< wrapText text wrapping property 711 | int textRotation; ///< textRotation angle in degree from -90 to 90 712 | 713 | public: 714 | Style() 715 | { 716 | Clear(); 717 | } 718 | 719 | void Clear(); 720 | }; 721 | 722 | /// @brief This structure represents a handle to manage newly adding styles to avoid dublicating 723 | class StyleList 724 | { 725 | public: 726 | static const size_t BUILT_IN_STYLES_NUMBER = 164; 727 | static const size_t STYLE_LINK_NUMBER = 4; 728 | 729 | enum 730 | { 731 | STYLE_LINK_BORDER = 0, 732 | STYLE_LINK_FONT, 733 | STYLE_LINK_FILL, 734 | STYLE_LINK_NUM_FORMAT 735 | }; 736 | 737 | struct StylePosInfo 738 | { 739 | EAlignHoriz horizAlign; 740 | EAlignVert vertAlign; 741 | bool wrapText; 742 | int textRotation; 743 | 744 | inline bool isAllDefault() const 745 | { 746 | return ( horizAlign == ALIGN_H_NONE ) && ( vertAlign == ALIGN_V_NONE ) && ! wrapText && ( textRotation == 0 ); 747 | } 748 | }; 749 | 750 | private: 751 | size_t m_fmtLastId; ///< m_fmtLastId format counter. There are 164 (0 - 163) built-in numeric formats 752 | 753 | std::vector m_borders; ///< borders set of values represent styled borders 754 | std::vector m_fonts; ///< fonts set of fonts to be declared 755 | std::vector m_fills; ///< fills set of fills to be declared 756 | std::vector m_nums; ///< nums set of number formats to be declared 757 | std::vector > m_styleIndexes;///< styleIndexes vector of a number triplet contains links to style parts: 758 | /// first - border id in borders 759 | /// second - font id in fonts 760 | /// third - fill id in fills 761 | /// fourth - number format id in nums 762 | 763 | std::vector< StylePosInfo > m_stylePos;///< stylePos vector of a number triplet contains style`s alignments and wrap sign: 764 | 765 | public: 766 | StyleList(); 767 | 768 | // *INDENT-OFF* For AStyle tool 769 | /// @brief For internal use (at the book saving) 770 | inline const std::vector & GetBorders() const { return m_borders; } 771 | 772 | /// @brief For internal use (at the book saving) 773 | inline const std::vector & GetFonts() const { return m_fonts; } 774 | 775 | /// @brief For internal use (at the book saving) 776 | inline const std::vector & GetFills() const { return m_fills; } 777 | 778 | /// @brief For internal use (at the book saving) 779 | inline const std::vector & GetNumFormats() const { return m_nums; } 780 | 781 | /// @brief For internal use (at the book saving) 782 | inline const std::vector > & GetIndexes() const { return m_styleIndexes; } 783 | 784 | /// @brief For internal use (at the book saving) 785 | inline const std::vector< StylePosInfo > & GetPositions() const { return m_stylePos; } 786 | // *INDENT-ON* For AStyle tool 787 | 788 | /// @brief Adds a new style into collection if it is not exists yet 789 | /// @param style Reference to the Style structure object 790 | /// @return Style index that should be used at data appending to a data sheet 791 | /// @note If returned value is 0 - this is a default normal style and it is optional 792 | /// whether is will be added into column description or not 793 | /// (but better not to add to reduce size and resource consumption) 794 | size_t Add( const Style & style ); 795 | }; 796 | 797 | //Struct for the drawing (chart, image) position description 798 | struct DrawingPoint 799 | { 800 | uint32_t col; ///< Column (starts from 0) 801 | uint32_t colOff;///< Column Offset (starts from 0) 802 | uint32_t row; ///< Row (starts from 0) 803 | uint32_t rowOff;///< Row Offset (starts from 0) 804 | 805 | DrawingPoint() {} 806 | DrawingPoint( uint32_t acol, uint32_t arow ) : 807 | col( acol ), colOff( 0 ), row( arow ), rowOff( 0 ) {} 808 | DrawingPoint( uint32_t acol, uint32_t acolOff, uint32_t arow, uint32_t arowOff ) : 809 | col( acol ), colOff( acolOff ), row( arow ), rowOff( arowOff ) {} 810 | }; 811 | 812 | //Class for image description 813 | class CImage 814 | { 815 | public: 816 | enum ImageType 817 | { 818 | unknown, gif, jpg, jpeg, png, tif, tiff 819 | }; 820 | 821 | std::string LocalPath; //Path to the file in the system 822 | std::string InternalName; //Name of the file in XLSX 823 | ImageType Type; //Image type (extension) 824 | uint16_t Width; //Width of the image 825 | uint16_t Height; //Height of the image 826 | 827 | static const uint16_t PointByPixel = 9525; // Points count by one pixel 828 | 829 | CImage( const std::string & LocPath, const std::string & TempPath, ImageType AType, uint16_t AWidth, uint16_t AHeight ) : 830 | LocalPath( LocPath ), InternalName( TempPath ), Type( AType ), Width( AWidth ), Height( AHeight ) {} 831 | }; 832 | 833 | // Base class for CWorksheet and CChartsheet 834 | class CSheet 835 | { 836 | public: 837 | virtual ~CSheet(); 838 | virtual const UniString & GetTitle() const = 0; 839 | 840 | inline size_t GetIndex() const 841 | { 842 | return m_index; 843 | } 844 | 845 | protected: 846 | const size_t m_index; ///< current sheet number 847 | 848 | CSheet( size_t SheetIndex ) : m_index( SheetIndex ) {} 849 | }; 850 | 851 | } // namespace SimpleXlsx 852 | 853 | #endif // XLSX_SIMPLE_XLSX_DEF_H 854 | --------------------------------------------------------------------------------