├── .dockerignore ├── .github └── workflows │ └── test.yml ├── .gitignore ├── .octocov.yml ├── CHANGELOG.md ├── Dockerfile.test ├── Gemfile ├── LICENSE ├── Makefile ├── README.md ├── Rakefile ├── benchmarks ├── 1k_rows.rb ├── 20k_rows.rb ├── auto_width.rb ├── init.rb ├── memory.rb ├── profiler.rb └── write_value.rb ├── examples ├── example.rb ├── example_align.rb ├── example_auto_width.rb ├── example_chart.rb ├── example_colors.rb ├── example_date_time.rb ├── example_filters.rb ├── example_formula.rb ├── example_hyperlink.rb ├── example_image.rb ├── example_styles.rb └── logo.png ├── ext └── fast_excel │ ├── extconf.rb │ └── text_width_ext.c ├── extconf.rb ├── fast_excel.gemspec ├── letters.html ├── lib ├── fast_excel.rb └── fast_excel │ ├── binding.rb │ └── binding │ ├── chart.rb │ ├── format.rb │ ├── workbook.rb │ └── worksheet.rb ├── libxlsxwriter ├── .github │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE.md │ ├── PULL_REQUEST_TEMPLATE.md │ └── workflows │ │ ├── cmake_actions.yml │ │ ├── code_style.yml │ │ ├── coverity.yml │ │ ├── make_actions.yml │ │ ├── valgrind.yml │ │ ├── windows_build.yml │ │ └── zig_build.yml ├── .gitignore ├── .indent.pro ├── CMakeLists.txt ├── CONTRIBUTING.md ├── Changes.txt ├── LICENSE.txt ├── Makefile ├── Package.swift ├── Readme.md ├── build.zig ├── build.zig.zon ├── cmake │ ├── FindMINIZIP.cmake │ ├── FindPackage.cmake │ └── i686-toolchain.cmake ├── cocoapods │ ├── libxlsxwriter-umbrella.h │ └── libxlsxwriter.modulemap ├── include │ ├── xlsxwriter.h │ └── xlsxwriter │ │ ├── app.h │ │ ├── chart.h │ │ ├── chartsheet.h │ │ ├── comment.h │ │ ├── common.h │ │ ├── content_types.h │ │ ├── core.h │ │ ├── custom.h │ │ ├── drawing.h │ │ ├── format.h │ │ ├── hash_table.h │ │ ├── metadata.h │ │ ├── packager.h │ │ ├── relationships.h │ │ ├── shared_strings.h │ │ ├── styles.h │ │ ├── table.h │ │ ├── theme.h │ │ ├── third_party │ │ ├── emyg_dtoa.h │ │ ├── ioapi.h │ │ ├── md5.h │ │ ├── queue.h │ │ ├── tmpfileplus.h │ │ ├── tree.h │ │ └── zip.h │ │ ├── utility.h │ │ ├── vml.h │ │ ├── workbook.h │ │ ├── worksheet.h │ │ └── xmlwriter.h ├── lib │ └── .gitignore ├── libxlsxwriter.podspec ├── src │ ├── Makefile │ ├── app.c │ ├── chart.c │ ├── chartsheet.c │ ├── comment.c │ ├── content_types.c │ ├── core.c │ ├── custom.c │ ├── drawing.c │ ├── format.c │ ├── hash_table.c │ ├── metadata.c │ ├── packager.c │ ├── relationships.c │ ├── shared_strings.c │ ├── styles.c │ ├── table.c │ ├── theme.c │ ├── utility.c │ ├── vml.c │ ├── workbook.c │ ├── worksheet.c │ └── xmlwriter.c ├── third_party │ ├── dtoa │ │ ├── Makefile │ │ ├── emyg_dtoa.c │ │ └── emyg_dtoa.h │ ├── md5 │ │ ├── Makefile │ │ ├── md5.c │ │ └── md5.h │ ├── minizip │ │ ├── Makefile │ │ ├── Makefile.am │ │ ├── Makefile.orig │ │ ├── MiniZip64_Changes.txt │ │ ├── MiniZip64_info.txt │ │ ├── README.txt │ │ ├── configure.ac │ │ ├── crypt.h │ │ ├── ioapi.c │ │ ├── ioapi.h │ │ ├── iowin32.c │ │ ├── iowin32.h │ │ ├── make_vms.com │ │ ├── miniunz.c │ │ ├── miniunzip.1 │ │ ├── minizip.1 │ │ ├── minizip.c │ │ ├── minizip.pc.in │ │ ├── mztools.c │ │ ├── mztools.h │ │ ├── unzip.c │ │ ├── unzip.h │ │ ├── zip.c │ │ └── zip.h │ └── tmpfileplus │ │ ├── Makefile │ │ ├── tmpfileplus.c │ │ └── tmpfileplus.h └── version.txt ├── sonar-project.properties └── test ├── auto_width_test.rb ├── date_test.rb ├── default_format_test.rb ├── format_test.rb ├── reopen_test.rb ├── test_helper.rb ├── tmpfile_test.rb ├── validations_test.rb └── worksheet_test.rb /.dockerignore: -------------------------------------------------------------------------------- 1 | libxlsxwriter 2 | .git 3 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test: 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | os: [ubuntu-latest, macos-latest, windows-latest] 11 | ruby: [2.7, 3.1, 3.3, 3.4] 12 | 13 | runs-on: ${{ matrix.os }} 14 | 15 | steps: 16 | - uses: actions/checkout@v2 17 | - uses: ruby/setup-ruby@v1 18 | with: 19 | ruby-version: ${{ matrix.ruby }} 20 | 21 | - run: bundle config set --local without 'benchmarks' 22 | - run: bundle install 23 | - run: make 24 | - run: make install 25 | 26 | - run: rake test 27 | - run: rake examples 28 | - run: gem build fast_excel.gemspec 29 | 30 | - name: Coverage Report by octocov 31 | if: ${{ matrix.os == 'ubuntu-latest' && matrix.ruby == '3.4' }} 32 | uses: k1LoW/octocov-action@v1 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .ruby-version 2 | .idea/ 3 | try.c 4 | try.rb 5 | gen.rb 6 | gen_ffi.rb 7 | *.xlsx 8 | a.out 9 | .DS_Store 10 | *.gem 11 | *.cmake 12 | libxlsxwriter/CmakeFiles 13 | libxlsxwriter/CmakeCache.txt 14 | libxlsxwriter/dev 15 | libxlsxwriter/docs 16 | libxlsxwriter/examples 17 | libxlsxwriter/test 18 | ext/fast_excel/text_width_ext.o 19 | ext/fast_excel/Makefile 20 | ext/fast_excel/text_width_ext.bundle 21 | Gemfile.lock 22 | lib/libxlsxwriter.dylib 23 | coverage/ 24 | -------------------------------------------------------------------------------- /.octocov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | paths: 3 | - coverage/.resultset.json 4 | codeToTestRatio: 5 | code: 6 | - '**/*.rb' 7 | - '!test/**/*.rb' 8 | test: 9 | - 'test/**/*_test.rb' 10 | testExecutionTime: 11 | if: true 12 | diff: 13 | datastores: 14 | - artifact://${GITHUB_REPOSITORY} 15 | comment: 16 | if: is_pull_request 17 | deletePrevious: true 18 | report: 19 | if: is_default_branch 20 | datastores: 21 | - artifact://${GITHUB_REPOSITORY} 22 | timeout: 5min 23 | summary: 24 | if: true 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | #### Version 0.5.0 - 02 jan 2024 2 | 3 | * Support ruby 3.3 4 | * Sync latest libxlsxwriter 5 | * Add support for writing cell comments 6 | * Add more examples 7 | * Fix compilation of minizip on NixOS (Thanks to @Mange) 8 | * On close set empty columns to default width (Thanks to @steffansluis) 9 | 10 | #### Version 0.4.1 - 13 jan 2023 11 | 12 | * Support ruby 3.2 13 | * Improve library loading (Thanks to @sly7-7 and @BrianHawley) 14 | * Ensure Time.zone is not nil (Thanks to @ksuh90) 15 | * Get utc_offset from current value if possible (Thanks to @KevinSchiffmann) 16 | * Validate worksheet name using Libxlsxwriter (Thanks to @datbth) 17 | * Fix readme typo (Thanks to @sw4d) 18 | 19 | #### Version 0.4.0 - 14 feb 2021 20 | 21 | * Support ruby 3.0 22 | * Fix for ffi library loading issue on Windows 23 | 24 | #### Version 0.3.0 - 23 jul 2020 25 | 26 | * Add support for FastExcel::URL 27 | * Add support for writing boolean values 28 | * Add enable_filters!(end_col: X) 29 | * Allow to open with an empty existing file 30 | * Add missing enums to chart 31 | * Don't change sheet name from "" to nil 32 | * Support build with docker 33 | * Fix crash when sheet name exceeds maximum length. 34 | * [BREAKING CHANGE] Rename `worksheet.right_to_left` to `worksheet.set_right_to_left`: 35 | - now it will work properly when using the `pry-rails` gem, not forcing the document start from right even when this method is not called. 36 | 37 | #### Version 0.2.6 - 26 jan 2019 38 | 39 | * Add column auto width (thanks to @duffyjp) 40 | 41 | #### Version 0.2.5 - 22 jun 2018 42 | 43 | * Update libxlsxwriter to 0.7.7 44 | 45 | #### Version 0.2.4 - 13 mar 2018 46 | 47 | * Update libxlsxwriter to 0.7.6 48 | * Don’t crash process when duplicated worksheet name 49 | 50 | #### Version 0.2.3 - 27 oct 2017 51 | 52 | * Allow Date along with DateTime in write_value (thanks to @noxern) 53 | 54 | #### Version 0.2.2 - 20 sep 2017 55 | 56 | * Nice setters and getters for format.align 57 | * Add nice setters for colors and borders 58 | * Add sheet.append_row, sheet.last_row_number 59 | * Run tests in CI 60 | * Performance optimizations and type check refactoring 61 | * Add styles_example.rb 62 | * Fix assigning align from other format 63 | 64 | #### Version 0.2.1 - 20 jun 2017 65 | 66 | * Add FastExcel::Formula 67 | 68 | #### Version 0.2.0 - 24 apr 2017 69 | 70 | * Add FastExcel.date_num 71 | * Add feature to use user default font 72 | * Add benchmarks 73 | 74 | #### Version 0.1.0 - 24 feb 2017 75 | 76 | Initial 77 | -------------------------------------------------------------------------------- /Dockerfile.test: -------------------------------------------------------------------------------- 1 | FROM ruby 2 | 3 | RUN gem install fast_excel 4 | 5 | ARG TRAVIS_COMMIT 6 | ARG TRAVIS_BRANCH 7 | ARG GIT_REPO 8 | 9 | RUN echo "source 'https://rubygems.org'" > Gemfile 10 | 11 | RUN [ -z "$TRAVIS_COMMIT" ] && \ 12 | echo "gem 'fast_excel', git: 'https://github.com/Paxa/fast_excel.git'" >> Gemfile || true 13 | RUN [ -z "$TRAVIS_COMMIT" ] || \ 14 | echo "gem 'fast_excel', git: 'https://github.com/${GIT_REPO}.git', branch: '$TRAVIS_BRANCH', ref: '$TRAVIS_COMMIT'" >> Gemfile 15 | 16 | RUN cat Gemfile 17 | RUN bundle -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem 'rake' 6 | 7 | gem 'roo' 8 | gem 'csv' 9 | gem 'bigdecimal' 10 | 11 | gem 'simplecov', require: false 12 | gem 'minitest' 13 | gem 'minitest-reporters' 14 | 15 | group :benchmarks do 16 | gem 'caxlsx', git: 'https://github.com/caxlsx/caxlsx' 17 | gem 'write_xlsx' 18 | gem 'xlsxtream' 19 | gem 'benchmark-ips' 20 | gem 'process_memory', git: 'https://github.com/paxa/process_memory', platforms: :ruby 21 | end 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Pavel Evstigneev 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 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | Q=@ 2 | ifdef V 3 | Q= 4 | endif 5 | 6 | UNAME := $(shell uname) 7 | 8 | LIBXLSXWRITER_SO = libxlsxwriter.so 9 | 10 | ifeq ($(UNAME), Darwin) 11 | LIBXLSXWRITER_SO = libxlsxwriter.dylib 12 | endif 13 | 14 | # Check for MinGW/MinGW64/Cygwin environments. 15 | ifneq (,$(findstring MINGW, $(UNAME))) 16 | MING_LIKE = y 17 | endif 18 | ifneq (,$(findstring MSYS, $(UNAME))) 19 | MING_LIKE = y 20 | endif 21 | ifneq (,$(findstring CYGWIN, $(UNAME))) 22 | MING_LIKE = y 23 | endif 24 | 25 | ifdef MING_LIKE 26 | LIBXLSXWRITER_SO = libxlsxwriter.dll 27 | endif 28 | 29 | # with xcode better to use cmake 30 | UNAME_S := $(shell uname -s) 31 | ifeq ($(UNAME_S),"Darwin") 32 | USE_CMAKE := $(shell command -v cmake 2> /dev/null) 33 | endif 34 | 35 | ifndef ($(sitearchdir)) 36 | sitearchdir = './lib' 37 | endif 38 | 39 | all : 40 | # @echo "Compiling ext/text_width ..." 41 | # rake compile 42 | @echo "Compiling libxlsxwriter ..." 43 | ifdef USE_CMAKE 44 | @echo "run cmake libxlsxwriter ..." 45 | cmake libxlsxwriter 46 | else 47 | $(Q)$(MAKE) -C libxlsxwriter 48 | endif 49 | 50 | clean : 51 | $(Q)$(MAKE) clean -C libxlsxwriter 52 | 53 | install : 54 | $(Q)cp libxlsxwriter/lib/$(LIBXLSXWRITER_SO) $(sitearchdir) 55 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ultra Fast Excel Writer for Ruby 2 | 3 | ```ruby 4 | require 'fast_excel' 5 | 6 | workbook = FastExcel.open("hello_world.xlsx", constant_memory: true) 7 | workbook.default_format.set( 8 | font_size: 0, # user's default 9 | font_family: "Arial" 10 | ) 11 | 12 | worksheet = workbook.add_worksheet("Example Report") 13 | 14 | bold = workbook.bold_format 15 | worksheet.set_column(0, 0, FastExcel::DEF_COL_WIDTH, bold) 16 | 17 | price = workbook.number_format("#,##0.00") 18 | worksheet.set_column(1, 1, 20, price) 19 | 20 | date_format = workbook.number_format("[$-409]m/d/yy h:mm AM/PM;@") 21 | worksheet.set_column(2, 2, 20, date_format) 22 | 23 | worksheet.append_row(["message", "price", "date"], bold) 24 | 25 | for i in 1..1000 26 | worksheet.append_row(["Hello", (rand * 10_000_000).round(2), Time.now]) 27 | end 28 | 29 | worksheet.append_row(["Sum", FastExcel::Formula.new("SUM(B2:B1001)")], bold) 30 | 31 | workbook.close 32 | ``` 33 | 34 | See [more examples](https://github.com/Paxa/fast_excel/tree/master/examples) 35 | 36 | This repository and gem contain sources of [libxlsxwriter](https://github.com/jmcnamara/libxlsxwriter) 37 | 38 | ## Install 39 | 40 | ```ruby 41 | # Gemfile 42 | gem 'fast_excel' 43 | ``` 44 | Or 45 | ``` 46 | gem install fast_excel 47 | ``` 48 | 49 | 50 | 51 | ### Create Document 52 | ```ruby 53 | workbook = FastExcel.open # creates tmp file 54 | # ... 55 | send_data(workbook.read_string, filename: "table.xlsx") # read tmp file and delete it 56 | ``` 57 | 58 | Also can use `workbook.remove_tmp_folder` to delete tmp file manually 59 | 60 | 61 | **Constant memory mode**: saves each row to disk, good for really big files but can not change previous lines that already saved 62 | ```ruby 63 | workbook = FastExcel.open(constant_memory: true) 64 | ``` 65 | 66 | **Save to file** 67 | ```ruby 68 | workbook = FastExcel.open("my_dinner.xlsx") 69 | ``` 70 | 71 | ### Write Data 72 | FastExcel will automatically detect data type and one of `write_number` or `write_datetime` or `write_formula` or `write_string` or `write_url` 73 | ```ruby 74 | workbook = FastExcel.open 75 | worksheet = workbook.add_worksheet 76 | 77 | # write specific type value value 78 | worksheet.write_number(row = 0, col = 5, 1_234_567, format = nil) 79 | 80 | # write value with type detection 81 | worksheet.write_value(row = 0, col = 5, 1_234_567, format = nil) 82 | 83 | # write row of values. format argument can be format object or array of format objects 84 | worksheet.write_row(row = 1, ["strong", 123_456, Time.now], format = nil) 85 | 86 | # write row to the bottom 87 | worksheet.append_row(["strong", 123_456, Time.now], ) 88 | 89 | # shortcut for append_row() 90 | worksheet << ["strong", 123_456, Time.now] 91 | ``` 92 | 93 | **Saving dates**: excel store dates as number of days since 1st January 1900, and FastExcel will make it for you. 94 | 95 | To make saving of dates slightly faster can use `FastExcel.date_num` helper: 96 | ```ruby 97 | date_format = workbook.number_format("[$-409]m/d/yy hh:mm;@") 98 | worksheet.write_number(0, 0, FastExcel.date_num(Time.now, Time.zone.utc_offset), date_format) 99 | ``` 100 | 101 | **Formulas**: special type of value in excel 102 | ```ruby 103 | worksheet << [1, 2, 3, 4] 104 | worksheet << [FastExcel::Formula.new("SUM(A1:D1)")] # A2 will be shown as 10 105 | ``` 106 | 107 | **URL**: Link to website or something else 108 | ```ruby 109 | url_format = workbook.add_format(underline: :underline_single, font_color: :blue) # format is optional 110 | worksheet.append_row([ 111 | FastExcel::URL.new("https://github.com/Paxa/fast_excel"), 112 | FastExcel::URL.new("postgres://localhost") 113 | ], url_format) 114 | # or 115 | worksheet.write_url(0, 2, "https://github.com/Paxa/fast_excel", url_format) 116 | ``` 117 | 118 | 119 | ### Data Formatting 120 | ```ruby 121 | format = workbook.add_format( 122 | bold: true, 123 | italic: true, 124 | font_outline: true, 125 | font_shadow: true, 126 | text_wrap: true, 127 | font_strikeout: true, 128 | shrink: true, 129 | text_justlast: true, 130 | font_size: 13, # default is 11, use 0 for user's default 131 | font_name: "Arial", # default is Calibri, also accessible via font_family 132 | font_color: :orange, # can use RGB hex as "#FF0000" or 0x00FF00 or color name as symbol or string 133 | font_script: :font_subscript, 134 | rotation: 10, 135 | underline: :underline_single, # or :underline_double or :underline_single_accounting or :underline_double_accounting 136 | indent: 1, 137 | # border styles 138 | border: :border_thin, 139 | left: :medium, 140 | top: :dashed, 141 | right: :double, 142 | bottom: :hair, 143 | bottom_color: :alice_blue, 144 | top_color: "#11ABCD", 145 | # Align 146 | align: {h: :align_center, v: :align_vertical_center}, 147 | num_format: "#,##0.00" 148 | ) 149 | ``` 150 | 151 | **Shortcuts**: 152 | ```ruby 153 | workbook.bold_format # bold text 154 | workbook.number_format("[$-409]m/d/yy h:mm AM/PM;@") # format for date 155 | ``` 156 | 157 | ### Set Column Width 158 | 159 | ```ruby 160 | worksheet.set_column(start_col, end_col, width = nil, format = nil) 161 | # or 162 | worksheet.set_column_width(col, width = 60) 163 | # or 164 | worksheet.set_columns_width(start_col, end_col, width = 60) 165 | ``` 166 | 167 | ### Set Row Height 168 | ```ruby 169 | worksheet.set_row(row_num = 0, height = 30, format = nil) 170 | ``` 171 | 172 | ### Column Auto Width 173 | 174 | Column authwidth only works for string values, because numbers may have custom formatting 175 | 176 | Enabling column auto widths will slow down writing string values for about 15-25% 177 | 178 | ```ruby 179 | require 'fast_excel' 180 | 181 | workbook = FastExcel.open(constant_memory: true) 182 | 183 | worksheet = workbook.add_worksheet 184 | worksheet.auto_width = true 185 | 186 | worksheet.append_row(["some text", "some longer text for example"]) 187 | 188 | content = workbook.read_string 189 | File.open('./some_file.xlsx', 'wb') {|f| f.write(content) } 190 | ``` 191 | 192 | ![fast_excel_auto_width](https://user-images.githubusercontent.com/26019/51788441-ba981300-21b0-11e9-9611-54dda78effcd.png) 193 | 194 | 195 | ### API 196 | 197 | This gem is FFI binding for libxlsxwriter C library with some syntax sugar. All original functions is avaliable, for example: 198 | 199 | ```ruby 200 | Libxlsxwriter.worksheet_activate(worksheet) # => will call void worksheet_activate(lxw_worksheet *worksheet) 201 | # or shorter: 202 | worksheet.activate 203 | ``` 204 | 205 | Full libxlsxwriter documentation: [http://libxlsxwriter.github.io/](http://libxlsxwriter.github.io/) 206 | 207 | Generated rdoc: [rubydoc.info/github/Paxa/fast_excel](https://www.rubydoc.info/github/Paxa/fast_excel) 208 | 209 | ## Benchmarks 210 | 211 | 1000 rows: 212 | ``` 213 | Comparison: 214 | FastExcel: 31.7 i/s 215 | Axlsx: 8.0 i/s - 3.98x slower 216 | write_xlsx: 6.9 i/s - 4.62x slower 217 | ``` 218 | 219 | 20000 rows: 220 | ``` 221 | Comparison: 222 | FastExcel: 1.4 i/s 223 | Axlsx: 0.4 i/s - 3.46x slower 224 | write_xlsx: 0.1 i/s - 17.04x slower 225 | ``` 226 | 227 | Max memory usage, generating 100k rows: 228 | ``` 229 | FastExcel - 20 MB 230 | Axlsx - 60 MB 231 | write_xlsx - 100 MB 232 | ``` 233 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | desc "Sync github.com:Paxa/libxlsxwriter to ./libxlsxwriter" 2 | task :sync do 3 | require 'fileutils' 4 | FileUtils.rm_rf("./libxlsxwriter") 5 | system("git clone --depth 10 git@github.com:Paxa/libxlsxwriter.git") 6 | Dir.chdir("./libxlsxwriter") do 7 | system("git show --pretty='format:%cd %h' --date=iso --quiet > version.txt") 8 | FileUtils.rm_rf("./.git") 9 | end 10 | end 11 | 12 | require 'rake/testtask' 13 | 14 | Rake::TestTask.new do |test| 15 | test.test_files = Dir.glob('test/**/*_test.rb') 16 | end 17 | 18 | #task :default => :test 19 | 20 | desc "Run all examples" 21 | task :examples do 22 | Dir.glob('examples/**/*.rb').each do |file| 23 | require './' + file.sub(/\.rb$/, '') 24 | end 25 | end 26 | 27 | desc "Compile libxlsxwriter shared library" 28 | task :compile do 29 | %x{ 30 | cd ext/fast_excel 31 | ruby ./extconf.rb 32 | make 33 | } 34 | end 35 | -------------------------------------------------------------------------------- /benchmarks/1k_rows.rb: -------------------------------------------------------------------------------- 1 | require_relative 'init' 2 | 3 | HEADERS = ["id", "name", "age", "date"].freeze 4 | 5 | DATA = [] 6 | 1000.times do |n| 7 | DATA << [n, "String string #{n}", (n * rand * 10).round, Time.at(n * 1000 + 1492922688)] 8 | end 9 | 10 | Benchmark.ips do |x| 11 | x.config(time: 10, warmup: 40) 12 | 13 | x.report("FastExcel") do 14 | workbook = FastExcel.open(constant_memory: true) 15 | worksheet = workbook.add_worksheet("benchmark") 16 | 17 | worksheet.write_row(0, HEADERS) 18 | DATA.each do |row| 19 | worksheet.append_row(row) 20 | end 21 | workbook.read_string 22 | end 23 | 24 | x.report("Axlsx") do 25 | filename = "#{Dir.mktmpdir}/axlsx.xlsx" 26 | Axlsx::Package.new do |package| 27 | package.use_autowidth = false 28 | package.workbook.add_worksheet do |sheet| 29 | sheet.add_row(HEADERS) 30 | DATA.each do |row| 31 | sheet.add_row(row) 32 | end 33 | end 34 | package.serialize(filename) 35 | File.open(filename, 'rb', &:read) 36 | File.delete(filename) 37 | end 38 | end 39 | 40 | x.report("write_xlsx") do 41 | filename = "#{Dir.mktmpdir}/write_xlsx.xlsx" 42 | workbook = WriteXLSX.new(filename) 43 | worksheet = workbook.add_worksheet 44 | HEADERS.each_with_index do |value, i| 45 | worksheet.write(0, i, value) 46 | end 47 | DATA.each_with_index do |row, row_num| 48 | worksheet.write_number(row_num + 1, 0, row[0]) 49 | worksheet.write_string(row_num + 1, 1, row[1]) 50 | worksheet.write_number(row_num + 1, 2, row[2]) 51 | worksheet.write_number(row_num + 1, 3, row[3]) 52 | end 53 | workbook.close 54 | File.open(filename, 'rb', &:read) 55 | File.delete(filename) 56 | end 57 | 58 | x.report("xlsxtream") do 59 | filename = "#{Dir.mktmpdir}/xlsxtream.xlsx" 60 | 61 | Xlsxtream::Workbook.open(filename) do |xlsx| 62 | xlsx.write_worksheet do |sheet| 63 | sheet << HEADERS 64 | DATA.each do |row| 65 | sheet << row 66 | end 67 | end 68 | end 69 | end 70 | 71 | x.compare! 72 | end 73 | -------------------------------------------------------------------------------- /benchmarks/20k_rows.rb: -------------------------------------------------------------------------------- 1 | require_relative 'init' 2 | 3 | HEADERS = ["id", "name", "age", "date", "random"] 4 | 5 | DATA = [] 6 | 20_000.times do |n| 7 | DATA << [n, "String string #{n}" * 5, (n * rand * 10).round, Time.at(n * 1000 + 1492922688), n * 100] 8 | end 9 | 10 | Benchmark.ips do |x| 11 | x.config(time: 10, warmup: 2) 12 | 13 | x.report("FastExcel") do 14 | write_fast_excel_20k 15 | end 16 | 17 | x.report("Axlsx") do 18 | write_axlsx_20k 19 | end 20 | 21 | x.report("write_xlsx") do 22 | write_xlsx_20k 23 | end 24 | 25 | x.report("xlsxtream") do 26 | write_xlsxtream_20k 27 | end 28 | 29 | x.compare! 30 | end 31 | -------------------------------------------------------------------------------- /benchmarks/auto_width.rb: -------------------------------------------------------------------------------- 1 | require_relative 'init' 2 | 3 | HEADERS = ["id", "name", "age", "date"] 4 | 5 | DATA = [] 6 | 1000.times do |n| 7 | DATA << [n, "String string #{n}", (n * rand * 10).round, Time.at(n * 1000 + 1492922688)] 8 | end 9 | 10 | Benchmark.ips do |x| 11 | x.config(time: 10, warmup: 2) 12 | 13 | x.report("Normal") do 14 | workbook = FastExcel.open(constant_memory: true) 15 | worksheet = workbook.add_worksheet("benchmark") 16 | 17 | worksheet.write_row(0, HEADERS) 18 | DATA.each_with_index do |row, i| 19 | worksheet.write_row(i + 1, row) 20 | end 21 | workbook.read_string 22 | end 23 | 24 | x.report("With auto_width") do 25 | workbook = FastExcel.open(constant_memory: true) 26 | worksheet = workbook.add_worksheet("benchmark") 27 | worksheet.auto_width = true 28 | 29 | worksheet.write_row(0, HEADERS) 30 | DATA.each_with_index do |row, i| 31 | worksheet.write_row(i + 1, row) 32 | end 33 | workbook.read_string 34 | end 35 | 36 | x.compare! 37 | end 38 | -------------------------------------------------------------------------------- /benchmarks/init.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'fileutils' 3 | require 'tmpdir' 4 | require_relative '../lib/fast_excel' 5 | 6 | # gem install axlsx benchmark-ips write_xlsx 7 | 8 | require "benchmark/ips" 9 | require 'axlsx' 10 | require 'write_xlsx' 11 | require 'xlsxtream' 12 | require 'process_memory' 13 | 14 | def write_fast_excel_20k 15 | workbook = FastExcel.open(constant_memory: true) 16 | worksheet = workbook.add_worksheet("benchmark") 17 | 18 | worksheet.write_row(0, HEADERS) 19 | DATA.each_with_index do |row, i| 20 | worksheet.write_row(i + 1, row) 21 | end 22 | workbook.read_string 23 | end 24 | 25 | def write_xlsx_20k 26 | filename = "#{Dir.mktmpdir}/write_xlsx.xlsx" 27 | workbook = WriteXLSX.new(filename) 28 | worksheet = workbook.add_worksheet 29 | HEADERS.each_with_index do |value, i| 30 | worksheet.write(0, i, value) 31 | end 32 | DATA.each_with_index do |row, row_num| 33 | worksheet.write_number(row_num + 1, 0, row[0]) 34 | worksheet.write_string(row_num + 1, 1, row[1]) 35 | worksheet.write_number(row_num + 1, 2, row[2]) 36 | worksheet.write_number(row_num + 1, 3, row[3]) 37 | worksheet.write_number(row_num + 1, 4, row[4]) 38 | end 39 | workbook.close 40 | File.open(filename, 'rb', &:read) 41 | File.delete(filename) 42 | end 43 | 44 | def write_axlsx_20k 45 | filename = "#{Dir.mktmpdir}/axlsx.xlsx" 46 | Axlsx::Package.new do |package| 47 | package.use_autowidth = false 48 | package.workbook.add_worksheet do |sheet| 49 | sheet.add_row(HEADERS) 50 | DATA.each do |row| 51 | sheet.add_row(row) 52 | end 53 | end 54 | package.serialize(filename) 55 | File.open(filename, 'rb', &:read) 56 | File.delete(filename) 57 | end 58 | end 59 | 60 | def write_xlsxtream_20k 61 | filename = "#{Dir.mktmpdir}/xlsxtream.xlsx" 62 | 63 | Xlsxtream::Workbook.open(filename) do |xlsx| 64 | xlsx.write_worksheet do |sheet| 65 | sheet << HEADERS 66 | DATA.each do |row| 67 | sheet << row 68 | end 69 | end 70 | end 71 | end -------------------------------------------------------------------------------- /benchmarks/memory.rb: -------------------------------------------------------------------------------- 1 | require_relative 'init' 2 | 3 | HEADERS = ["id", "name", "age", "date", "random"] 4 | 5 | DATA = [] 6 | 10_000.times do |n| 7 | DATA << [n, "String string #{n}" * 5, (n * rand * 10).round, Time.at(n * 1000 + 1492922688), n * 100] 8 | end 9 | 10 | puts "warm up..." 11 | write_fast_excel_20k 12 | write_axlsx_20k 13 | write_xlsx_20k 14 | write_xlsxtream_20k 15 | 16 | DATA.clear 17 | 50_000.times do |n| 18 | DATA << [n, "String string #{n}" * 5, (n * rand * 10).round, Time.at(n * 1000 + 1492922688), n * 100] 19 | end 20 | 21 | GC.start 22 | sleep 5 23 | 24 | def measure_memory(title) 25 | puts "Running test: #{title}" 26 | recorder = ProcessMemory.start_recording 27 | yield 28 | puts recorder.print("Done!") 29 | recorder.stop 30 | puts recorder.report_per_second_pretty 31 | puts 32 | end 33 | 34 | measure_memory("FastExcel") do 35 | write_fast_excel_20k 36 | end 37 | 38 | GC.start 39 | sleep 5 40 | 41 | measure_memory("Axlsx") do 42 | write_axlsx_20k 43 | end 44 | 45 | GC.start 46 | sleep 5 47 | 48 | measure_memory("write_xlsx") do 49 | write_xlsx_20k 50 | end 51 | 52 | GC.start 53 | sleep 5 54 | 55 | measure_memory("xlsxtream") do 56 | write_xlsxtream_20k 57 | end 58 | -------------------------------------------------------------------------------- /benchmarks/profiler.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | require 'ruby-prof' 3 | 4 | DATA = [] 5 | 1000.times do |n| 6 | DATA << [n, "String string #{n}", (n * rand * 10).round, Time.at(n * 1000 + 1492922688)] 7 | end 8 | 9 | RubyProf.start 10 | 11 | 100.times do 12 | workbook = FastExcel.open(constant_memory: true) 13 | worksheet = workbook.add_worksheet("benchmark") 14 | worksheet.auto_width = true 15 | 16 | DATA.each_with_index do |row, i| 17 | worksheet.write_row(i + 1, row) 18 | end 19 | workbook.read_string 20 | 21 | print '.' 22 | end 23 | result = RubyProf.stop 24 | 25 | # print a flat profile to text 26 | printer = RubyProf::FlatPrinter.new(result) 27 | printer.print(STDOUT) 28 | -------------------------------------------------------------------------------- /benchmarks/write_value.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | require "benchmark/memory" 3 | require "benchmark/ips" 4 | 5 | DATA = [] 6 | 1000.times do |n| 7 | DATA << [n, "String string #{n}", (n * rand * 10).round, Time.at(n * 1000 + 1492922688)] 8 | end 9 | 10 | 5.times do 11 | workbook = FastExcel.open(constant_memory: true) 12 | worksheet = workbook.add_worksheet("benchmark") 13 | 14 | DATA.each_with_index do |row, row_num| 15 | row.each_with_index do |val, cell_num| 16 | worksheet.write_value(row_num + 1, cell_num + 1, val) 17 | end 18 | end 19 | workbook.read_string 20 | end 21 | 22 | 23 | workbook = FastExcel.open(constant_memory: true) 24 | worksheet = workbook.add_worksheet("benchmark") 25 | 26 | DATA.each_with_index do |row, row_num| 27 | row.each_with_index do |val, cell_num| 28 | worksheet.write_value(row_num + 1, cell_num + 1, val) 29 | end 30 | end 31 | workbook.read_string 32 | 33 | Benchmark.ips do |x| 34 | #x.config(time: 10, warmup: 2) 35 | 36 | x.report("Normal") do 37 | workbook = FastExcel.open(constant_memory: true) 38 | worksheet = workbook.add_worksheet("benchmark") 39 | 40 | DATA.each_with_index do |row, row_num| 41 | row.each_with_index do |val, cell_num| 42 | worksheet.write_value(row_num + 1, cell_num + 1, val) 43 | end 44 | end 45 | workbook.read_string 46 | end 47 | 48 | x.report("Auto-width") do 49 | workbook = FastExcel.open(constant_memory: true) 50 | worksheet = workbook.add_worksheet("benchmark") 51 | worksheet.auto_width = true 52 | 53 | DATA.each_with_index do |row, row_num| 54 | row.each_with_index do |val, cell_num| 55 | worksheet.write_value(row_num + 1, cell_num + 1, val) 56 | end 57 | end 58 | workbook.read_string 59 | end 60 | 61 | x.compare! 62 | end 63 | -------------------------------------------------------------------------------- /examples/example.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example.xlsx", constant_memory: true) 4 | 5 | workbook.default_format.set( 6 | font_size: 0, # user's default 7 | #font_family: "Arial" 8 | ) 9 | 10 | # pp workbook.default_format 11 | 12 | worksheet = workbook.add_worksheet("Payments Report") 13 | 14 | bold = workbook.bold_format 15 | worksheet.set_column(0, 0, FastExcel::DEF_COL_WIDTH, bold) 16 | 17 | price = workbook.number_format("#,##0.00") 18 | worksheet.set_column(1, 1, 20, price) 19 | 20 | date_format = workbook.number_format("[$-409]m/d/yy h:mm AM/PM;@") 21 | worksheet.set_column(2, 2, 20, date_format) 22 | 23 | worksheet.write_row(0, ["message", "price", "date", "complete"], bold) 24 | 25 | worksheet.write_comment(2, 2, "Comment to field") 26 | 27 | for i in 1..1000 28 | worksheet.write_row(i, ["Hello", (rand * 10_000_000).round(2), Time.now, i % 2 == 0]) 29 | 30 | # Or manually 31 | # worksheet.write_string(i, 0, "Hello", nil) 32 | # worksheet.write_number(i, 1, (rand * 10_000_000).round(2), nil) 33 | # date = Libxlsxwriter::Datetime.new 34 | # date[:year] = 2017 35 | # date[:month] = 2 36 | # date[:day] = 24 37 | # date[:hour] = i % 24 38 | # date[:min] = i % 60 39 | # date[:sec] = i % 60 40 | # worksheet.write_datetime(i, 2, date, nil) 41 | end 42 | 43 | workbook.close 44 | puts "Saved to file example.xlsx" -------------------------------------------------------------------------------- /examples/example_align.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_align.xlsx", constant_memory: true) 4 | 5 | worksheet = workbook.add_worksheet 6 | 7 | row_format = workbook.add_format 8 | 9 | row_format.align = {h: :center, v: :center} 10 | # Can also be called as: 11 | # row_format.align = :align_center 12 | # row_format.align = :align_vertical_center 13 | 14 | print "Align set as: " 15 | p row_format.align # => {horizontal: :align_center, vertical: :align_vertical_center} 16 | 17 | worksheet.set_column_width(0, 30) 18 | worksheet.set_row(0, 30, row_format) 19 | 20 | worksheet.write_row(0, ["Hello"]) 21 | 22 | workbook.close 23 | puts "Saved to file example_align.xlsx" 24 | -------------------------------------------------------------------------------- /examples/example_auto_width.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_auto_width.xlsx", constant_memory: false) 4 | 5 | # this is required to make auto-width works correctly 6 | workbook.default_format.set( 7 | font_size: 13, 8 | font_family: "Arial" 9 | ) 10 | 11 | worksheet = workbook.add_worksheet 12 | worksheet.auto_width = true 13 | 14 | ['Arial', 'Calibri', 'Times New Roman'].each_with_index do |font, index| 15 | col_format = workbook.add_format(font_family: font, font_size: 17) 16 | worksheet.set_column(index * 4, index * 4 + 3, 10, col_format) 17 | 18 | worksheet.write_value(0, index * 4 + 2, font) 19 | worksheet.write_value(1, index * 4, "tini") 20 | worksheet.write_value(1, index * 4 + 1, "Longer") 21 | worksheet.write_value(1, index * 4 + 2, "Some longer text!") 22 | worksheet.write_value(1, index * 4 + 3, "This gem is FFI binding for libxlsxwriter C library") 23 | end 24 | 25 | workbook.close 26 | puts "Saved to file example_auto_width.xlsx" 27 | -------------------------------------------------------------------------------- /examples/example_chart.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_chart.xlsx", constant_memory: true) 4 | worksheet = workbook.add_worksheet 5 | 6 | for i in 0..5 7 | for n in 0..3 8 | worksheet.write_number(i, n, (i + 1) * (n + 1), nil) 9 | end 10 | end 11 | 12 | chart = workbook.add_chart(Libxlsxwriter::enum_type(:chart_type)[:column]) 13 | 14 | chart.add_series("Bob", "Sheet1!$A$1:$A$5") 15 | chart.add_series("Alice", "Sheet1!$B$1:$B$5") 16 | chart.add_series("Montgomery", "Sheet1!$C$1:$C$5") 17 | 18 | worksheet.insert_chart(1, 7, chart) 19 | 20 | workbook.close 21 | puts "Saved to file example_chart.xlsx" -------------------------------------------------------------------------------- /examples/example_colors.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_colors.xlsx", constant_memory: true) 4 | 5 | worksheet = workbook.add_worksheet 6 | 7 | color_format = workbook.add_format 8 | 9 | # We can use color names as string and symbols, color hex codes and color hex numbers 10 | 11 | color_format.set( 12 | font_color: '9900FF', 13 | bg_color: '#FFAAAA', 14 | 15 | border_bottom: :medium, 16 | border_bottom_color: 'green', 17 | 18 | border_left: :slant_dash_dot, 19 | border_left_color: 0x00FF00, 20 | 21 | border_right: :double, 22 | border_right_color: :crimson, 23 | 24 | border_top: :border_hair, 25 | border_top_color: :medium_blue 26 | ) 27 | 28 | # Possible border styles: 29 | # [:none, :thin, :medium, :dashed, :dotted, :thick, :double, :hair, :medium_dashed, 30 | # :dash_dot, :medium_dash_dot, :dash_dot_dot, :medium_dash_dot_dot, :slant_dash_dot] 31 | 32 | worksheet.set_column_width(1, 30) 33 | 34 | worksheet.write_value(1, 1, "Hello", color_format) 35 | 36 | workbook.close 37 | puts "Saved to file example_colors.xlsx" 38 | -------------------------------------------------------------------------------- /examples/example_date_time.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | require 'date' 4 | require 'time' 5 | 6 | 7 | File.unlink("example_date_time.xlsx") if File.exist?("example_date_time.xlsx") 8 | 9 | workbook = FastExcel.open("example_date_time.xlsx", constant_memory: true) 10 | workbook.default_format.set( 11 | font_size: 0, # user's default 12 | ) 13 | worksheet = workbook.add_worksheet 14 | 15 | worksheet.set_columns_width(0, 4, 25) 16 | worksheet.set_column(1, 1, 25, workbook.number_format("[$-409]m/d/yy hh:mm;@")) 17 | 18 | intro = "Date and time in excel file stored as decimal number, it show number of days since January 1900, decimal part is for time of the day" 19 | worksheet.merge_range(0, 0, 0, 4, intro, nil) 20 | worksheet.write_value(1, 0, "") 21 | 22 | worksheet.append_row(['', 'Formatted as Date', 'No formatting, plain number']) 23 | 24 | worksheet.append_row(["Time.now", Time.now, Time.now, 'local timezone']) 25 | worksheet.append_row(["Time.now.utc", Time.now.utc, Time.now.utc, 'UTC timezone']) 26 | 27 | worksheet.append_row(["DateTime.now", DateTime.now, DateTime.now, 'local timezone']) 28 | dt = DateTime.now.new_offset("+02:00") 29 | worksheet.append_row(["DateTime new_offset", dt, dt, 'GMT+2 timezone']) 30 | 31 | today = Date.today 32 | worksheet.append_row(["Date.today", today, today]) 33 | 34 | worksheet.append_row(["0 (just zero)", 0, 0, '00 January 1900']) 35 | 36 | 37 | workbook.close 38 | puts "Saved to file example_date_time.xlsx" 39 | -------------------------------------------------------------------------------- /examples/example_filters.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | `rm example_filters.xlsx` if File.exist?('example_filters.xlsx') 4 | workbook = FastExcel.open("example_filters.xlsx", constant_memory: false) 5 | 6 | workbook.default_format.set( 7 | font_size: 0, # user's default 8 | #font_family: "Arial" 9 | ) 10 | 11 | # pp workbook.default_format 12 | 13 | worksheet = workbook.add_worksheet("Payments Report") 14 | 15 | # p worksheet[:filter_on] 16 | # FastExcel.print_ffi_obj(worksheet) 17 | 18 | bold = workbook.bold_format 19 | worksheet.set_column(0, 0, FastExcel::DEF_COL_WIDTH, bold) 20 | 21 | price = workbook.number_format("#,##0.00") 22 | worksheet.set_column(1, 1, 20, price) 23 | 24 | date_format = workbook.number_format("[$-409]m/d/yy h:mm AM/PM;@") 25 | worksheet.set_column(2, 2, 20, date_format) 26 | 27 | worksheet.write_row(0, ["message", "price", "date", "complete"], bold) 28 | 29 | for i in 1..1000 30 | worksheet.write_row(i, ["Hello", (rand * 10_000_000).round(2), Time.now, i % 2 == 0]) 31 | end 32 | 33 | worksheet.enable_filters!(end_col: 3) 34 | 35 | workbook.close 36 | puts "Saved to file example_filters.xlsx" -------------------------------------------------------------------------------- /examples/example_formula.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_formula.xlsx", constant_memory: false) 4 | 5 | worksheet = workbook.add_worksheet 6 | 7 | worksheet.write_row(0, ["Item", "Weight"]) 8 | worksheet.write_row(1, ["Laptop", 1.37]) 9 | worksheet.write_row(2, ["Phone", 0.138]) 10 | worksheet.write_row(3, ["Mouse", 0.099]) 11 | worksheet.write_row(4, ["Speaker", 2.5]) 12 | worksheet.write_row(5, ["Camera", 0.383]) 13 | worksheet.write_row(6, ["Total", FastExcel::Formula.new("SUM(B2:B6)")], workbook.bold_format) 14 | 15 | workbook.close 16 | puts "Saved to file example_formula.xlsx" 17 | -------------------------------------------------------------------------------- /examples/example_hyperlink.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_hyperlink.xlsx", constant_memory: false) 4 | worksheet = workbook.add_worksheet 5 | worksheet.auto_width = true 6 | 7 | url_format = workbook.add_format(underline: :underline_single, font_color: :blue) 8 | 9 | worksheet.append_row([ 10 | "Ultra Fast Excel Writer for Ruby", 11 | FastExcel::URL.new("https://github.com/Paxa/fast_excel"), 12 | FastExcel::URL.new("postgres://localhost") 13 | ], [nil, url_format]) 14 | 15 | # Same as: 16 | # worksheet.write_value(0, 0, "Ultra Fast Excel Writer for Ruby") 17 | # worksheet.write_url(0, 1, "https://github.com/Paxa/fast_excel", url_format) 18 | 19 | workbook.close 20 | puts "Saved to file example_hyperlink.xlsx" 21 | -------------------------------------------------------------------------------- /examples/example_image.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_image.xlsx", constant_memory: false) 4 | worksheet = workbook.add_worksheet 5 | 6 | img_options = Libxlsxwriter::ImageOptions.new 7 | img_options[:x_offset] = 0 8 | img_options[:y_offset] = 0 9 | 10 | worksheet.insert_image_opt(3, 3, "examples/logo.png", img_options) 11 | 12 | workbook.close 13 | puts "Saved to file example_image.xlsx" -------------------------------------------------------------------------------- /examples/example_styles.rb: -------------------------------------------------------------------------------- 1 | require_relative '../lib/fast_excel' 2 | 3 | workbook = FastExcel.open("example_styles.xlsx", constant_memory: true) 4 | 5 | #workbook.default_format.set( 6 | # font_size: 0, # user's default 7 | # #font_family: "Arial" 8 | #) 9 | 10 | worksheet = workbook.add_worksheet 11 | 12 | worksheet.set_columns_width(0, 11, 11) 13 | 14 | worksheet.write_value(0, 0, "Bold", workbook.add_format(bold: true)) 15 | worksheet.write_value(0, 1, "Italic", workbook.add_format(italic: true)) 16 | worksheet.write_value(0, 2, "Underline", workbook.add_format(underline: :underline_single)) 17 | worksheet.write_value(0, 3, "Double line", workbook.add_format(underline: :underline_double)) 18 | worksheet.write_value(0, 4, "Indent", workbook.add_format(indent: 1)) 19 | worksheet.write_value(0, 5, "Border", workbook.add_format(border: :border_thin)) 20 | worksheet.write_value(0, 6, "Border2", workbook.add_format(border: :border_medium)) 21 | worksheet.write_value(0, 7, "Pattern", workbook.add_format(pattern: :pattern_light_up, bg_color: :yellow)) 22 | worksheet.write_value(0, 8, "Script", workbook.add_format(font_script: :font_subscript)) 23 | worksheet.write_value(0, 9, "Strike", workbook.add_format(font_strikeout: true)) 24 | worksheet.write_value(0, 10, "Shaddow", workbook.add_format(font_shadow: true)) 25 | 26 | workbook.close 27 | puts "Saved to file example_styles.xlsx" -------------------------------------------------------------------------------- /examples/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paxa/fast_excel/dc2b5e56e28a26e5f601fde98233a0241a4c4ebd/examples/logo.png -------------------------------------------------------------------------------- /ext/fast_excel/extconf.rb: -------------------------------------------------------------------------------- 1 | require 'mkmf' 2 | 3 | create_makefile('ext/text_width_ext') -------------------------------------------------------------------------------- /extconf.rb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paxa/fast_excel/dc2b5e56e28a26e5f601fde98233a0241a4c4ebd/extconf.rb -------------------------------------------------------------------------------- /fast_excel.gemspec: -------------------------------------------------------------------------------- 1 | Gem::Specification.new do |s| 2 | s.name = "fast_excel" 3 | s.version = "0.5.0" 4 | s.author = ["Pavel Evstigneev"] 5 | s.email = ["pavel.evst@gmail.com"] 6 | s.homepage = "https://github.com/paxa/fast_excel" 7 | s.summary = %q{Ultra Fast Excel Writer} 8 | s.description = "Wrapper for libxlsxwriter using ffi" 9 | s.license = 'MIT' 10 | s.required_ruby_version = ['>= 2.0'] 11 | 12 | s.files = `git ls-files`.split("\n") 13 | s.test_files = [] 14 | 15 | s.require_paths = ["lib"] 16 | s.extensions = ["extconf.rb"] 17 | 18 | s.add_runtime_dependency "ffi", ["> 1.17", "< 2"] 19 | s.add_runtime_dependency "base64", [">= 0.2", "< 2"] 20 | end 21 | -------------------------------------------------------------------------------- /letters.html: -------------------------------------------------------------------------------- 1 | 11 | 12 | 18 | 19 |
 20 |   
 21 | 
22 | 23 | 115 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: ["paypal.me/xlsxwriter"] 2 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # libxlsxwriter: Reporting Bugs 2 | 3 | Here are some tips on reporting bugs in `libxlsxwriter`. 4 | 5 | ### Upgrade to the latest version of the library 6 | 7 | Upgrade to the latest version of the library since the bug you are reporting 8 | may already be fixed. 9 | 10 | Check the [Changes][changes] section of the documentation to see what has 11 | changed in the latest versions. 12 | 13 | [changes]: http://libxlsxwriter.github.io/changes.html 14 | 15 | You can check which version of `libxlsxwriter` that you are using by checking 16 | the `xlsxwriter.h` header file or by adding the following to your program: 17 | 18 | ```C 19 | #include 20 | #include "xlsxwriter.h" 21 | 22 | int main() { 23 | 24 | printf("Libxlsxwriter version = %s\n", lxw_version()); 25 | 26 | return 0; 27 | } 28 | ``` 29 | 30 | ### Read the documentation 31 | 32 | Read or search the `libxlsxwriter` [documentation][docs] to see if the issue 33 | you are encountering is already explained. 34 | 35 | [docs]: http://libxlsxwriter.github.io/index.html 36 | 37 | ### Look at the example programs 38 | 39 | There are many [examples programs][examples] in the distribution. Try to 40 | identify an example program that corresponds to your query and adapt it to use 41 | as a bug report. 42 | 43 | [examples]: http://libxlsxwriter.github.io/examples.html 44 | 45 | 46 | ### Tips for submitting a bug report 47 | 48 | 1. Describe the problem as clearly and as concisely as possible. 49 | 2. Include a sample program. This is probably the most important step. 50 | It is generally easier to describe a problem in code than in written 51 | prose. 52 | 3. The sample program should be as small as possible to demonstrate the 53 | problem. Don't copy and paste large non-relevant sections of your 54 | program. 55 | 56 | A sample bug report is shown below. This format helps analyze and respond to 57 | the bug report more quickly. 58 | 59 | 60 | > Subject: Issue with SOMETHING 61 | > 62 | > Greetings, 63 | > 64 | > I am using libxlsxwriter to do SOMETHING but it appears to do SOMETHING ELSE. 65 | > 66 | > I am using CC version X.Y.Z, OS = uname and libxlsxwriter x.y.z. 67 | > 68 | > Here is some code that demonstrates the problem: 69 | > 70 | > 71 | >```C 72 | >#include "xlsxwriter.h" 73 | > 74 | >int main() { 75 | > 76 | > lxw_workbook *workbook = workbook_new("bug_report.xlsx"); 77 | > lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); 78 | > 79 | > worksheet_write_string(worksheet, 0, 0, "Hello", NULL); 80 | > worksheet_write_number(worksheet, 1, 0, 123, NULL); 81 | > 82 | > return workbook_close(workbook); 83 | >} 84 | >``` 85 | > 86 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # libxlsxwriter: Submitting Pull Requests 2 | 3 | # Pull Requests and Contributing to Libxlsxwriter 4 | 5 | All patches and pull requests are welcome but in general you should start with 6 | an issue tracker to describe what you intend to do before you do it. 7 | 8 | 9 | ### Getting Started 10 | 11 | 1. Pull requests and new feature proposals must start with an [issue 12 | tracker][issues]. This serves as the focal point for the design discussion. 13 | 2. Describe what you plan to do. If there are API changes add some code 14 | example to demonstrate them. 15 | 3. Fork the repository. 16 | 4. Run all the tests to make sure the current code works on your system using 17 | `make test`. See the [Running the Test Suite][tests] section of the docs 18 | for instructions. 19 | 5. Create a feature branch for your new feature. 20 | 21 | 22 | [tests]: http://libxlsxwriter.github.io/running_the_tests.html 23 | 24 | ### Code Style 25 | 26 | The code style is mainly K&R style with 4 space indents. 27 | 28 | The author uses GNU indent (`gindent`) 2.2.10 with the following options: 29 | 30 | ``` 31 | --braces-on-if-line 32 | --braces-on-struct-decl-line 33 | --case-indentation 4 34 | --continue-at-parentheses 35 | --declaration-comment-column 0 36 | --format-first-column-comments 37 | --honour-newlines 38 | --ignore-profile 39 | --indent-label 0 40 | --indent-level 4 41 | --no-space-after-function-call-names 42 | --no-tabs 43 | --swallow-optional-blank-lines 44 | ``` 45 | 46 | The [indent configuration file][indentpro] is available in the repo. The code 47 | can be indented automatically if the same version of `gindent` is used with 48 | the following make command: 49 | 50 | ```shell 51 | make indent 52 | ``` 53 | 54 | Note, make sure you have backed up your files or added them to the index 55 | before running this command. 56 | 57 | In general follow the existing style in the code. 58 | 59 | [indentpro]: https://github.com/jmcnamara/libxlsxwriter/blob/master/.indent.pro 60 | 61 | ### Writing and Running Tests 62 | 63 | Any significant features should be accompanied by a test. See the `test` 64 | directory and the [Running the Test Suite][tests] section of the docs for 65 | details of the test setup. 66 | 67 | The tests can be run as follows: 68 | 69 | ```shell 70 | make test 71 | ``` 72 | Same as: 73 | 74 | ```shell 75 | make test_unit 76 | make test_functional 77 | ``` 78 | 79 | The functional tests require the Python module [pytest][pytest] as a test runner. 80 | 81 | If you have `valgrind` installed you can use the test suite to check for memory leaks: 82 | 83 | ```shell 84 | make test_valgrind 85 | ``` 86 | 87 | When you push your changes they will also be tested automatically using 88 | [GitHub Actions][actions]. 89 | 90 | [actions]: https://github.com/jmcnamara/libxlsxwriter/actions 91 | [pytest]: http://pytest.org/ 92 | 93 | 94 | ### Documentation 95 | 96 | The `libxlsxwriter` documentation is written in Doxygen format in the header 97 | files and in additional `.dox` files in the `docs/src` directory of the 98 | repo. The documentation can be built as follows: 99 | 100 | ```shell 101 | make docs 102 | open docs/html/index.html 103 | ``` 104 | 105 | 106 | ### Example programs 107 | 108 | If applicable add an example program to the `examples` directory. Example 109 | files can be built using: 110 | 111 | ```shell 112 | make docs 113 | ``` 114 | 115 | ### Copyright and License 116 | 117 | Copyright remains with the original author. Do not include additional 118 | copyright claims or Licensing requirements. GitHub and the `git` repository 119 | will record your contribution and it will be acknowledged it in the Changes 120 | file. 121 | 122 | 123 | ### Submitting the Pull Request 124 | 125 | If your change involves several incremental `git` commits then `rebase` or 126 | `squash` them onto another branch so that the Pull Request is a single commit 127 | or a small number of logical commits. 128 | 129 | Push your changes to GitHub and submit the Pull Request with a hash link to 130 | the to the Issue tracker that was opened above. 131 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/workflows/cmake_actions.yml: -------------------------------------------------------------------------------- 1 | name: Test CMake build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: 8 | Cmake 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | cc: [gcc, clang] 13 | cmake_flags: ["", 14 | "-DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON", 15 | "-DUSE_DTOA_LIBRARY=ON -DBUILD_TESTS=ON", 16 | "-DUSE_MEM_FILE=ON -DBUILD_TESTS=ON", 17 | "-DUSE_NO_MD5=ON -DBUILD_TESTS=ON", 18 | "-DUSE_OPENSSL_MD5=ON -DBUILD_TESTS=ON", 19 | "-DUSE_STANDARD_TMPFILE=ON -DBUILD_TESTS=ON", 20 | "-DUSE_SYSTEM_MINIZIP=ON -DBUILD_TESTS=ON", 21 | "-DUSE_SYSTEM_MINIZIP=ON -DUSE_OPENSSL_MD5=ON -DBUILD_TESTS=ON"] 22 | runs-on: ubuntu-latest 23 | env: 24 | CC: ${{ matrix.cc }} 25 | 26 | steps: 27 | - uses: actions/checkout@v2 28 | 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install pytest 33 | sudo apt update 34 | sudo apt-get -y install zlib1g-dev 35 | sudo apt-get -y install libminizip-dev 36 | sudo apt-get -y install libssl-dev 37 | 38 | - name: Configure CMake 39 | working-directory: ${{ github.workspace }}/cmake 40 | run: cmake .. -DBUILD_TESTS=ON ${{ matrix.cmake_flags }} -DCMAKE_BUILD_TYPE=Release 41 | 42 | - name: Build 43 | working-directory: ${{ github.workspace }}/cmake 44 | run: cmake --build . --config Release --parallel 45 | 46 | - name: Test 47 | working-directory: ${{ github.workspace }}/cmake 48 | run: ctest -C Release -V 49 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/workflows/code_style.yml: -------------------------------------------------------------------------------- 1 | name: Check code style 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: 8 | Check code style 9 | 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - uses: actions/checkout@v2 14 | 15 | - name: Install dependencies 16 | run: | 17 | sudo apt-get -y install indent 18 | sudo ln -s /usr/bin/indent /usr/bin/gindent 19 | 20 | - name: Make indent 21 | run: | 22 | make indent 23 | git status | grep 'nothing to commit' 24 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/workflows/coverity.yml: -------------------------------------------------------------------------------- 1 | name: Coverity Scan 2 | 3 | on: 4 | push: 5 | branches: [coverity] 6 | 7 | jobs: 8 | coverity: 9 | runs-on: ubuntu-latest 10 | steps: 11 | 12 | - uses: actions/checkout@v2 13 | 14 | - name: Build third party libs to exclude them from scan 15 | run: make third_party 16 | 17 | - uses: vapier/coverity-scan-action@v1 18 | with: 19 | project: libxlsxwriter 20 | email: ${{ secrets.COVERITY_SCAN_EMAIL }} 21 | token: ${{ secrets.COVERITY_SCAN_TOKEN }} 22 | command: make -C src libxlsxwriter.a 23 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/workflows/make_actions.yml: -------------------------------------------------------------------------------- 1 | name: Test Make build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: 8 | Make 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | cc: [gcc, clang] 13 | make_flags: ["", 14 | "USE_STANDARD_TMPFILE=1", 15 | "USE_SYSTEM_MINIZIP=1", 16 | "USE_DTOA_LIBRARY=1", 17 | "USE_NO_MD5=1", 18 | "USE_OPENSSL_MD5=1", 19 | "USE_MEM_FILE=1"] 20 | runs-on: ubuntu-latest 21 | env: 22 | CC: ${{ matrix.cc }} 23 | CXX: ${{ matrix.cc }} 24 | CFLAGS: '-Werror' 25 | 26 | steps: 27 | - uses: actions/checkout@v2 28 | 29 | - name: Install dependencies 30 | run: | 31 | python -m pip install --upgrade pip 32 | pip install pytest 33 | sudo apt update 34 | sudo apt-get -y install zlib1g-dev 35 | sudo apt-get -y install libminizip-dev 36 | sudo apt-get -y install libssl-dev 37 | sudo apt-get -y install valgrind 38 | 39 | - name: make 40 | run: ${{ matrix.make_flags }} make V=1 41 | 42 | - name: test unit 43 | run: ${{ matrix.make_flags }} make test_unit V=1 44 | 45 | - name: test functional 46 | run: ${{ matrix.make_flags }} make test_functional V=1 -j 47 | 48 | - name: test cpp 49 | run: ${{ matrix.make_flags }} make test_cpp V=1 50 | 51 | - name: test examples 52 | run: ${{ matrix.make_flags }} make examples V=1 53 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/workflows/valgrind.yml: -------------------------------------------------------------------------------- 1 | name: Test for memory leaks 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: 8 | Valgrind 9 | runs-on: ubuntu-latest 10 | env: 11 | CC: gcc 12 | 13 | steps: 14 | - uses: actions/checkout@v2 15 | 16 | - name: Install dependencies 17 | run: | 18 | sudo apt update 19 | sudo apt-get -y install valgrind 20 | sudo apt-get -y install zlib1g-dev 21 | 22 | - name: test valgrind 23 | run: make test_valgrind V=1 -j 2 24 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/workflows/windows_build.yml: -------------------------------------------------------------------------------- 1 | name: Test Cmake build on Windows 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | name: CMake on Windows 8 | 9 | strategy: 10 | fail-fast: false 11 | matrix: 12 | cmake_flags: ["-DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON", 13 | "-DUSE_DTOA_LIBRARY=ON -DBUILD_TESTS=ON", 14 | #"-DUSE_SYSTEM_MINIZIP=ON -DBUILD_TESTS=ON", 15 | #"-DUSE_SYSTEM_MINIZIP=ON -DUSE_OPENSSL_MD5=ON -DBUILD_TESTS=ON", 16 | "-DUSE_OPENSSL_MD5=ON -DBUILD_TESTS=ON", 17 | ] 18 | 19 | runs-on: windows-latest 20 | 21 | steps: 22 | - uses: actions/checkout@v2 23 | 24 | - name: Install dependencies 25 | working-directory: ${{env.GITHUB_WORKSPACE}} 26 | shell: cmd 27 | run: | 28 | vcpkg.exe install zlib:x64-windows minizip:x64-windows openssl:x64-windows 29 | vcpkg.exe integrate install 30 | pip install pytest 31 | 32 | - name: Configure CMake 33 | working-directory: ${{env.GITHUB_WORKSPACE}} 34 | shell: cmd 35 | run: | 36 | cd cmake 37 | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" 38 | cmake .. -DCMAKE_BUILD_TYPE=Release ${{ matrix.cmake_flags }} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -A x64 39 | 40 | - name: Build 41 | working-directory: ${{env.GITHUB_WORKSPACE}} 42 | shell: cmd 43 | run: | 44 | cd cmake 45 | call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvars64.bat" 46 | cmake --build . --config Release 47 | 48 | - name: Test 49 | working-directory: ${{env.GITHUB_WORKSPACE}} 50 | shell: cmd 51 | run: | 52 | cd cmake 53 | copy test\functional\src\Release\*.exe test\functional\src 54 | pytest -v test/functional 55 | -------------------------------------------------------------------------------- /libxlsxwriter/.github/workflows/zig_build.yml: -------------------------------------------------------------------------------- 1 | name: Zig Build 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | build: 7 | strategy: 8 | fail-fast: false 9 | matrix: 10 | runs-on: [ubuntu-latest, macos-latest, windows-latest] 11 | runs-on: ${{ matrix.runs-on }} 12 | steps: 13 | - uses: actions/checkout@v4 14 | with: 15 | submodules: recursive 16 | fetch-depth: 0 17 | - uses: goto-bus-stop/setup-zig@v2 18 | with: 19 | version: 0.11.0 20 | 21 | - name: Build Summary 22 | run: zig build -DBUILD_TESTS -DBUILD_EXAMPLES -DUSE_SYSTEM_MINIZIP --summary all -freference-trace 23 | -------------------------------------------------------------------------------- /libxlsxwriter/.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.o 3 | *.so 4 | *.so.* 5 | *.to 6 | *.lo 7 | *.la 8 | *.dylib 9 | *.dll 10 | *.gcno 11 | *.gcda 12 | test_* 13 | !test_*.c 14 | !test_*.cpp 15 | !test_*.py 16 | *.tar.gz 17 | *~ 18 | TAGS 19 | .#* 20 | *# 21 | ~*xlsx 22 | *.xlsx 23 | *.bak 24 | !test/functional/xlsx_files/*.xlsx 25 | *.pyc 26 | .pytest_cache/ 27 | .cproject 28 | .project 29 | .pydevproject 30 | .settings/ 31 | .DS_Store 32 | __pycache__ 33 | .cache 34 | docs/html 35 | docs/latex 36 | .deps 37 | .dirstamp 38 | _temp.c 39 | examples/* 40 | !examples/*.c 41 | !examples/*.png 42 | !examples/Makefile 43 | !examples/vbaProject.bin 44 | cov-int 45 | libxlsxwriter-coverity.tgz 46 | build 47 | 48 | third_party/zlib-1.2.8/configure.log 49 | third_party/zlib-1.2.8/contrib/minizip/miniunz 50 | third_party/zlib-1.2.8/contrib/minizip/minizip 51 | third_party/zlib-1.2.8/example 52 | third_party/zlib-1.2.8/examplesh 53 | third_party/zlib-1.2.8/minigzip 54 | third_party/zlib-1.2.8/minigzipsh 55 | third_party/zlib-1.2.8/zlib.pc 56 | 57 | cmake 58 | !cmake/FindMINIZIP.cmake 59 | !cmake/FindPackage.cmake 60 | !cmake/i686-toolchain.cmake 61 | 62 | .vscode 63 | 64 | zig-cache/ 65 | zig-out/ -------------------------------------------------------------------------------- /libxlsxwriter/.indent.pro: -------------------------------------------------------------------------------- 1 | /* 2 | * Indent rules for libxlsxwriter. 3 | * 4 | * The rules for user defined typedefs can be update as follows: 5 | * 6 | perl -i -pe 'print and last if /[l]ibxlsxwriter typedefs/' .indent.pro 7 | ack -h typedef include/xlsxwriter/*.h src/*.c | perl -lne 'print "-T $1" if /\w+\s+\w+\s+(\w+)/' | sort >> .indent.pro 8 | * 9 | */ 10 | 11 | /* Command line options used with GNU indent 2.2.10 */ 12 | --braces-on-if-line 13 | --braces-on-struct-decl-line 14 | --case-indentation 4 15 | --continue-at-parentheses 16 | --declaration-comment-column 0 17 | --format-first-column-comments 18 | --honour-newlines 19 | --ignore-profile 20 | --indent-label 0 21 | --indent-level 4 22 | --no-space-after-function-call-names 23 | --no-tabs 24 | --swallow-optional-blank-lines 25 | 26 | /* Typedefs used in the code. */ 27 | -T int8_t 28 | -T int16_t 29 | -T int32_t 30 | -T int64_t 31 | -T uint8_t 32 | -T uint16_t 33 | -T uint32_t 34 | -T uint64_t 35 | -T ssize_t 36 | -T size_t 37 | -T time_t 38 | 39 | -T LIST_ENTRY 40 | -T RB_ENTRY 41 | -T SLIST_ENTRY 42 | -T STAILQ_ENTRY 43 | -T TAILQ_ENTRY 44 | 45 | /* libxlsxwriter typedefs. */ 46 | -T lxw_app 47 | -T lxw_author_id 48 | -T lxw_autofilter 49 | -T lxw_border 50 | -T lxw_button_options 51 | -T lxw_cell 52 | -T lxw_chart 53 | -T lxw_chart_axis 54 | -T lxw_chart_axis_display_unit 55 | -T lxw_chart_axis_label_alignment 56 | -T lxw_chart_axis_label_position 57 | -T lxw_chart_axis_tick_mark 58 | -T lxw_chart_axis_tick_position 59 | -T lxw_chart_axis_type 60 | -T lxw_chart_blank 61 | -T lxw_chart_custom_label 62 | -T lxw_chart_data_label 63 | -T lxw_chart_error_bar_axis 64 | -T lxw_chart_error_bar_cap 65 | -T lxw_chart_error_bar_direction 66 | -T lxw_chart_error_bar_type 67 | -T lxw_chart_fill 68 | -T lxw_chart_font 69 | -T lxw_chart_gridline 70 | -T lxw_chart_label_position 71 | -T lxw_chart_label_separator 72 | -T lxw_chart_legend 73 | -T lxw_chart_legend_position 74 | -T lxw_chart_line 75 | -T lxw_chart_line_dash_type 76 | -T lxw_chart_marker 77 | -T lxw_chart_marker_type 78 | -T lxw_chart_options 79 | -T lxw_chart_pattern 80 | -T lxw_chart_pattern_type 81 | -T lxw_chart_point 82 | -T lxw_chart_series 83 | -T lxw_chart_title 84 | -T lxw_chart_trendline_type 85 | -T lxw_chart_type 86 | -T lxw_chartsheet 87 | -T lxw_chartsheet_name 88 | -T lxw_col_options 89 | -T lxw_col_t 90 | -T lxw_color_t 91 | -T lxw_comment 92 | -T lxw_comment_options 93 | -T lxw_cond_format_hash_element 94 | -T lxw_cond_format_obj 95 | -T lxw_conditional_format 96 | -T lxw_content_types 97 | -T lxw_core 98 | -T lxw_custom 99 | -T lxw_custom_property 100 | -T lxw_data_val_obj 101 | -T lxw_data_validation 102 | -T lxw_datetime 103 | -T lxw_defined_name 104 | -T lxw_doc_properties 105 | -T lxw_drawing 106 | -T lxw_drawing_coords 107 | -T lxw_drawing_object 108 | -T lxw_drawing_rel_id 109 | -T lxw_error 110 | -T lxw_fill 111 | -T lxw_filter_rule 112 | -T lxw_filter_rule_obj 113 | -T lxw_font 114 | -T lxw_format 115 | -T lxw_hash_element 116 | -T lxw_hash_table 117 | -T lxw_header_footer_options 118 | -T lxw_heading_pair 119 | -T lxw_image_md5 120 | -T lxw_image_options 121 | -T lxw_merged_range 122 | -T lxw_metadata 123 | -T lxw_object_properties 124 | -T lxw_packager 125 | -T lxw_panes 126 | -T lxw_part_name 127 | -T lxw_print_area 128 | -T lxw_protection 129 | -T lxw_protection_obj 130 | -T lxw_rel_tuple 131 | -T lxw_relationships 132 | -T lxw_repeat_cols 133 | -T lxw_repeat_rows 134 | -T lxw_rich_string_tuple 135 | -T lxw_row 136 | -T lxw_row_col_options 137 | -T lxw_row_t 138 | -T lxw_selection 139 | -T lxw_series_data_point 140 | -T lxw_series_error_bars 141 | -T lxw_series_range 142 | -T lxw_sheet 143 | -T lxw_sst 144 | -T lxw_styles 145 | -T lxw_table 146 | -T lxw_table_column 147 | -T lxw_table_obj 148 | -T lxw_table_options 149 | -T lxw_theme 150 | -T lxw_tuple 151 | -T lxw_vml 152 | -T lxw_vml_obj 153 | -T lxw_workbook 154 | -T lxw_workbook_options 155 | -T lxw_worksheet 156 | -T lxw_worksheet_init_data 157 | -T lxw_worksheet_name 158 | -------------------------------------------------------------------------------- /libxlsxwriter/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # libxlsxwriter: Reporting Bugs and submitting Pull Requests 2 | 3 | 4 | ## Reporting Bugs 5 | 6 | Here are some tips on reporting bugs in `libxlsxwriter`. 7 | 8 | ### Upgrade to the latest version of the library 9 | 10 | Upgrade to the latest version of the library since the bug you are reporting 11 | may already be fixed. 12 | 13 | Check the [Changes][changes] section of the documentation to see what has 14 | changed in the latest versions. 15 | 16 | [changes]: http://libxlsxwriter.github.io/changes.html 17 | 18 | You can check which version of `libxlsxwriter` that you are using by checking 19 | the `xlsxwriter.h` header file or by adding the following to your program: 20 | 21 | ```C 22 | #include 23 | #include "xlsxwriter.h" 24 | 25 | int main() { 26 | 27 | printf("Libxlsxwriter version = %s\n", lxw_version()); 28 | 29 | return 0; 30 | } 31 | ``` 32 | 33 | 34 | ### Read the documentation 35 | 36 | Read or search the `libxlsxwriter` [documentation][docs] to see if the issue 37 | you are encountering is already explained. 38 | 39 | [docs]: http://libxlsxwriter.github.io/index.html 40 | 41 | ### Look at the example programs 42 | 43 | There are many [examples programs][examples] in the distribution. Try to 44 | identify an example program that corresponds to your query and adapt it to use 45 | as a bug report. 46 | 47 | [examples]: http://libxlsxwriter.github.io/examples.html 48 | 49 | 50 | ### Use the xlsxwriter Issue Tracker 51 | 52 | The [libxlsxwriter issue tracker][issues] is on GitHub. 53 | 54 | [issues]: https://github.com/jmcnamara/libxlsxwriter/issues 55 | 56 | 57 | ### Tips for submitting a bug report 58 | 59 | 1. Describe the problem as clearly and as concisely as possible. 60 | 2. Include a sample program. This is probably the most important step. 61 | It is generally easier to describe a problem in code than in written 62 | prose. 63 | 3. The sample program should be as small as possible to demonstrate the 64 | problem. Don't copy and paste large non-relevant sections of your 65 | program. 66 | 67 | A sample bug report is shown below. This format helps analyze and respond to 68 | the bug report more quickly. 69 | 70 | 71 | > Subject: Issue with SOMETHING 72 | > 73 | > Greetings, 74 | > 75 | > I am using libxlsxwriter to do SOMETHING but it appears to do SOMETHING ELSE. 76 | > 77 | > I am using CC version X.Y.Z, OS = uname and libxlsxwriter x.y.z. 78 | > 79 | > Here is some code that demonstrates the problem: 80 | > 81 | > 82 | >```C 83 | >#include "xlsxwriter.h" 84 | > 85 | >int main() { 86 | > 87 | > lxw_workbook *workbook = workbook_new("bug_report.xlsx"); 88 | > lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); 89 | > 90 | > worksheet_write_string(worksheet, 0, 0, "Hello", NULL); 91 | > worksheet_write_number(worksheet, 1, 0, 123, NULL); 92 | > 93 | > return workbook_close(workbook); 94 | >} 95 | >``` 96 | > 97 | 98 | 99 | # Pull Requests and Contributing to Libxlsxwriter 100 | 101 | All patches and pull requests are welcome but in general you should start with 102 | an issue tracker to describe what you intend to do before you do it. 103 | 104 | 105 | ### Getting Started 106 | 107 | 1. Pull requests and new feature proposals must start with an [issue 108 | tracker][issues]. This serves as the focal point for the design discussion. 109 | 2. Describe what you plan to do. If there are API changes add some code 110 | example to demonstrate them. 111 | 3. Fork the repository. 112 | 4. Run all the tests to make sure the current code works on your system using 113 | `make test`. See the [Running the Test Suite][tests] section of the docs 114 | for instructions. 115 | 5. Create a feature branch for your new feature. 116 | 117 | 118 | [tests]: http://libxlsxwriter.github.io/running_the_tests.html 119 | 120 | ### Code Style 121 | 122 | The code style is mainly K&R style with 4 space indents. 123 | 124 | The author uses GNU indent (`gindent`) 2.2.10 with the following options: 125 | 126 | ``` 127 | --braces-on-if-line 128 | --braces-on-struct-decl-line 129 | --case-indentation 4 130 | --continue-at-parentheses 131 | --declaration-comment-column 0 132 | --format-first-column-comments 133 | --honour-newlines 134 | --ignore-profile 135 | --indent-label 0 136 | --indent-level 4 137 | --no-space-after-function-call-names 138 | --no-tabs 139 | --swallow-optional-blank-lines 140 | ``` 141 | 142 | The [indent configuration file][indentpro] is available in the repo. The code 143 | can be indented automatically if the same version of `gindent` is used with 144 | the following make command: 145 | 146 | ```shell 147 | make indent 148 | ``` 149 | 150 | Note, make sure you have backed up your files or added them to the index 151 | before running this command. 152 | 153 | In general follow the existing style in the code. 154 | 155 | [indentpro]: https://github.com/jmcnamara/libxlsxwriter/blob/master/.indent.pro 156 | 157 | ### Writing and Running Tests 158 | 159 | Any significant features should be accompanied by a test. See the `test` 160 | directory and the [Running the Test Suite][tests] section of the docs for 161 | details of the test setup. 162 | 163 | The tests can be run as follows: 164 | 165 | ```shell 166 | make test 167 | ``` 168 | Same as: 169 | 170 | ```shell 171 | make test_unit 172 | make test_functional 173 | ``` 174 | 175 | The functional tests require the Python module [pytest][pytest] as a test runner. 176 | 177 | If you have `valgrind` installed you can use the test suite to check for memory leaks: 178 | 179 | ```shell 180 | make test_valgrind 181 | ``` 182 | 183 | When you push your changes they will also be tested automatically using 184 | [GitHub Actions][actions]. 185 | 186 | [actions]: https://github.com/jmcnamara/libxlsxwriter/actions 187 | [pytest]: http://pytest.org/ 188 | 189 | 190 | ### Documentation 191 | 192 | The `libxlsxwriter` documentation is written in Doxygen format in the header 193 | files and in additional `.dox` files in the `docs/src` directory of the 194 | repo. The documentation can be built as follows: 195 | 196 | ```shell 197 | make docs 198 | open docs/html/index.html 199 | ``` 200 | 201 | 202 | ### Example programs 203 | 204 | If applicable add an example program to the `examples` directory. Example 205 | files can be built using: 206 | 207 | ```shell 208 | make docs 209 | ``` 210 | 211 | ### Copyright and License 212 | 213 | Copyright remains with the original author. Do not include additional 214 | copyright claims or Licensing requirements. GitHub and the `git` repository 215 | will record your contribution and it will be acknowledged it in the Changes 216 | file. 217 | 218 | 219 | ### Submitting the Pull Request 220 | 221 | If your change involves several incremental `git` commits then `rebase` or 222 | `squash` them onto another branch so that the Pull Request is a single commit 223 | or a small number of logical commits. 224 | 225 | Push your changes to GitHub and submit the Pull Request with a hash link to 226 | the to the Issue tracker that was opened above. 227 | -------------------------------------------------------------------------------- /libxlsxwriter/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 5.7 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | 4 | import PackageDescription 5 | 6 | let package = Package( 7 | name: "libxlsxwriter", 8 | products: [ 9 | .library( 10 | name: "libxlsxwriter", 11 | targets: ["libxlsxwriter"]), 12 | ], 13 | targets: [ 14 | .target( 15 | name: "libxlsxwriter", 16 | path: ".", 17 | exclude: [ 18 | "src/Makefile", 19 | ], 20 | sources: [ 21 | "include", 22 | "src", 23 | "third_party/minizip/zip.c", 24 | "third_party/minizip/ioapi.c", 25 | "third_party/tmpfileplus/tmpfileplus.c", 26 | "third_party/md5/md5.c" 27 | ], 28 | publicHeadersPath: "include", 29 | linkerSettings: [ 30 | .linkedLibrary("z") 31 | ]), 32 | .testTarget( 33 | name: "libxlsxwritertests", 34 | dependencies: ["libxlsxwriter"], 35 | path: ".", 36 | sources: ["test/swift"], 37 | linkerSettings: [ 38 | .linkedLibrary("z") 39 | ] 40 | ) 41 | ] 42 | ) 43 | -------------------------------------------------------------------------------- /libxlsxwriter/Readme.md: -------------------------------------------------------------------------------- 1 | # libxlsxwriter 2 | 3 | 4 | Libxlsxwriter: A C library for creating Excel XLSX files. 5 | 6 | 7 | ![demo image](http://libxlsxwriter.github.io/demo.png) 8 | 9 | 10 | ## The libxlsxwriter library 11 | 12 | Libxlsxwriter is a C library that can be used to write text, numbers, formulas 13 | and hyperlinks to multiple worksheets in an Excel 2007+ XLSX file. 14 | 15 | It supports features such as: 16 | 17 | - 100% compatible Excel XLSX files. 18 | - Full Excel formatting. 19 | - Merged cells. 20 | - Defined names. 21 | - Autofilters. 22 | - Charts. 23 | - Data validation and drop down lists. 24 | - Conditional formatting. 25 | - Worksheet PNG/JPEG/GIF images. 26 | - Cell comments. 27 | - Support for adding Macros. 28 | - Memory optimization mode for writing large files. 29 | - Source code available on [GitHub](https://github.com/jmcnamara/libxlsxwriter). 30 | - FreeBSD license. 31 | - ANSI C. 32 | - Works with GCC, Clang, Xcode, MSVC 2015, ICC, TCC, MinGW, MingGW-w64/32. 33 | - Works on Linux, FreeBSD, OpenBSD, OS X, iOS and Windows. Also works on MSYS/MSYS2 and Cygwin. 34 | - Compiles for 32 and 64 bit. 35 | - Compiles and works on big and little endian systems. 36 | - The only dependency is on `zlib`. 37 | 38 | Here is an example that was used to create the spreadsheet shown above: 39 | 40 | 41 | ```C 42 | #include "xlsxwriter.h" 43 | 44 | int main() { 45 | 46 | /* Create a new workbook and add a worksheet. */ 47 | lxw_workbook *workbook = workbook_new("demo.xlsx"); 48 | lxw_worksheet *worksheet = workbook_add_worksheet(workbook, NULL); 49 | 50 | /* Add a format. */ 51 | lxw_format *format = workbook_add_format(workbook); 52 | 53 | /* Set the bold property for the format */ 54 | format_set_bold(format); 55 | 56 | /* Change the column width for clarity. */ 57 | worksheet_set_column(worksheet, 0, 0, 20, NULL); 58 | 59 | /* Write some simple text. */ 60 | worksheet_write_string(worksheet, 0, 0, "Hello", NULL); 61 | 62 | /* Text with formatting. */ 63 | worksheet_write_string(worksheet, 1, 0, "World", format); 64 | 65 | /* Write some numbers. */ 66 | worksheet_write_number(worksheet, 2, 0, 123, NULL); 67 | worksheet_write_number(worksheet, 3, 0, 123.456, NULL); 68 | 69 | /* Insert an image. */ 70 | worksheet_insert_image(worksheet, 1, 2, "logo.png"); 71 | 72 | workbook_close(workbook); 73 | 74 | return 0; 75 | } 76 | 77 | ``` 78 | 79 | 80 | See the [full documentation](http://libxlsxwriter.github.io) for the getting 81 | started guide, a tutorial, the main API documentation and examples. 82 | 83 | -------------------------------------------------------------------------------- /libxlsxwriter/build.zig.zon: -------------------------------------------------------------------------------- 1 | .{ 2 | .name = "libxlsxwriter", 3 | .version = "1.1.6", 4 | .dependencies = .{ 5 | .zlib = .{ 6 | .url = "https://github.com/kassane/zlib/archive/4a99cc2bfa344c969f086fcb8c5873d80448f3e6.tar.gz", 7 | .hash = "12209e851f7e2c6ba2f01de3e11b1771f03e49666065320abd8414aac152bfa75fae", 8 | }, 9 | }, 10 | } 11 | //syntax tip: zig - anon struct (json-like) 12 | -------------------------------------------------------------------------------- /libxlsxwriter/cmake/FindMINIZIP.cmake: -------------------------------------------------------------------------------- 1 | # :copyright: (c) 2017 Alex Huszagh. 2 | # :license: FreeBSD, see LICENSE.txt for more details. 3 | 4 | # FindMINIZIP 5 | # ----------- 6 | # 7 | # Find MINIZIP include dirs and libraries 8 | # 9 | # Use this module by invoking find_package with the form:: 10 | # 11 | # find_package(MINIZIP 12 | # [version] [EXACT] # Minimum or EXACT version e.g. 1.0.6 13 | # [REQUIRED] # Fail with error if MINIZIP is not found 14 | # ) 15 | # 16 | # You may also set `MINIZIP_USE_STATIC_LIBS` to prefer static libraries 17 | # to shared ones. 18 | # 19 | # If found, `MINIZIP_FOUND` will be set to true, and `MINIZIP_LIBRARIES` 20 | # and `MINIZIP_INCLUDE_DIRS` will both be set. 21 | # 22 | # You may optionally set `MINIZIP_ROOT` to specify a custom root directory 23 | # for the MINIZIP installation. 24 | # 25 | 26 | include(CheckCXXSourceCompiles) 27 | include(FindPackage) 28 | 29 | # PATHS 30 | # ----- 31 | 32 | set(MINIZIP_SEARCH_PATHS) 33 | 34 | if(MINIZIP_ROOT) 35 | list(APPEND MINIZIP_SEARCH_PATHS ${MINIZIP_ROOT}) 36 | endif() 37 | 38 | if(WIN32) 39 | list(APPEND ZLIB_SEARCH_PATHS 40 | "$ENV{PROGRAMFILES}/minizip" 41 | ) 42 | endif() 43 | 44 | unset(MINIZIP_SYSTEM_ROOT) 45 | unset(MINIZIP_CUSTOM_ROOT) 46 | unset(MINIZIP_SEARCH_HKEY) 47 | 48 | # FIND 49 | # ---- 50 | 51 | # INCLUDE DIRECTORY 52 | SetSuffixes(MINIZIP) 53 | foreach(search ${MINIZIP_SEARCH_PATHS}) 54 | FIND_PATH(MINIZIP_INCLUDE_DIR 55 | NAMES minizip/zip.h 56 | PATHS ${search} 57 | PATH_SUFFIXES include 58 | ) 59 | endforeach(search) 60 | 61 | if(NOT MINIZIP_INCLUDE_DIR) 62 | FIND_PATH(MINIZIP_INCLUDE_DIR minizip/zip.h PATH_SUFFIXES include) 63 | endif() 64 | 65 | # LIBRARY PATHS 66 | set(MINIZIP_LIBRARY_NAMES minizip) 67 | if(CMAKE_BUILD_TYPE MATCHES Debug) 68 | list(APPEND MINIZIP_LIBRARY_NAMES minizipd) 69 | endif() 70 | 71 | foreach(search ${MINIZIP_SEARCH_PATHS}) 72 | FIND_LIBRARY(MINIZIP_LIBRARY 73 | NAMES ${MINIZIP_LIBRARY_NAMES} 74 | PATHS ${search} 75 | PATH_SUFFIXES lib 76 | ) 77 | endforeach(search) 78 | 79 | if(NOT MINIZIP_LIBRARY) 80 | FIND_LIBRARY(MINIZIP_LIBRARY NAMES ${MINIZIP_LIBRARY_NAMES} PATH_SUFFIXES lib) 81 | endif() 82 | 83 | set(MINIZIP_INCLUDE_DIRS ${MINIZIP_INCLUDE_DIR}) 84 | set(MINIZIP_LIBRARIES ${MINIZIP_LIBRARY}) 85 | 86 | CheckFound(MINIZIP) 87 | FindStaticLibs(MINIZIP) 88 | 89 | # VERSION 90 | # ------- 91 | 92 | if(MINIZIP_FOUND) 93 | file(STRINGS "${MINIZIP_INCLUDE_DIRS}/zlib.h" MINIZIP_VERSION_CONTENTS REGEX "version [0-9]+\\.[0-9]+(\\.[0-9]+)?") 94 | string(REGEX REPLACE ".*version ([0-9]+)\\.[0-9]+" "\\1" MINIZIP_VERSION_MAJOR "${MINIZIP_VERSION_CONTENTS}") 95 | string(REGEX REPLACE ".*version [0-9]+\\.([0-9]+)" "\\1" MINIZIP_VERSION_MINOR "${MINIZIP_VERSION_CONTENTS}") 96 | set(MINIZIP_VERSION_PATCH 0) 97 | 98 | set(MINIZIP_VERSION_STRING "${MINIZIP_VERSION_MAJOR}.${MINIZIP_VERSION_MINOR}.${MINIZIP_VERSION_PATCH}") 99 | set(MINIZIP_VERSION ${MINIZIP_VERSION_STRING}) 100 | 101 | MatchVersion(MINIZIP) 102 | endif() 103 | 104 | # COMPILATION 105 | # ----------- 106 | 107 | set(MINIZIP_CODE " 108 | #include 109 | int main(void) 110 | { 111 | zip_fileinfo zipfile_info; 112 | 113 | return 0; 114 | } 115 | " 116 | ) 117 | 118 | if(MINIZIP_FOUND) 119 | CheckCompiles(MINIZIP) 120 | endif() 121 | RequiredPackageFound(MINIZIP) 122 | -------------------------------------------------------------------------------- /libxlsxwriter/cmake/FindPackage.cmake: -------------------------------------------------------------------------------- 1 | # :copyright: (c) 2017 Alex Huszagh. 2 | # :license: FreeBSD, see LICENSE.txt for more details. 3 | 4 | # FindPackage 5 | # ----------- 6 | # 7 | # Macros and functions to help find packages. Do not invoke this module 8 | # directly, it merely provides library definitions to be invoked 9 | # by other find utilities. 10 | 11 | include(CheckCXXSourceCompiles) 12 | 13 | 14 | # Return if the package name has previously been found 15 | # 16 | # Args: 17 | # packageName Name of the package 18 | # 19 | # Example: 20 | # ReturnFound(Iconv) 21 | # 22 | macro(ReturnFound packageName) 23 | if(${packageName}_FOUND) 24 | return() 25 | endif() 26 | endmacro(ReturnFound) 27 | 28 | 29 | # Set the library extensions for a given package dependent on whether 30 | # to search for static or dynamic libraries. 31 | # 32 | # Args: 33 | # packageName Name of the package 34 | # 35 | # Example: 36 | # SetSuffixes(IConv) 37 | # 38 | macro(SetSuffixes packageName) 39 | if(${packageName}_USE_STATIC_LIBS) 40 | if(MSVC) 41 | set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib") 42 | else() 43 | set(CMAKE_FIND_LIBRARY_SUFFIXES ".a") 44 | endif() 45 | else() 46 | if(WIN32) 47 | set(CMAKE_FIND_LIBRARY_SUFFIXES ".dll.a" ".dll" ".lib" ".a") 48 | else() 49 | set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a") 50 | endif() 51 | endif() 52 | endmacro(SetSuffixes) 53 | 54 | 55 | # Check if the package was found. 56 | # 57 | # Args: 58 | # packageName Name of the package 59 | # 60 | # Example: 61 | # CheckFound(IConv) 62 | # 63 | macro(CheckFound packageName) 64 | if(${packageName}_INCLUDE_DIRS AND ${packageName}_LIBRARIES) 65 | set(${packageName}_FOUND TRUE) 66 | endif() 67 | endmacro(CheckFound) 68 | 69 | 70 | # Replace a dynamic library with a `.dll.a` extension with the corresponding 71 | # library removing the `.dll`. 72 | # 73 | # Args: 74 | # libraryName Variable name for path to found library 75 | # 76 | # Example: 77 | # ReplaceDynamic(/mingw64/lib/libiconv.dll.a) 78 | # 79 | macro(ReplaceDynamic libraryName) 80 | if(${libraryName} MATCHES ".dll.a") 81 | string(REPLACE ".dll.a" ".a" static ${${libraryName}}) 82 | if(EXISTS ${static}) 83 | set(${libraryName} ${static}) 84 | endif() 85 | endif() 86 | endmacro(ReplaceDynamic) 87 | 88 | 89 | # Replace a dynamic libraries with the static variants, with integrity 90 | # checks for the package. 91 | # 92 | # Args: 93 | # packageName Name of the package 94 | # 95 | # Example: 96 | # FindStaticLibs(IConv) 97 | # 98 | macro(FindStaticLibs packageName) 99 | if(${packageName}_USE_STATIC_LIBS AND MSYS) 100 | # convert `.dll.a` to `.a` 101 | set(${packageName}_LIBRARY_SOURCE ${${packageName}_LIBRARIES}) 102 | set(${packageName}_LIBRARIES "") 103 | foreach(library ${${packageName}_LIBRARY_SOURCE}) 104 | # replace each dynamic library with a single one 105 | set(static_library ${library}) 106 | ReplaceDynamic(static_library) 107 | list(APPEND ${packageName}_LIBRARIES ${static_library}) 108 | endforeach(library) 109 | endif() 110 | endmacro(FindStaticLibs) 111 | 112 | 113 | # Checks if a suitable version for the found library was identified, 114 | # if provided. The library can either force exact or inexact matching. 115 | # 116 | # Args: 117 | # packageName Name of the package 118 | # 119 | # Example: 120 | # MatchVersion(ICU) 121 | # 122 | macro(MatchVersion packageName) 123 | if(${packageName}_FOUND AND ${packageName}_FIND_VERSION) 124 | # MATCH VERSION 125 | if(${packageName}_FIND_VERSION_EXACT) 126 | # EXACT VERSION 127 | if(${packageName}_FIND_VERSION VERSION_EQUAL ${packageName}_VERSION) 128 | else() 129 | set(${packageName}_FOUND FALSE) 130 | endif() 131 | else() 132 | # GREATER THAN VERSION 133 | if(${packageName}_VERSION VERSION_LESS ${packageName}_FIND_VERSION) 134 | set(${packageName}_FOUND FALSE) 135 | endif() 136 | endif() 137 | endif() 138 | endmacro(MatchVersion) 139 | 140 | 141 | # Check if a sample program compiles, if not, set the library to not found. 142 | # 143 | # Args: 144 | # packageName Name of the package 145 | # code String of simple program depending on the library 146 | # 147 | # Example: 148 | # set(IConv_CODE "int main(int argc, char **argv){ return 0; }") 149 | # CheckCompiles(IConv) 150 | # 151 | macro(CheckCompiles packageName) 152 | # FLAGS 153 | set(CMAKE_REQUIRED_INCLUDES ${${packageName}_INCLUDE_DIRS}) 154 | set(CMAKE_REQUIRED_LIBRARIES ${${packageName}_LIBRARIES}) 155 | 156 | # COMPILATION 157 | check_cxx_source_compiles("${${packageName}_CODE}" ${packageName}_COMPILES) 158 | if(NOT ${${packageName}_COMPILES}) 159 | set(${packageName}_FOUND FALSE) 160 | message(SEND_ERROR "Cannot compile a simple ${packageName} program.") 161 | endif() 162 | 163 | endmacro(CheckCompiles) 164 | 165 | 166 | # Send an error if a required package was not found. Otherwise, if the 167 | # package is found, report to the user it was identified. 168 | # 169 | # Args: 170 | # packageName Name of the package 171 | # 172 | # Example: 173 | # RequiredPackageFound(ICU) 174 | # 175 | macro(RequiredPackageFound packageName) 176 | if(${packageName}_FOUND) 177 | message("Found ${packageName}.") 178 | else() 179 | if(${packageName}_FIND_REQUIRED) 180 | message(SEND_ERROR "Unable to find requested ${packageName} libraries.") 181 | endif() 182 | endif() 183 | endmacro(RequiredPackageFound) 184 | -------------------------------------------------------------------------------- /libxlsxwriter/cmake/i686-toolchain.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_SYSTEM_NAME Linux) 2 | set(CMAKE_SYSTEM_VERSION 1) 3 | set(CMAKE_SYSTEM_PROCESSOR "i686") 4 | 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32" CACHE STRING "c++ flags") 6 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32" CACHE STRING "c flags") 7 | set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -m32" CACHE STRING "asm flags") 8 | -------------------------------------------------------------------------------- /libxlsxwriter/cocoapods/libxlsxwriter-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "../xlsxwriter.h" 4 | #import "app.h" 5 | #import "chart.h" 6 | #import "chartsheet.h" 7 | #import "comment.h" 8 | #import "common.h" 9 | #import "content_types.h" 10 | #import "core.h" 11 | #import "custom.h" 12 | #import "drawing.h" 13 | #import "format.h" 14 | #import "hash_table.h" 15 | #import "metadata.h" 16 | #import "packager.h" 17 | #import "relationships.h" 18 | #import "shared_strings.h" 19 | #import "styles.h" 20 | #import "table.h" 21 | #import "theme.h" 22 | #import "third_party/emyg_dtoa.h" 23 | #import "third_party/ioapi.h" 24 | #import "third_party/md5.h" 25 | #import "third_party/queue.h" 26 | #import "third_party/tmpfileplus.h" 27 | #import "third_party/tree.h" 28 | #import "third_party/zip.h" 29 | #import "utility.h" 30 | #import "vml.h" 31 | #import "workbook.h" 32 | #import "worksheet.h" 33 | #import "xmlwriter.h" 34 | 35 | FOUNDATION_EXPORT double xlsxwriterVersionNumber; 36 | FOUNDATION_EXPORT const unsigned char xlsxwriterVersionString[]; 37 | 38 | -------------------------------------------------------------------------------- /libxlsxwriter/cocoapods/libxlsxwriter.modulemap: -------------------------------------------------------------------------------- 1 | framework module xlsxwriter { 2 | umbrella header "xlsxwriter/libxlsxwriter-umbrella.h" 3 | header "xlsxwriter.h" 4 | 5 | export * 6 | module * { export * } 7 | } 8 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | */ 6 | 7 | /** 8 | * @file xlsxwriter.h 9 | * 10 | * xlsxwriter - A library for creating Excel XLSX files. 11 | * 12 | */ 13 | #ifndef __LXW_XLSXWRITER_H__ 14 | #define __LXW_XLSXWRITER_H__ 15 | 16 | #include "xlsxwriter/workbook.h" 17 | #include "xlsxwriter/worksheet.h" 18 | #include "xlsxwriter/format.h" 19 | #include "xlsxwriter/utility.h" 20 | 21 | #define LXW_VERSION "1.1.5" 22 | #define LXW_VERSION_ID 115 23 | #define LXW_SOVERSION "5" 24 | 25 | #endif /* __LXW_XLSXWRITER_H__ */ 26 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/app.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * app - A libxlsxwriter library for creating Excel XLSX app files. 7 | * 8 | */ 9 | #ifndef __LXW_APP_H__ 10 | #define __LXW_APP_H__ 11 | 12 | #include 13 | #include 14 | #include "workbook.h" 15 | #include "common.h" 16 | 17 | /* Define the queue.h TAILQ structs for the App structs. */ 18 | STAILQ_HEAD(lxw_heading_pairs, lxw_heading_pair); 19 | STAILQ_HEAD(lxw_part_names, lxw_part_name); 20 | 21 | typedef struct lxw_heading_pair { 22 | 23 | char *key; 24 | char *value; 25 | 26 | STAILQ_ENTRY (lxw_heading_pair) list_pointers; 27 | 28 | } lxw_heading_pair; 29 | 30 | typedef struct lxw_part_name { 31 | 32 | char *name; 33 | 34 | STAILQ_ENTRY (lxw_part_name) list_pointers; 35 | 36 | } lxw_part_name; 37 | 38 | /* Struct to represent an App object. */ 39 | typedef struct lxw_app { 40 | 41 | FILE *file; 42 | 43 | struct lxw_heading_pairs *heading_pairs; 44 | struct lxw_part_names *part_names; 45 | lxw_doc_properties *properties; 46 | 47 | uint32_t num_heading_pairs; 48 | uint32_t num_part_names; 49 | uint8_t doc_security; 50 | 51 | } lxw_app; 52 | 53 | 54 | /* *INDENT-OFF* */ 55 | #ifdef __cplusplus 56 | extern "C" { 57 | #endif 58 | /* *INDENT-ON* */ 59 | 60 | lxw_app *lxw_app_new(void); 61 | void lxw_app_free(lxw_app *app); 62 | void lxw_app_assemble_xml_file(lxw_app *self); 63 | void lxw_app_add_part_name(lxw_app *self, const char *name); 64 | void lxw_app_add_heading_pair(lxw_app *self, const char *key, 65 | const char *value); 66 | 67 | /* Declarations required for unit testing. */ 68 | #ifdef TESTING 69 | 70 | STATIC void _app_xml_declaration(lxw_app *self); 71 | 72 | #endif /* TESTING */ 73 | 74 | /* *INDENT-OFF* */ 75 | #ifdef __cplusplus 76 | } 77 | #endif 78 | /* *INDENT-ON* */ 79 | 80 | #endif /* __LXW_APP_H__ */ 81 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/comment.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * comment - A libxlsxwriter library for creating Excel XLSX comment files. 7 | * 8 | */ 9 | #ifndef __LXW_COMMENT_H__ 10 | #define __LXW_COMMENT_H__ 11 | 12 | #include 13 | 14 | #include "common.h" 15 | #include "worksheet.h" 16 | 17 | /* Define the tree.h RB structs for the red-black head types. */ 18 | RB_HEAD(lxw_author_ids, lxw_author_id); 19 | 20 | /* 21 | * Struct to represent a comment object. 22 | */ 23 | typedef struct lxw_comment { 24 | 25 | FILE *file; 26 | struct lxw_comment_objs *comment_objs; 27 | struct lxw_author_ids *author_ids; 28 | char *comment_author; 29 | uint32_t author_id; 30 | 31 | } lxw_comment; 32 | 33 | /* Struct to an author id */ 34 | typedef struct lxw_author_id { 35 | uint32_t id; 36 | char *author; 37 | 38 | RB_ENTRY (lxw_author_id) tree_pointers; 39 | } lxw_author_id; 40 | 41 | #define LXW_RB_GENERATE_AUTHOR_IDS(name, type, field, cmp) \ 42 | RB_GENERATE_INSERT_COLOR(name, type, field, static) \ 43 | RB_GENERATE_REMOVE_COLOR(name, type, field, static) \ 44 | RB_GENERATE_INSERT(name, type, field, cmp, static) \ 45 | RB_GENERATE_REMOVE(name, type, field, static) \ 46 | RB_GENERATE_FIND(name, type, field, cmp, static) \ 47 | RB_GENERATE_NEXT(name, type, field, static) \ 48 | RB_GENERATE_MINMAX(name, type, field, static) \ 49 | /* Add unused struct to allow adding a semicolon */ \ 50 | struct lxw_rb_generate_author_ids{int unused;} 51 | 52 | 53 | /* *INDENT-OFF* */ 54 | #ifdef __cplusplus 55 | extern "C" { 56 | #endif 57 | /* *INDENT-ON* */ 58 | 59 | lxw_comment *lxw_comment_new(void); 60 | void lxw_comment_free(lxw_comment *comment); 61 | void lxw_comment_assemble_xml_file(lxw_comment *self); 62 | 63 | /* Declarations required for unit testing. */ 64 | #ifdef TESTING 65 | 66 | STATIC void _comment_xml_declaration(lxw_comment *self); 67 | 68 | #endif /* TESTING */ 69 | 70 | /* *INDENT-OFF* */ 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | /* *INDENT-ON* */ 75 | 76 | #endif /* __LXW_COMMENT_H__ */ 77 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/content_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * content_types - A libxlsxwriter library for creating Excel XLSX 7 | * content_types files. 8 | * 9 | */ 10 | #ifndef __LXW_CONTENT_TYPES_H__ 11 | #define __LXW_CONTENT_TYPES_H__ 12 | 13 | #include 14 | #include 15 | 16 | #include "common.h" 17 | 18 | #define LXW_APP_PACKAGE "application/vnd.openxmlformats-package." 19 | #define LXW_APP_DOCUMENT "application/vnd.openxmlformats-officedocument." 20 | #define LXW_APP_MSEXCEL "application/vnd.ms-excel." 21 | 22 | /* 23 | * Struct to represent a content_types. 24 | */ 25 | typedef struct lxw_content_types { 26 | 27 | FILE *file; 28 | 29 | struct lxw_tuples *default_types; 30 | struct lxw_tuples *overrides; 31 | 32 | } lxw_content_types; 33 | 34 | 35 | /* *INDENT-OFF* */ 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | /* *INDENT-ON* */ 40 | 41 | lxw_content_types *lxw_content_types_new(void); 42 | void lxw_content_types_free(lxw_content_types *content_types); 43 | void lxw_content_types_assemble_xml_file(lxw_content_types *content_types); 44 | void lxw_ct_add_default(lxw_content_types *content_types, const char *key, 45 | const char *value); 46 | void lxw_ct_add_override(lxw_content_types *content_types, const char *key, 47 | const char *value); 48 | void lxw_ct_add_worksheet_name(lxw_content_types *content_types, 49 | const char *name); 50 | void lxw_ct_add_chartsheet_name(lxw_content_types *content_types, 51 | const char *name); 52 | void lxw_ct_add_chart_name(lxw_content_types *content_types, 53 | const char *name); 54 | void lxw_ct_add_drawing_name(lxw_content_types *content_types, 55 | const char *name); 56 | void lxw_ct_add_table_name(lxw_content_types *content_types, 57 | const char *name); 58 | void lxw_ct_add_comment_name(lxw_content_types *content_types, 59 | const char *name); 60 | void lxw_ct_add_vml_name(lxw_content_types *content_types); 61 | 62 | void lxw_ct_add_shared_strings(lxw_content_types *content_types); 63 | void lxw_ct_add_calc_chain(lxw_content_types *content_types); 64 | void lxw_ct_add_custom_properties(lxw_content_types *content_types); 65 | void lxw_ct_add_metadata(lxw_content_types *content_types); 66 | 67 | /* Declarations required for unit testing. */ 68 | #ifdef TESTING 69 | 70 | STATIC void _content_types_xml_declaration(lxw_content_types *self); 71 | STATIC void _write_default(lxw_content_types *self, const char *ext, 72 | const char *type); 73 | STATIC void _write_override(lxw_content_types *self, const char *part_name, 74 | const char *type); 75 | 76 | #endif /* TESTING */ 77 | 78 | /* *INDENT-OFF* */ 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | /* *INDENT-ON* */ 83 | 84 | #endif /* __LXW_CONTENT_TYPES_H__ */ 85 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/core.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * core - A libxlsxwriter library for creating Excel XLSX core files. 7 | * 8 | */ 9 | #ifndef __LXW_CORE_H__ 10 | #define __LXW_CORE_H__ 11 | 12 | #include 13 | 14 | #include "workbook.h" 15 | #include "common.h" 16 | 17 | /* 18 | * Struct to represent a core. 19 | */ 20 | typedef struct lxw_core { 21 | 22 | FILE *file; 23 | lxw_doc_properties *properties; 24 | 25 | } lxw_core; 26 | 27 | 28 | /* *INDENT-OFF* */ 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | /* *INDENT-ON* */ 33 | 34 | lxw_core *lxw_core_new(void); 35 | void lxw_core_free(lxw_core *core); 36 | void lxw_core_assemble_xml_file(lxw_core *self); 37 | 38 | /* Declarations required for unit testing. */ 39 | #ifdef TESTING 40 | 41 | STATIC void _core_xml_declaration(lxw_core *self); 42 | 43 | #endif /* TESTING */ 44 | 45 | /* *INDENT-OFF* */ 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | /* *INDENT-ON* */ 50 | 51 | #endif /* __LXW_CORE_H__ */ 52 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/custom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * custom - A libxlsxwriter library for creating Excel custom property files. 7 | * 8 | */ 9 | #ifndef __LXW_CUSTOM_H__ 10 | #define __LXW_CUSTOM_H__ 11 | 12 | #include 13 | 14 | #include "common.h" 15 | 16 | /* 17 | * Struct to represent a custom property file object. 18 | */ 19 | typedef struct lxw_custom { 20 | 21 | FILE *file; 22 | 23 | struct lxw_custom_properties *custom_properties; 24 | uint32_t pid; 25 | 26 | } lxw_custom; 27 | 28 | 29 | /* *INDENT-OFF* */ 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | /* *INDENT-ON* */ 34 | 35 | lxw_custom *lxw_custom_new(void); 36 | void lxw_custom_free(lxw_custom *custom); 37 | void lxw_custom_assemble_xml_file(lxw_custom *self); 38 | 39 | /* Declarations required for unit testing. */ 40 | #ifdef TESTING 41 | 42 | STATIC void _custom_xml_declaration(lxw_custom *self); 43 | 44 | #endif /* TESTING */ 45 | 46 | /* *INDENT-OFF* */ 47 | #ifdef __cplusplus 48 | } 49 | #endif 50 | /* *INDENT-ON* */ 51 | 52 | #endif /* __LXW_CUSTOM_H__ */ 53 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/drawing.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * drawing - A libxlsxwriter library for creating Excel XLSX drawing files. 7 | * 8 | */ 9 | #ifndef __LXW_DRAWING_H__ 10 | #define __LXW_DRAWING_H__ 11 | 12 | #include 13 | #include 14 | 15 | #include "common.h" 16 | 17 | STAILQ_HEAD(lxw_drawing_objects, lxw_drawing_object); 18 | 19 | enum lxw_drawing_types { 20 | LXW_DRAWING_NONE = 0, 21 | LXW_DRAWING_IMAGE, 22 | LXW_DRAWING_CHART, 23 | LXW_DRAWING_SHAPE 24 | }; 25 | 26 | enum image_types { 27 | LXW_IMAGE_UNKNOWN = 0, 28 | LXW_IMAGE_PNG, 29 | LXW_IMAGE_JPEG, 30 | LXW_IMAGE_BMP, 31 | LXW_IMAGE_GIF 32 | }; 33 | 34 | /* Coordinates used in a drawing object. */ 35 | typedef struct lxw_drawing_coords { 36 | uint32_t col; 37 | uint32_t row; 38 | double col_offset; 39 | double row_offset; 40 | } lxw_drawing_coords; 41 | 42 | /* Object to represent the properties of a drawing. */ 43 | typedef struct lxw_drawing_object { 44 | uint8_t type; 45 | uint8_t anchor; 46 | struct lxw_drawing_coords from; 47 | struct lxw_drawing_coords to; 48 | uint64_t col_absolute; 49 | uint64_t row_absolute; 50 | uint32_t width; 51 | uint32_t height; 52 | uint8_t shape; 53 | uint32_t rel_index; 54 | uint32_t url_rel_index; 55 | char *description; 56 | char *tip; 57 | uint8_t decorative; 58 | 59 | STAILQ_ENTRY (lxw_drawing_object) list_pointers; 60 | 61 | } lxw_drawing_object; 62 | 63 | /* 64 | * Struct to represent a collection of drawings. 65 | */ 66 | typedef struct lxw_drawing { 67 | 68 | FILE *file; 69 | 70 | uint8_t embedded; 71 | uint8_t orientation; 72 | 73 | struct lxw_drawing_objects *drawing_objects; 74 | 75 | } lxw_drawing; 76 | 77 | 78 | /* *INDENT-OFF* */ 79 | #ifdef __cplusplus 80 | extern "C" { 81 | #endif 82 | /* *INDENT-ON* */ 83 | 84 | lxw_drawing *lxw_drawing_new(void); 85 | void lxw_drawing_free(lxw_drawing *drawing); 86 | void lxw_drawing_assemble_xml_file(lxw_drawing *self); 87 | void lxw_free_drawing_object(struct lxw_drawing_object *drawing_object); 88 | void lxw_add_drawing_object(lxw_drawing *drawing, 89 | lxw_drawing_object *drawing_object); 90 | 91 | /* Declarations required for unit testing. */ 92 | #ifdef TESTING 93 | 94 | STATIC void _drawing_xml_declaration(lxw_drawing *self); 95 | #endif /* TESTING */ 96 | 97 | /* *INDENT-OFF* */ 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | /* *INDENT-ON* */ 102 | 103 | #endif /* __LXW_DRAWING_H__ */ 104 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/hash_table.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * hash_table - Hash table functions for libxlsxwriter. 7 | * 8 | */ 9 | 10 | #ifndef __LXW_HASH_TABLE_H__ 11 | #define __LXW_HASH_TABLE_H__ 12 | 13 | #include "common.h" 14 | 15 | /* Macro to loop over hash table elements in insertion order. */ 16 | #define LXW_FOREACH_ORDERED(elem, hash_table) \ 17 | STAILQ_FOREACH((elem), (hash_table)->order_list, lxw_hash_order_pointers) 18 | 19 | /* List declarations. */ 20 | STAILQ_HEAD(lxw_hash_order_list, lxw_hash_element); 21 | SLIST_HEAD(lxw_hash_bucket_list, lxw_hash_element); 22 | 23 | /* LXW_HASH hash table struct. */ 24 | typedef struct lxw_hash_table { 25 | uint32_t num_buckets; 26 | uint32_t used_buckets; 27 | uint32_t unique_count; 28 | uint8_t free_key; 29 | uint8_t free_value; 30 | 31 | struct lxw_hash_order_list *order_list; 32 | struct lxw_hash_bucket_list **buckets; 33 | } lxw_hash_table; 34 | 35 | /* 36 | * LXW_HASH table element struct. 37 | * 38 | * The hash elements contain pointers to allow them to be stored in 39 | * lists in the the hash table buckets and also pointers to track the 40 | * insertion order in a separate list. 41 | */ 42 | typedef struct lxw_hash_element { 43 | void *key; 44 | void *value; 45 | 46 | STAILQ_ENTRY (lxw_hash_element) lxw_hash_order_pointers; 47 | SLIST_ENTRY (lxw_hash_element) lxw_hash_list_pointers; 48 | } lxw_hash_element; 49 | 50 | 51 | /* *INDENT-OFF* */ 52 | #ifdef __cplusplus 53 | extern "C" { 54 | #endif 55 | /* *INDENT-ON* */ 56 | 57 | lxw_hash_element *lxw_hash_key_exists(lxw_hash_table *lxw_hash, void *key, 58 | size_t key_len); 59 | lxw_hash_element *lxw_insert_hash_element(lxw_hash_table *lxw_hash, void *key, 60 | void *value, size_t key_len); 61 | lxw_hash_table *lxw_hash_new(uint32_t num_buckets, uint8_t free_key, 62 | uint8_t free_value); 63 | void lxw_hash_free(lxw_hash_table *lxw_hash); 64 | 65 | /* Declarations required for unit testing. */ 66 | #ifdef TESTING 67 | 68 | #endif 69 | 70 | /* *INDENT-OFF* */ 71 | #ifdef __cplusplus 72 | } 73 | #endif 74 | /* *INDENT-ON* */ 75 | 76 | #endif /* __LXW_HASH_TABLE_H__ */ 77 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/metadata.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * metadata - A libxlsxwriter library for creating Excel XLSX metadata files. 7 | * 8 | */ 9 | #ifndef __LXW_METADATA_H__ 10 | #define __LXW_METADATA_H__ 11 | 12 | #include 13 | 14 | #include "common.h" 15 | 16 | /* 17 | * Struct to represent a metadata object. 18 | */ 19 | typedef struct lxw_metadata { 20 | 21 | FILE *file; 22 | 23 | } lxw_metadata; 24 | 25 | 26 | /* *INDENT-OFF* */ 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | /* *INDENT-ON* */ 31 | 32 | lxw_metadata *lxw_metadata_new(void); 33 | void lxw_metadata_free(lxw_metadata *metadata); 34 | void lxw_metadata_assemble_xml_file(lxw_metadata *self); 35 | 36 | /* Declarations required for unit testing. */ 37 | #ifdef TESTING 38 | 39 | STATIC void _metadata_xml_declaration(lxw_metadata *self); 40 | 41 | #endif /* TESTING */ 42 | 43 | /* *INDENT-OFF* */ 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | /* *INDENT-ON* */ 48 | 49 | #endif /* __LXW_METADATA_H__ */ 50 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/packager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * packager - A libxlsxwriter library for creating Excel XLSX packager files. 7 | * 8 | */ 9 | #ifndef __LXW_PACKAGER_H__ 10 | #define __LXW_PACKAGER_H__ 11 | 12 | #include 13 | 14 | #ifdef USE_SYSTEM_MINIZIP 15 | #ifdef __GNUC__ 16 | #pragma GCC system_header 17 | #endif 18 | #include "minizip/zip.h" 19 | #else 20 | #include "third_party/zip.h" 21 | #endif 22 | 23 | #include "common.h" 24 | #include "workbook.h" 25 | #include "worksheet.h" 26 | #include "shared_strings.h" 27 | #include "app.h" 28 | #include "core.h" 29 | #include "custom.h" 30 | #include "table.h" 31 | #include "theme.h" 32 | #include "styles.h" 33 | #include "format.h" 34 | #include "content_types.h" 35 | #include "relationships.h" 36 | #include "vml.h" 37 | #include "comment.h" 38 | #include "metadata.h" 39 | 40 | #define LXW_ZIP_BUFFER_SIZE (16384) 41 | 42 | /* If zip returns a ZIP_XXX error then errno is set and we can trap that in 43 | * workbook.c. Otherwise return a default libxlsxwriter error. */ 44 | #define RETURN_ON_ZIP_ERROR(err, default_err) \ 45 | do { \ 46 | if (err == ZIP_ERRNO) \ 47 | return LXW_ERROR_ZIP_FILE_OPERATION; \ 48 | else if (err == ZIP_PARAMERROR) \ 49 | return LXW_ERROR_ZIP_PARAMETER_ERROR; \ 50 | else if (err == ZIP_BADZIPFILE) \ 51 | return LXW_ERROR_ZIP_BAD_ZIP_FILE; \ 52 | else if (err == ZIP_INTERNALERROR) \ 53 | return LXW_ERROR_ZIP_INTERNAL_ERROR; \ 54 | else \ 55 | return default_err; \ 56 | } while (0) 57 | 58 | /* 59 | * Struct to represent a packager. 60 | */ 61 | typedef struct lxw_packager { 62 | 63 | FILE *file; 64 | lxw_workbook *workbook; 65 | 66 | size_t buffer_size; 67 | size_t output_buffer_size; 68 | zipFile zipfile; 69 | zip_fileinfo zipfile_info; 70 | const char *filename; 71 | const char *buffer; 72 | char *output_buffer; 73 | const char *tmpdir; 74 | uint8_t use_zip64; 75 | 76 | } lxw_packager; 77 | 78 | 79 | /* *INDENT-OFF* */ 80 | #ifdef __cplusplus 81 | extern "C" { 82 | #endif 83 | /* *INDENT-ON* */ 84 | 85 | lxw_packager *lxw_packager_new(const char *filename, const char *tmpdir, 86 | uint8_t use_zip64); 87 | void lxw_packager_free(lxw_packager *packager); 88 | lxw_error lxw_create_package(lxw_packager *self); 89 | 90 | /* Declarations required for unit testing. */ 91 | #ifdef TESTING 92 | 93 | #endif /* TESTING */ 94 | 95 | /* *INDENT-OFF* */ 96 | #ifdef __cplusplus 97 | } 98 | #endif 99 | /* *INDENT-ON* */ 100 | 101 | #endif /* __LXW_PACKAGER_H__ */ 102 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/relationships.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * relationships - A libxlsxwriter library for creating Excel XLSX 7 | * relationships files. 8 | * 9 | */ 10 | #ifndef __LXW_RELATIONSHIPS_H__ 11 | #define __LXW_RELATIONSHIPS_H__ 12 | 13 | #include 14 | 15 | #include "common.h" 16 | 17 | /* Define the queue.h STAILQ structs for the generic data structs. */ 18 | STAILQ_HEAD(lxw_rel_tuples, lxw_rel_tuple); 19 | 20 | typedef struct lxw_rel_tuple { 21 | 22 | char *type; 23 | char *target; 24 | char *target_mode; 25 | 26 | STAILQ_ENTRY (lxw_rel_tuple) list_pointers; 27 | 28 | } lxw_rel_tuple; 29 | 30 | /* 31 | * Struct to represent a relationships. 32 | */ 33 | typedef struct lxw_relationships { 34 | 35 | FILE *file; 36 | 37 | uint32_t rel_id; 38 | struct lxw_rel_tuples *relationships; 39 | 40 | } lxw_relationships; 41 | 42 | 43 | 44 | /* *INDENT-OFF* */ 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | /* *INDENT-ON* */ 49 | 50 | lxw_relationships *lxw_relationships_new(void); 51 | void lxw_free_relationships(lxw_relationships *relationships); 52 | void lxw_relationships_assemble_xml_file(lxw_relationships *self); 53 | 54 | void lxw_add_document_relationship(lxw_relationships *self, const char *type, 55 | const char *target); 56 | void lxw_add_package_relationship(lxw_relationships *self, const char *type, 57 | const char *target); 58 | void lxw_add_ms_package_relationship(lxw_relationships *self, 59 | const char *type, const char *target); 60 | void lxw_add_worksheet_relationship(lxw_relationships *self, const char *type, 61 | const char *target, 62 | const char *target_mode); 63 | 64 | /* Declarations required for unit testing. */ 65 | #ifdef TESTING 66 | 67 | STATIC void _relationships_xml_declaration(lxw_relationships *self); 68 | 69 | #endif /* TESTING */ 70 | 71 | /* *INDENT-OFF* */ 72 | #ifdef __cplusplus 73 | } 74 | #endif 75 | /* *INDENT-ON* */ 76 | 77 | #endif /* __LXW_RELATIONSHIPS_H__ */ 78 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/shared_strings.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * shared_strings - A libxlsxwriter library for creating Excel XLSX 7 | * sst files. 8 | * 9 | */ 10 | #ifndef __LXW_SST_H__ 11 | #define __LXW_SST_H__ 12 | 13 | #include 14 | #include 15 | 16 | #include "common.h" 17 | 18 | /* Define a tree.h RB structure for storing shared strings. */ 19 | RB_HEAD(sst_rb_tree, sst_element); 20 | 21 | /* Define a queue.h structure for storing shared strings in insertion order. */ 22 | STAILQ_HEAD(sst_order_list, sst_element); 23 | 24 | /* Wrapper around RB_GENERATE_STATIC from tree.h to avoid unused function 25 | * warnings and to avoid portability issues with the _unused attribute. */ 26 | #define LXW_RB_GENERATE_ELEMENT(name, type, field, cmp) \ 27 | RB_GENERATE_INSERT_COLOR(name, type, field, static) \ 28 | RB_GENERATE_INSERT(name, type, field, cmp, static) \ 29 | /* Add unused struct to allow adding a semicolon */ \ 30 | struct lxw_rb_generate_element{int unused;} 31 | 32 | /* 33 | * Elements of the SST table. They contain pointers to allow them to 34 | * be stored in a RB tree and also pointers to track the insertion order 35 | * in a separate list. 36 | */ 37 | struct sst_element { 38 | uint32_t index; 39 | char *string; 40 | uint8_t is_rich_string; 41 | 42 | STAILQ_ENTRY (sst_element) sst_order_pointers; 43 | RB_ENTRY (sst_element) sst_tree_pointers; 44 | }; 45 | 46 | /* 47 | * Struct to represent a sst. 48 | */ 49 | typedef struct lxw_sst { 50 | FILE *file; 51 | 52 | uint32_t string_count; 53 | uint32_t unique_count; 54 | 55 | struct sst_order_list *order_list; 56 | struct sst_rb_tree *rb_tree; 57 | 58 | } lxw_sst; 59 | 60 | /* *INDENT-OFF* */ 61 | #ifdef __cplusplus 62 | extern "C" { 63 | #endif 64 | /* *INDENT-ON* */ 65 | 66 | lxw_sst *lxw_sst_new(void); 67 | void lxw_sst_free(lxw_sst *sst); 68 | struct sst_element *lxw_get_sst_index(lxw_sst *sst, const char *string, 69 | uint8_t is_rich_string); 70 | void lxw_sst_assemble_xml_file(lxw_sst *self); 71 | 72 | /* Declarations required for unit testing. */ 73 | #ifdef TESTING 74 | 75 | STATIC void _sst_xml_declaration(lxw_sst *self); 76 | 77 | #endif /* TESTING */ 78 | 79 | /* *INDENT-OFF* */ 80 | #ifdef __cplusplus 81 | } 82 | #endif 83 | /* *INDENT-ON* */ 84 | 85 | #endif /* __LXW_SST_H__ */ 86 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/styles.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * styles - A libxlsxwriter library for creating Excel XLSX styles files. 7 | * 8 | */ 9 | #ifndef __LXW_STYLES_H__ 10 | #define __LXW_STYLES_H__ 11 | 12 | #include 13 | #include 14 | 15 | #include "format.h" 16 | 17 | /* 18 | * Struct to represent a styles. 19 | */ 20 | typedef struct lxw_styles { 21 | 22 | FILE *file; 23 | uint32_t font_count; 24 | uint32_t xf_count; 25 | uint32_t dxf_count; 26 | uint32_t num_format_count; 27 | uint32_t border_count; 28 | uint32_t fill_count; 29 | struct lxw_formats *xf_formats; 30 | struct lxw_formats *dxf_formats; 31 | uint8_t has_hyperlink; 32 | uint16_t hyperlink_font_id; 33 | uint8_t has_comments; 34 | 35 | } lxw_styles; 36 | 37 | 38 | /* *INDENT-OFF* */ 39 | #ifdef __cplusplus 40 | extern "C" { 41 | #endif 42 | /* *INDENT-ON* */ 43 | 44 | lxw_styles *lxw_styles_new(void); 45 | void lxw_styles_free(lxw_styles *styles); 46 | void lxw_styles_assemble_xml_file(lxw_styles *self); 47 | void lxw_styles_write_string_fragment(lxw_styles *self, const char *string); 48 | void lxw_styles_write_rich_font(lxw_styles *styles, lxw_format *format); 49 | 50 | /* Declarations required for unit testing. */ 51 | #ifdef TESTING 52 | 53 | STATIC void _styles_xml_declaration(lxw_styles *self); 54 | STATIC void _write_style_sheet(lxw_styles *self); 55 | STATIC void _write_font_size(lxw_styles *self, double font_size); 56 | STATIC void _write_font_color_theme(lxw_styles *self, uint8_t theme); 57 | STATIC void _write_font_name(lxw_styles *self, const char *font_name, 58 | uint8_t is_rich_string); 59 | STATIC void _write_font_family(lxw_styles *self, uint8_t font_family); 60 | STATIC void _write_font_scheme(lxw_styles *self, const char *font_scheme); 61 | STATIC void _write_font(lxw_styles *self, lxw_format *format, uint8_t is_dxf, 62 | uint8_t is_rich_string); 63 | STATIC void _write_fonts(lxw_styles *self); 64 | STATIC void _write_default_fill(lxw_styles *self, const char *pattern); 65 | STATIC void _write_fills(lxw_styles *self); 66 | STATIC void _write_border(lxw_styles *self, lxw_format *format, 67 | uint8_t is_dxf); 68 | STATIC void _write_borders(lxw_styles *self); 69 | STATIC void _write_style_xf(lxw_styles *self, uint8_t has_hyperlink, 70 | uint16_t font_id); 71 | STATIC void _write_cell_style_xfs(lxw_styles *self); 72 | STATIC void _write_xf(lxw_styles *self, lxw_format *format); 73 | STATIC void _write_cell_xfs(lxw_styles *self); 74 | STATIC void _write_cell_style(lxw_styles *self, char *name, uint8_t xf_id, 75 | uint8_t builtin_id); 76 | STATIC void _write_cell_styles(lxw_styles *self); 77 | STATIC void _write_dxfs(lxw_styles *self); 78 | STATIC void _write_table_styles(lxw_styles *self); 79 | 80 | #endif /* TESTING */ 81 | 82 | /* *INDENT-OFF* */ 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | /* *INDENT-ON* */ 87 | 88 | #endif /* __LXW_STYLES_H__ */ 89 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/table.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * table - A libxlsxwriter library for creating Excel XLSX table files. 7 | * 8 | */ 9 | #ifndef __LXW_TABLE_H__ 10 | #define __LXW_TABLE_H__ 11 | 12 | #include 13 | 14 | #include "common.h" 15 | 16 | /* 17 | * Struct to represent a table object. 18 | */ 19 | typedef struct lxw_table { 20 | 21 | FILE *file; 22 | 23 | struct lxw_table_obj *table_obj; 24 | 25 | } lxw_table; 26 | 27 | 28 | /* *INDENT-OFF* */ 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | /* *INDENT-ON* */ 33 | 34 | lxw_table *lxw_table_new(void); 35 | void lxw_table_free(lxw_table *table); 36 | void lxw_table_assemble_xml_file(lxw_table *self); 37 | 38 | /* Declarations required for unit testing. */ 39 | #ifdef TESTING 40 | 41 | STATIC void _table_xml_declaration(lxw_table *self); 42 | 43 | #endif /* TESTING */ 44 | 45 | /* *INDENT-OFF* */ 46 | #ifdef __cplusplus 47 | } 48 | #endif 49 | /* *INDENT-ON* */ 50 | 51 | #endif /* __LXW_TABLE_H__ */ 52 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/theme.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * theme - A libxlsxwriter library for creating Excel XLSX theme files. 7 | * 8 | */ 9 | #ifndef __LXW_THEME_H__ 10 | #define __LXW_THEME_H__ 11 | 12 | #include 13 | 14 | #include "common.h" 15 | 16 | /* 17 | * Struct to represent a theme. 18 | */ 19 | typedef struct lxw_theme { 20 | 21 | FILE *file; 22 | } lxw_theme; 23 | 24 | 25 | /* *INDENT-OFF* */ 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | /* *INDENT-ON* */ 30 | 31 | lxw_theme *lxw_theme_new(void); 32 | void lxw_theme_free(lxw_theme *theme); 33 | void lxw_theme_xml_declaration(lxw_theme *self); 34 | void lxw_theme_assemble_xml_file(lxw_theme *self); 35 | 36 | /* Declarations required for unit testing. */ 37 | #ifdef TESTING 38 | 39 | #endif /* TESTING */ 40 | 41 | /* *INDENT-OFF* */ 42 | #ifdef __cplusplus 43 | } 44 | #endif 45 | /* *INDENT-ON* */ 46 | 47 | #endif /* __LXW_THEME_H__ */ 48 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/third_party/emyg_dtoa.h: -------------------------------------------------------------------------------- 1 | /* emyg_dtoa.h 2 | ** Copyright (C) 2015 Doug Currie 3 | ** based on dtoa_milo.h 4 | ** Copyright (C) 2014 Milo Yip 5 | ** 6 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 7 | ** of this software and associated documentation files (the "Software"), to deal 8 | ** in the Software without restriction, including without limitation the rights 9 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | ** copies of the Software, and to permit persons to whom the Software is 11 | ** furnished to do so, subject to the following conditions: 12 | ** 13 | ** The above copyright notice and this permission notice shall be included in 14 | ** all copies or substantial portions of the Software. 15 | ** 16 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | ** THE SOFTWARE. 23 | */ 24 | 25 | /* Source from https://github.com/miloyip/dtoa-benchmark */ 26 | void emyg_dtoa (double value, char* buffer); 27 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/third_party/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 3 | * MD5 Message-Digest Algorithm (RFC 1321). 4 | * 5 | * Homepage: 6 | * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 7 | * 8 | * Author: 9 | * Alexander Peslyak, better known as Solar Designer 10 | * 11 | * This software was written by Alexander Peslyak in 2001. No copyright is 12 | * claimed, and the software is hereby placed in the public domain. 13 | * In case this attempt to disclaim copyright and place the software in the 14 | * public domain is deemed null and void, then the software is 15 | * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 16 | * general public under the following terms: 17 | * 18 | * Redistribution and use in source and binary forms, with or without 19 | * modification, are permitted. 20 | * 21 | * There's ABSOLUTELY NO WARRANTY, express or implied. 22 | * 23 | * See md5.c for more information. 24 | */ 25 | 26 | #ifdef HAVE_OPENSSL 27 | #include 28 | #elif !defined(_MD5_H) 29 | #define _MD5_H 30 | 31 | /* Any 32-bit or wider unsigned integer data type will do */ 32 | typedef unsigned int MD5_u32plus; 33 | 34 | typedef struct { 35 | MD5_u32plus lo, hi; 36 | MD5_u32plus a, b, c, d; 37 | unsigned char buffer[64]; 38 | MD5_u32plus block[16]; 39 | } MD5_CTX; 40 | 41 | extern void MD5_Init(MD5_CTX *ctx); 42 | extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); 43 | extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/third_party/tmpfileplus.h: -------------------------------------------------------------------------------- 1 | /* $Id: tmpfileplus.h $ */ 2 | /* 3 | * $Date: 2016-06-01 03:31Z $ 4 | * $Revision: 2.0.0 $ 5 | * $Author: dai $ 6 | */ 7 | 8 | /* 9 | * This Source Code Form is subject to the terms of the Mozilla Public 10 | * License, v. 2.0. If a copy of the MPL was not distributed with this 11 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 12 | * 13 | * Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd 14 | * . 15 | */ 16 | 17 | #if _MSC_VER > 1000 18 | #pragma once 19 | #endif 20 | 21 | #ifndef TMPFILEPLUS_H_ 22 | #define TMPFILEPLUS_H_ 23 | 24 | #include 25 | 26 | /** Create a unique temporary file. 27 | @param dir (optional) directory to create file. If NULL use default TMP directory. 28 | @param prefix (optional) prefix for file name. If NULL use "tmp.". 29 | @param pathname (optional) pointer to a buffer to receive the temp filename. 30 | Allocated using `malloc()`; user to free. Ignored if NULL. 31 | @param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing. 32 | Otherwise file is automatically deleted when closed. 33 | @return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error. 34 | @exception ENOMEM Not enough memory to allocate filename. 35 | */ 36 | FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep); 37 | 38 | 39 | /** Create a unique temporary file with filename stored in a fixed-length buffer. 40 | @param dir (optional) directory to create file. If NULL use default directory. 41 | @param prefix (optional) prefix for file name. If NULL use "tmp.". 42 | @param pathnamebuf (optional) buffer to receive full pathname of temporary file. Ignored if NULL. 43 | @param pathsize Size of buffer to receive filename and its terminating null character. 44 | @param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing. 45 | Otherwise file is automatically deleted when closed. 46 | @return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error. 47 | @exception E2BIG Resulting filename is too big for the buffer `pathnamebuf`. 48 | */ 49 | FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep); 50 | 51 | #define TMPFILE_KEEP 1 52 | 53 | #endif /* end TMPFILEPLUS_H_ */ 54 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/vml.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * vml - A libxlsxwriter library for creating Excel XLSX vml files. 7 | * 8 | */ 9 | #ifndef __LXW_VML_H__ 10 | #define __LXW_VML_H__ 11 | 12 | #include 13 | 14 | #include "common.h" 15 | #include "worksheet.h" 16 | 17 | /* 18 | * Struct to represent a vml object. 19 | */ 20 | typedef struct lxw_vml { 21 | 22 | FILE *file; 23 | uint8_t type; 24 | struct lxw_comment_objs *button_objs; 25 | struct lxw_comment_objs *comment_objs; 26 | struct lxw_comment_objs *image_objs; 27 | char *vml_data_id_str; 28 | uint32_t vml_shape_id; 29 | uint8_t comment_display_default; 30 | 31 | } lxw_vml; 32 | 33 | 34 | /* *INDENT-OFF* */ 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | /* *INDENT-ON* */ 39 | 40 | lxw_vml *lxw_vml_new(void); 41 | void lxw_vml_free(lxw_vml *vml); 42 | void lxw_vml_assemble_xml_file(lxw_vml *self); 43 | 44 | /* Declarations required for unit testing. */ 45 | #ifdef TESTING 46 | 47 | #endif /* TESTING */ 48 | 49 | /* *INDENT-OFF* */ 50 | #ifdef __cplusplus 51 | } 52 | #endif 53 | /* *INDENT-ON* */ 54 | 55 | #endif /* __LXW_VML_H__ */ 56 | -------------------------------------------------------------------------------- /libxlsxwriter/include/xlsxwriter/xmlwriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * libxlsxwriter 3 | * 4 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 5 | * 6 | * xmlwriter - A libxlsxwriter library for creating Excel XLSX 7 | * XML files. 8 | * 9 | * The xmlwriter library is used to create the XML sub-components files 10 | * in the Excel XLSX file format. 11 | * 12 | * This library is used in preference to a more generic XML library to allow 13 | * for customization and optimization for the XLSX file format. 14 | * 15 | * The xmlwriter functions are only used internally and do not need to be 16 | * called directly by the end user. 17 | * 18 | */ 19 | #ifndef __XMLWRITER_H__ 20 | #define __XMLWRITER_H__ 21 | 22 | #include 23 | #include 24 | #include 25 | #include "utility.h" 26 | 27 | #define LXW_MAX_ATTRIBUTE_LENGTH 2080 /* Max URL length. */ 28 | #define LXW_ATTR_32 32 29 | 30 | #define LXW_ATTRIBUTE_COPY(dst, src) \ 31 | do{ \ 32 | strncpy(dst, src, LXW_MAX_ATTRIBUTE_LENGTH -1); \ 33 | dst[LXW_MAX_ATTRIBUTE_LENGTH - 1] = '\0'; \ 34 | } while (0) 35 | 36 | 37 | /* *INDENT-OFF* */ 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | /* *INDENT-ON* */ 42 | 43 | /* Attribute used in XML elements. */ 44 | struct xml_attribute { 45 | char key[LXW_MAX_ATTRIBUTE_LENGTH]; 46 | char value[LXW_MAX_ATTRIBUTE_LENGTH]; 47 | 48 | /* Make the struct a queue.h list element. */ 49 | STAILQ_ENTRY (xml_attribute) list_entries; 50 | }; 51 | 52 | /* Use queue.h macros to define the xml_attribute_list type. */ 53 | STAILQ_HEAD(xml_attribute_list, xml_attribute); 54 | 55 | /* Create a new attribute struct to add to a xml_attribute_list. */ 56 | struct xml_attribute *lxw_new_attribute_str(const char *key, 57 | const char *value); 58 | struct xml_attribute *lxw_new_attribute_int(const char *key, uint64_t value); 59 | struct xml_attribute *lxw_new_attribute_dbl(const char *key, double value); 60 | 61 | /* Macro to initialize the xml_attribute_list pointers. */ 62 | #define LXW_INIT_ATTRIBUTES() \ 63 | STAILQ_INIT(&attributes) 64 | 65 | /* Macro to add attribute string elements to xml_attribute_list. */ 66 | #define LXW_PUSH_ATTRIBUTES_STR(key, value) \ 67 | do { \ 68 | attribute = lxw_new_attribute_str((key), (value)); \ 69 | STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \ 70 | } while (0) 71 | 72 | /* Macro to add attribute int values to xml_attribute_list. */ 73 | #define LXW_PUSH_ATTRIBUTES_INT(key, value) \ 74 | do { \ 75 | attribute = lxw_new_attribute_int((key), (value)); \ 76 | STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \ 77 | } while (0) 78 | 79 | /* Macro to add attribute double values to xml_attribute_list. */ 80 | #define LXW_PUSH_ATTRIBUTES_DBL(key, value) \ 81 | do { \ 82 | attribute = lxw_new_attribute_dbl((key), (value)); \ 83 | STAILQ_INSERT_TAIL(&attributes, attribute, list_entries); \ 84 | } while (0) 85 | 86 | /* Macro to free xml_attribute_list and attribute. */ 87 | #define LXW_FREE_ATTRIBUTES() \ 88 | do { \ 89 | while (!STAILQ_EMPTY(&attributes)) { \ 90 | attribute = STAILQ_FIRST(&attributes); \ 91 | STAILQ_REMOVE_HEAD(&attributes, list_entries); \ 92 | free(attribute); \ 93 | } \ 94 | } while (0) 95 | 96 | /** 97 | * Create the XML declaration in an XML file. 98 | * 99 | * @param xmlfile A FILE pointer to the output XML file. 100 | */ 101 | void lxw_xml_declaration(FILE * xmlfile); 102 | 103 | /** 104 | * Write an XML start tag with optional attributes. 105 | * 106 | * @param xmlfile A FILE pointer to the output XML file. 107 | * @param tag The XML tag to write. 108 | * @param attributes An optional list of attributes to add to the tag. 109 | */ 110 | void lxw_xml_start_tag(FILE * xmlfile, 111 | const char *tag, 112 | struct xml_attribute_list *attributes); 113 | 114 | /** 115 | * Write an XML start tag with optional un-encoded attributes. 116 | * This is a minor optimization for attributes that don't need encoding. 117 | * 118 | * @param xmlfile A FILE pointer to the output XML file. 119 | * @param tag The XML tag to write. 120 | * @param attributes An optional list of attributes to add to the tag. 121 | */ 122 | void lxw_xml_start_tag_unencoded(FILE * xmlfile, 123 | const char *tag, 124 | struct xml_attribute_list *attributes); 125 | 126 | /** 127 | * Write an XML end tag. 128 | * 129 | * @param xmlfile A FILE pointer to the output XML file. 130 | * @param tag The XML tag to write. 131 | */ 132 | void lxw_xml_end_tag(FILE * xmlfile, const char *tag); 133 | 134 | /** 135 | * Write an XML empty tag with optional attributes. 136 | * 137 | * @param xmlfile A FILE pointer to the output XML file. 138 | * @param tag The XML tag to write. 139 | * @param attributes An optional list of attributes to add to the tag. 140 | */ 141 | void lxw_xml_empty_tag(FILE * xmlfile, 142 | const char *tag, 143 | struct xml_attribute_list *attributes); 144 | 145 | /** 146 | * Write an XML empty tag with optional un-encoded attributes. 147 | * This is a minor optimization for attributes that don't need encoding. 148 | * 149 | * @param xmlfile A FILE pointer to the output XML file. 150 | * @param tag The XML tag to write. 151 | * @param attributes An optional list of attributes to add to the tag. 152 | */ 153 | void lxw_xml_empty_tag_unencoded(FILE * xmlfile, 154 | const char *tag, 155 | struct xml_attribute_list *attributes); 156 | 157 | /** 158 | * Write an XML element containing data and optional attributes. 159 | * 160 | * @param xmlfile A FILE pointer to the output XML file. 161 | * @param tag The XML tag to write. 162 | * @param data The data section of the XML element. 163 | * @param attributes An optional list of attributes to add to the tag. 164 | */ 165 | void lxw_xml_data_element(FILE * xmlfile, 166 | const char *tag, 167 | const char *data, 168 | struct xml_attribute_list *attributes); 169 | 170 | void lxw_xml_rich_si_element(FILE * xmlfile, const char *string); 171 | 172 | uint8_t lxw_has_control_characters(const char *string); 173 | char *lxw_escape_control_characters(const char *string); 174 | char *lxw_escape_url_characters(const char *string, uint8_t escape_hash); 175 | 176 | char *lxw_escape_data(const char *data); 177 | 178 | /* *INDENT-OFF* */ 179 | #ifdef __cplusplus 180 | } 181 | #endif 182 | /* *INDENT-ON* */ 183 | 184 | #endif /* __XMLWRITER_H__ */ 185 | -------------------------------------------------------------------------------- /libxlsxwriter/lib/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Paxa/fast_excel/dc2b5e56e28a26e5f601fde98233a0241a4c4ebd/libxlsxwriter/lib/.gitignore -------------------------------------------------------------------------------- /libxlsxwriter/libxlsxwriter.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "libxlsxwriter" 3 | s.version = "1.1.5" 4 | s.summary = "Libxlsxwriter: A C library for creating Excel XLSX files." 5 | s.ios.deployment_target = "8.0" 6 | s.osx.deployment_target = "10.8" 7 | 8 | s.description = <<-DESC 9 | Libxlsxwriter is a C library that can be used to write text, numbers, formulas and hyperlinks to multiple worksheets in an Excel 2007+ XLSX file. 10 | 11 | It supports features such as: 12 | 13 | * 100% compatible Excel XLSX files. 14 | * Full Excel formatting. 15 | * Merged cells. 16 | * Defined names. 17 | * Autofilters. 18 | * Charts. 19 | * Data validation and drop down lists. 20 | * Conditional formatting. 21 | * Worksheet PNG/JPEG/GIF images. 22 | * Cell comments. 23 | * Support for adding Macros. 24 | * Memory optimisation mode for writing large files. 25 | * Source code available on [GitHub](https://github.com/jmcnamara/libxlsxwriter). 26 | * FreeBSD license. 27 | * ANSI C. 28 | * Works with GCC, Clang, Xcode, MSVC 2015, ICC, TCC, MinGW, MingGW-w64/32. 29 | * Works on Linux, FreeBSD, OpenBSD, OS X, iOS and Windows. Also works on MSYS/MSYS2 and Cygwin. 30 | * Compiles for 32 and 64 bit. 31 | * Compiles and works on big and little endian systems. 32 | * The only dependency is on `zlib`. 33 | DESC 34 | 35 | s.homepage = "http://libxlsxwriter.github.io" 36 | s.documentation_url = "http://libxlsxwriter.github.io" 37 | s.license = "FreeBSD" 38 | s.author = { "John McNamara" => "jmcnamara@cpan.org" } 39 | 40 | s.source = { :git => "https://github.com/jmcnamara/libxlsxwriter.git", :tag => "RELEASE_" + s.version.to_s } 41 | s.source_files = "src/*.c", "third_party/**/{zip.c,ioapi.c,tmpfileplus.c,md5.c}", "include/**/*.h" 42 | s.preserve_paths = [ 'third_party/**/*.h' ] 43 | s.header_dir = "xlsxwriter" 44 | s.header_mappings_dir = "include" 45 | s.library = "z" 46 | s.compiler_flags = "-DNOCRYPT=1", "-DNOUNCRYPT=1" 47 | s.pod_target_xcconfig = { 'USER_HEADER_SEARCH_PATHS' => '${PODS_ROOT}/libxlsxwriter/include' } 48 | s.module_map = "cocoapods/libxlsxwriter.modulemap" 49 | s.prepare_command = <<-CMD 50 | cp cocoapods/libxlsxwriter-umbrella.h include/xlsxwriter/libxlsxwriter-umbrella.h 51 | CMD 52 | end 53 | -------------------------------------------------------------------------------- /libxlsxwriter/src/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Makefile for libxlsxwriter library. 4 | # 5 | # Copyright 2014-2022, John McNamara, jmcnamara@cpan.org 6 | # 7 | 8 | # Keep the output quiet by default. 9 | Q=@ 10 | ifdef V 11 | Q= 12 | endif 13 | 14 | DESTDIR ?= 15 | PREFIX ?= /usr/local 16 | OPT_LEVEL ?= -O3 17 | 18 | SOVERSION = $(shell sed -n -e 's/.*LXW_SOVERSION \"\(.*\)\"/\1/p' ../include/xlsxwriter.h) 19 | 20 | 21 | # Directory variables. 22 | OBJS_DIR = . 23 | INC_DIR = ../include 24 | 25 | LIBS = -lz 26 | 27 | ifdef USE_SYSTEM_MINIZIP 28 | LIBS += -lminizip 29 | CFLAGS += -DUSE_SYSTEM_MINIZIP 30 | else 31 | # Use the local copy of minizip. 32 | MINIZIP_DIR = ../third_party/minizip 33 | MINIZIP_OBJ = $(MINIZIP_DIR)/ioapi.o $(MINIZIP_DIR)/zip.o 34 | MINIZIP_SO = $(MINIZIP_DIR)/ioapi.so $(MINIZIP_DIR)/zip.so 35 | endif 36 | 37 | ifdef USE_STANDARD_TMPFILE 38 | # Use standard/C tmpfile(). 39 | CFLAGS += -DUSE_STANDARD_TMPFILE 40 | else 41 | # Use tmpfileplus (the default). 42 | TMPFILEPLUS_DIR = ../third_party/tmpfileplus 43 | TMPFILEPLUS_OBJ = $(TMPFILEPLUS_DIR)/tmpfileplus.o 44 | TMPFILEPLUS_SO = $(TMPFILEPLUS_DIR)/tmpfileplus.so 45 | endif 46 | 47 | ifdef USE_NO_MD5 48 | # Don't use MD5 to avoid duplicate image files. 49 | CFLAGS += -DUSE_NO_MD5 50 | else 51 | ifdef USE_OPENSSL_MD5 52 | CFLAGS += -DUSE_OPENSSL_MD5 -Wno-deprecated-declarations 53 | LIBS += -lcrypto 54 | else 55 | # Use md5 (the default). 56 | MD5_DIR = ../third_party/md5 57 | MD5_OBJ = $(MD5_DIR)/md5.o 58 | MD5_SO = $(MD5_DIR)/md5.so 59 | endif 60 | endif 61 | 62 | # Set flag for big endian architecture. 63 | ifdef USE_BIG_ENDIAN 64 | CFLAGS += -DLXW_BIG_ENDIAN 65 | endif 66 | 67 | # Use a third party double number formatting function. 68 | ifdef USE_DTOA_LIBRARY 69 | CFLAGS += -DUSE_DTOA_LIBRARY 70 | DTOA_LIB_DIR = ../third_party/dtoa 71 | DTOA_LIB_OBJ = $(DTOA_LIB_DIR)/emyg_dtoa.o 72 | DTOA_LIB_SO = $(DTOA_LIB_DIR)/emyg_dtoa.so 73 | endif 74 | 75 | # Use fmemopen()/open_memstream() to avoid creating temporary files 76 | ifdef USE_MEM_FILE 77 | USE_FMEMOPEN = 1 78 | endif 79 | 80 | ifdef USE_FMEMOPEN 81 | CFLAGS += -DUSE_FMEMOPEN 82 | endif 83 | 84 | # Flags passed to compiler. 85 | CFLAGS += -g $(OPT_LEVEL) -Wall -Wextra -Wstrict-prototypes -pedantic -ansi 86 | 87 | # Ignore icc remarks about inlining limits. 88 | ifeq ($(CC),icc) 89 | CFLAGS +=-diag-disable=11074,11076 90 | endif 91 | 92 | # Library names. 93 | LIBXLSXWRITER_A = libxlsxwriter.a 94 | LIBXLSXWRITER_SO = libxlsxwriter.so.$(SOVERSION) 95 | 96 | # Library with additional non-static functions for testing. 97 | LIBXLSXWRITER_TO = libxlsxwriter_test.a 98 | 99 | # Flags passed to static linker. 100 | ARFLAGS = rc 101 | 102 | # Flags passed to dynamic linker. 103 | FPIC = -fPIC 104 | SOFLAGS = -shared $(FPIC) -Wl,-soname,$(LIBXLSXWRITER_SO) 105 | 106 | # Get Env/OS name. 107 | UNAME := $(shell uname) 108 | 109 | # Change make options on OS X. 110 | ifeq ($(UNAME), Darwin) 111 | LIBXLSXWRITER_SO = libxlsxwriter.$(SOVERSION).dylib 112 | SOFLAGS = -dynamiclib $(FPIC) -compatibility_version $(SOVERSION) -install_name $(PREFIX)/lib/$(LIBXLSXWRITER_SO) $(GCOV) 113 | endif 114 | 115 | # Check for MinGW/MinGW64/Cygwin environments. 116 | ifneq (,$(findstring MINGW, $(UNAME))) 117 | MING_LIKE = y 118 | endif 119 | ifneq (,$(findstring MSYS, $(UNAME))) 120 | MING_LIKE = y 121 | endif 122 | ifneq (,$(findstring CYGWIN, $(UNAME))) 123 | MING_LIKE = y 124 | endif 125 | 126 | # Change make options on MinGW/MinGW64/Cygwin. 127 | ifdef MING_LIKE 128 | LIBXLSXWRITER_SO = libxlsxwriter.dll 129 | FPIC = 130 | CC = gcc 131 | CFLAGS += -Wno-char-subscripts -Wno-long-long 132 | endif 133 | 134 | # Headers as dependecies. 135 | HDRS = $(wildcard ../include/xlsxwriter/*.h) 136 | 137 | # Ojects to compile. 138 | SRCS = $(wildcard *.c) 139 | OBJS = $(patsubst %.c,%.o,$(SRCS)) 140 | SOBJS = $(patsubst %.c,%.so,$(SRCS)) 141 | TOBJS = $(patsubst %.c,%.to,$(SRCS)) 142 | # End of OBJS 143 | 144 | # Build the object files and the libraries. 145 | all : $(LIBXLSXWRITER_A) $(LIBXLSXWRITER_SO) 146 | $(Q)cp $(LIBXLSXWRITER_A) $(LIBXLSXWRITER_SO) ../lib 147 | 148 | ifeq ($(UNAME), Darwin) 149 | $(Q)rm -f ../lib/libxlsxwriter.dylib 150 | $(Q)ln -s $(LIBXLSXWRITER_SO) ../lib/libxlsxwriter.dylib 151 | endif 152 | 153 | ifneq ($(UNAME), Darwin) 154 | $(Q)rm -f ../lib/libxlsxwriter.so 155 | $(Q)ln -s $(LIBXLSXWRITER_SO) ../lib/libxlsxwriter.so 156 | endif 157 | 158 | test_lib : libxlsxwriter_test.a 159 | 160 | # The static library. 161 | $(LIBXLSXWRITER_A) : $(OBJS) 162 | $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_OBJ) $(TMPFILEPLUS_OBJ) $(DTOA_LIB_OBJ) $(MD5_OBJ) $^ 163 | 164 | # The dynamic library. 165 | ifeq ($(findstring m32,$(CFLAGS)),m32) 166 | ARCH = -m32 167 | endif 168 | 169 | $(LIBXLSXWRITER_SO) : $(SOBJS) 170 | $(Q)$(CC) $(LDFLAGS) $(SOFLAGS) $(ARCH) $(TARGET_ARCH) -o $@ $(MINIZIP_SO) $(TMPFILEPLUS_SO) $(MD5_SO) $(DTOA_LIB_SO) $^ $(LIBS) 171 | 172 | # The test library. 173 | $(LIBXLSXWRITER_TO) : $(TOBJS) 174 | $(Q)$(AR) $(ARFLAGS) $@ $(MINIZIP_OBJ) $(TMPFILEPLUS_OBJ) $(DTOA_LIB_SO) $(MD5_OBJ) $^ 175 | 176 | # Minimal target for quick compile without creating the libs. 177 | test_compile : $(OBJS) 178 | 179 | # Targets for the object files. 180 | %.o : %.c $(HDRS) 181 | $(Q)$(CC) -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) $(TARGET_ARCH) $(GCOV) -c $< 182 | 183 | %.so : %.c $(HDRS) 184 | $(Q)$(CC) $(FPIC) -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) $(TARGET_ARCH) $(GCOV) -c $< -o $@ 185 | 186 | %.to : %.c $(HDRS) 187 | $(Q)$(CC) -g $(OPT_LEVEL) -DTESTING -I$(INC_DIR) $(CFLAGS) $(CXXFLAGS) $(GCOV) -c $< -o $@ 188 | 189 | 190 | # Clean up any temp/build files. 191 | clean : 192 | $(Q)rm -f *.o *.a *.so *.so.* *.to *.dylib *.dll *.gcno *.gcda 193 | -------------------------------------------------------------------------------- /libxlsxwriter/src/custom.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * custom - A library for creating Excel custom property files. 3 | * 4 | * Used in conjunction with the libxlsxwriter library. 5 | * 6 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 7 | * 8 | */ 9 | 10 | #include "xlsxwriter/xmlwriter.h" 11 | #include "xlsxwriter/custom.h" 12 | #include "xlsxwriter/utility.h" 13 | 14 | /* 15 | * Forward declarations. 16 | */ 17 | 18 | /***************************************************************************** 19 | * 20 | * Private functions. 21 | * 22 | ****************************************************************************/ 23 | 24 | /* 25 | * Create a new custom object. 26 | */ 27 | lxw_custom * 28 | lxw_custom_new(void) 29 | { 30 | lxw_custom *custom = calloc(1, sizeof(lxw_custom)); 31 | GOTO_LABEL_ON_MEM_ERROR(custom, mem_error); 32 | 33 | return custom; 34 | 35 | mem_error: 36 | lxw_custom_free(custom); 37 | return NULL; 38 | } 39 | 40 | /* 41 | * Free a custom object. 42 | */ 43 | void 44 | lxw_custom_free(lxw_custom *custom) 45 | { 46 | if (!custom) 47 | return; 48 | 49 | free(custom); 50 | } 51 | 52 | /***************************************************************************** 53 | * 54 | * XML functions. 55 | * 56 | ****************************************************************************/ 57 | 58 | /* 59 | * Write the XML declaration. 60 | */ 61 | STATIC void 62 | _custom_xml_declaration(lxw_custom *self) 63 | { 64 | lxw_xml_declaration(self->file); 65 | } 66 | 67 | /* 68 | * Write the element. 69 | */ 70 | STATIC void 71 | _chart_write_vt_lpwstr(lxw_custom *self, char *value) 72 | { 73 | lxw_xml_data_element(self->file, "vt:lpwstr", value, NULL); 74 | } 75 | 76 | /* 77 | * Write the element. 78 | */ 79 | STATIC void 80 | _chart_write_vt_r_8(lxw_custom *self, double value) 81 | { 82 | char data[LXW_ATTR_32]; 83 | 84 | lxw_sprintf_dbl(data, value); 85 | 86 | lxw_xml_data_element(self->file, "vt:r8", data, NULL); 87 | } 88 | 89 | /* 90 | * Write the element. 91 | */ 92 | STATIC void 93 | _custom_write_vt_i_4(lxw_custom *self, int32_t value) 94 | { 95 | char data[LXW_ATTR_32]; 96 | 97 | lxw_snprintf(data, LXW_ATTR_32, "%d", value); 98 | 99 | lxw_xml_data_element(self->file, "vt:i4", data, NULL); 100 | } 101 | 102 | /* 103 | * Write the element. 104 | */ 105 | STATIC void 106 | _custom_write_vt_bool(lxw_custom *self, uint8_t value) 107 | { 108 | if (value) 109 | lxw_xml_data_element(self->file, "vt:bool", "true", NULL); 110 | else 111 | lxw_xml_data_element(self->file, "vt:bool", "false", NULL); 112 | } 113 | 114 | /* 115 | * Write the element. 116 | */ 117 | STATIC void 118 | _custom_write_vt_filetime(lxw_custom *self, lxw_datetime *datetime) 119 | { 120 | char data[LXW_DATETIME_LENGTH]; 121 | 122 | lxw_snprintf(data, LXW_DATETIME_LENGTH, "%4d-%02d-%02dT%02d:%02d:%02dZ", 123 | datetime->year, datetime->month, datetime->day, 124 | datetime->hour, datetime->min, (int) datetime->sec); 125 | 126 | lxw_xml_data_element(self->file, "vt:filetime", data, NULL); 127 | } 128 | 129 | /* 130 | * Write the element. 131 | */ 132 | STATIC void 133 | _chart_write_custom_property(lxw_custom *self, 134 | lxw_custom_property *custom_property) 135 | { 136 | struct xml_attribute_list attributes; 137 | struct xml_attribute *attribute; 138 | char fmtid[] = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"; 139 | 140 | self->pid++; 141 | 142 | LXW_INIT_ATTRIBUTES(); 143 | LXW_PUSH_ATTRIBUTES_STR("fmtid", fmtid); 144 | LXW_PUSH_ATTRIBUTES_INT("pid", self->pid + 1); 145 | LXW_PUSH_ATTRIBUTES_STR("name", custom_property->name); 146 | 147 | lxw_xml_start_tag(self->file, "property", &attributes); 148 | 149 | if (custom_property->type == LXW_CUSTOM_STRING) { 150 | /* Write the vt:lpwstr element. */ 151 | _chart_write_vt_lpwstr(self, custom_property->u.string); 152 | } 153 | else if (custom_property->type == LXW_CUSTOM_DOUBLE) { 154 | /* Write the vt:r8 element. */ 155 | _chart_write_vt_r_8(self, custom_property->u.number); 156 | } 157 | else if (custom_property->type == LXW_CUSTOM_INTEGER) { 158 | /* Write the vt:i4 element. */ 159 | _custom_write_vt_i_4(self, custom_property->u.integer); 160 | } 161 | else if (custom_property->type == LXW_CUSTOM_BOOLEAN) { 162 | /* Write the vt:bool element. */ 163 | _custom_write_vt_bool(self, custom_property->u.boolean); 164 | } 165 | else if (custom_property->type == LXW_CUSTOM_DATETIME) { 166 | /* Write the vt:filetime element. */ 167 | _custom_write_vt_filetime(self, &custom_property->u.datetime); 168 | } 169 | 170 | lxw_xml_end_tag(self->file, "property"); 171 | 172 | LXW_FREE_ATTRIBUTES(); 173 | } 174 | 175 | /* 176 | * Write the element. 177 | */ 178 | STATIC void 179 | _write_custom_properties(lxw_custom *self) 180 | { 181 | struct xml_attribute_list attributes; 182 | struct xml_attribute *attribute; 183 | char xmlns[] = LXW_SCHEMA_OFFICEDOC "/custom-properties"; 184 | char xmlns_vt[] = LXW_SCHEMA_OFFICEDOC "/docPropsVTypes"; 185 | lxw_custom_property *custom_property; 186 | 187 | LXW_INIT_ATTRIBUTES(); 188 | LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns); 189 | LXW_PUSH_ATTRIBUTES_STR("xmlns:vt", xmlns_vt); 190 | 191 | lxw_xml_start_tag(self->file, "Properties", &attributes); 192 | 193 | STAILQ_FOREACH(custom_property, self->custom_properties, list_pointers) { 194 | _chart_write_custom_property(self, custom_property); 195 | } 196 | 197 | LXW_FREE_ATTRIBUTES(); 198 | } 199 | 200 | /***************************************************************************** 201 | * 202 | * XML file assembly functions. 203 | * 204 | ****************************************************************************/ 205 | 206 | /* 207 | * Assemble and write the XML file. 208 | */ 209 | void 210 | lxw_custom_assemble_xml_file(lxw_custom *self) 211 | { 212 | /* Write the XML declaration. */ 213 | _custom_xml_declaration(self); 214 | 215 | _write_custom_properties(self); 216 | 217 | lxw_xml_end_tag(self->file, "Properties"); 218 | } 219 | 220 | /***************************************************************************** 221 | * 222 | * Public functions. 223 | * 224 | ****************************************************************************/ 225 | -------------------------------------------------------------------------------- /libxlsxwriter/src/hash_table.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * hash_table - Hash table functions for libxlsxwriter. 3 | * 4 | * Used in conjunction with the libxlsxwriter library. 5 | * 6 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 7 | * 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "xlsxwriter/hash_table.h" 15 | 16 | /* 17 | * Calculate the hash key using the FNV function. See: 18 | * http://en.wikipedia.org/wiki/Fowler-Noll-Vo_hash_function 19 | */ 20 | STATIC size_t 21 | _generate_hash_key(void *data, size_t data_len, size_t num_buckets) 22 | { 23 | unsigned char *p = data; 24 | size_t hash = 2166136261U; 25 | size_t i; 26 | 27 | for (i = 0; i < data_len; i++) 28 | hash = (hash * 16777619) ^ p[i]; 29 | 30 | return hash % num_buckets; 31 | } 32 | 33 | /* 34 | * Check if an element exists in the hash table and return a pointer 35 | * to it if it does. 36 | */ 37 | lxw_hash_element * 38 | lxw_hash_key_exists(lxw_hash_table *lxw_hash, void *key, size_t key_len) 39 | { 40 | size_t hash_key = _generate_hash_key(key, key_len, lxw_hash->num_buckets); 41 | struct lxw_hash_bucket_list *list; 42 | lxw_hash_element *element; 43 | 44 | if (!lxw_hash->buckets[hash_key]) { 45 | /* The key isn't in the LXW_HASH hash table. */ 46 | return NULL; 47 | } 48 | else { 49 | /* The key is already in the table or there is a hash collision. */ 50 | list = lxw_hash->buckets[hash_key]; 51 | 52 | /* Iterate over the keys in the bucket's linked list. */ 53 | SLIST_FOREACH(element, list, lxw_hash_list_pointers) { 54 | if (memcmp(element->key, key, key_len) == 0) { 55 | /* The key already exists in the table. */ 56 | return element; 57 | } 58 | } 59 | 60 | /* Key doesn't exist in the list so this is a hash collision. */ 61 | return NULL; 62 | } 63 | } 64 | 65 | /* 66 | * Insert or update a value in the LXW_HASH table based on a key 67 | * and return a pointer to the new or updated element. 68 | */ 69 | lxw_hash_element * 70 | lxw_insert_hash_element(lxw_hash_table *lxw_hash, void *key, void *value, 71 | size_t key_len) 72 | { 73 | size_t hash_key = _generate_hash_key(key, key_len, lxw_hash->num_buckets); 74 | struct lxw_hash_bucket_list *list = NULL; 75 | lxw_hash_element *element = NULL; 76 | 77 | if (!lxw_hash->buckets[hash_key]) { 78 | /* The key isn't in the LXW_HASH hash table. */ 79 | 80 | /* Create a linked list in the bucket to hold the lxw_hash keys. */ 81 | list = calloc(1, sizeof(struct lxw_hash_bucket_list)); 82 | GOTO_LABEL_ON_MEM_ERROR(list, mem_error1); 83 | 84 | /* Initialize the bucket linked list. */ 85 | SLIST_INIT(list); 86 | 87 | /* Create an lxw_hash element to add to the linked list. */ 88 | element = calloc(1, sizeof(lxw_hash_element)); 89 | GOTO_LABEL_ON_MEM_ERROR(element, mem_error1); 90 | 91 | /* Store the key and value. */ 92 | element->key = key; 93 | element->value = value; 94 | 95 | /* Add the lxw_hash element to the bucket's linked list. */ 96 | SLIST_INSERT_HEAD(list, element, lxw_hash_list_pointers); 97 | 98 | /* Also add it to the insertion order linked list. */ 99 | STAILQ_INSERT_TAIL(lxw_hash->order_list, element, 100 | lxw_hash_order_pointers); 101 | 102 | /* Store the bucket list at the hash index. */ 103 | lxw_hash->buckets[hash_key] = list; 104 | 105 | lxw_hash->used_buckets++; 106 | lxw_hash->unique_count++; 107 | 108 | return element; 109 | } 110 | else { 111 | /* The key is already in the table or there is a hash collision. */ 112 | list = lxw_hash->buckets[hash_key]; 113 | 114 | /* Iterate over the keys in the bucket's linked list. */ 115 | SLIST_FOREACH(element, list, lxw_hash_list_pointers) { 116 | if (memcmp(element->key, key, key_len) == 0) { 117 | /* The key already exists in the table. Update the value. */ 118 | if (lxw_hash->free_value) 119 | free(element->value); 120 | 121 | element->value = value; 122 | return element; 123 | } 124 | } 125 | 126 | /* Key doesn't exist in the list so this is a hash collision. 127 | * Create an lxw_hash element to add to the linked list. */ 128 | element = calloc(1, sizeof(lxw_hash_element)); 129 | GOTO_LABEL_ON_MEM_ERROR(element, mem_error2); 130 | 131 | /* Store the key and value. */ 132 | element->key = key; 133 | element->value = value; 134 | 135 | /* Add the lxw_hash element to the bucket linked list. */ 136 | SLIST_INSERT_HEAD(list, element, lxw_hash_list_pointers); 137 | 138 | /* Also add it to the insertion order linked list. */ 139 | STAILQ_INSERT_TAIL(lxw_hash->order_list, element, 140 | lxw_hash_order_pointers); 141 | 142 | lxw_hash->unique_count++; 143 | 144 | return element; 145 | } 146 | 147 | mem_error1: 148 | free(list); 149 | 150 | mem_error2: 151 | free(element); 152 | return NULL; 153 | } 154 | 155 | /* 156 | * Create a new LXW_HASH hash table object. 157 | */ 158 | lxw_hash_table * 159 | lxw_hash_new(uint32_t num_buckets, uint8_t free_key, uint8_t free_value) 160 | { 161 | /* Create the new hash table. */ 162 | lxw_hash_table *lxw_hash = calloc(1, sizeof(lxw_hash_table)); 163 | RETURN_ON_MEM_ERROR(lxw_hash, NULL); 164 | 165 | lxw_hash->free_key = free_key; 166 | lxw_hash->free_value = free_value; 167 | 168 | /* Add the lxw_hash element buckets. */ 169 | lxw_hash->buckets = 170 | calloc(num_buckets, sizeof(struct lxw_hash_bucket_list *)); 171 | GOTO_LABEL_ON_MEM_ERROR(lxw_hash->buckets, mem_error); 172 | 173 | /* Add a list for tracking the insertion order. */ 174 | lxw_hash->order_list = calloc(1, sizeof(struct lxw_hash_order_list)); 175 | GOTO_LABEL_ON_MEM_ERROR(lxw_hash->order_list, mem_error); 176 | 177 | /* Initialize the order list. */ 178 | STAILQ_INIT(lxw_hash->order_list); 179 | 180 | /* Store the number of buckets to calculate the load factor. */ 181 | lxw_hash->num_buckets = num_buckets; 182 | 183 | return lxw_hash; 184 | 185 | mem_error: 186 | lxw_hash_free(lxw_hash); 187 | return NULL; 188 | } 189 | 190 | /* 191 | * Free the LXW_HASH hash table object. 192 | */ 193 | void 194 | lxw_hash_free(lxw_hash_table *lxw_hash) 195 | { 196 | size_t i; 197 | lxw_hash_element *element; 198 | lxw_hash_element *element_temp; 199 | 200 | if (!lxw_hash) 201 | return; 202 | 203 | /* Free the lxw_hash_elements and data using the ordered linked list. */ 204 | if (lxw_hash->order_list) { 205 | STAILQ_FOREACH_SAFE(element, lxw_hash->order_list, 206 | lxw_hash_order_pointers, element_temp) { 207 | if (lxw_hash->free_key) 208 | free(element->key); 209 | if (lxw_hash->free_value) 210 | free(element->value); 211 | free(element); 212 | } 213 | } 214 | 215 | /* Free the buckets from the hash table. */ 216 | for (i = 0; i < lxw_hash->num_buckets; i++) { 217 | free(lxw_hash->buckets[i]); 218 | } 219 | 220 | free(lxw_hash->order_list); 221 | free(lxw_hash->buckets); 222 | free(lxw_hash); 223 | } 224 | -------------------------------------------------------------------------------- /libxlsxwriter/src/metadata.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * metadata - A library for creating Excel XLSX metadata files. 3 | * 4 | * Used in conjunction with the libxlsxwriter library. 5 | * 6 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 7 | * 8 | */ 9 | 10 | #include "xlsxwriter/xmlwriter.h" 11 | #include "xlsxwriter/metadata.h" 12 | #include "xlsxwriter/utility.h" 13 | 14 | /* 15 | * Forward declarations. 16 | */ 17 | 18 | /***************************************************************************** 19 | * 20 | * Private functions. 21 | * 22 | ****************************************************************************/ 23 | 24 | /* 25 | * Create a new metadata object. 26 | */ 27 | lxw_metadata * 28 | lxw_metadata_new(void) 29 | { 30 | lxw_metadata *metadata = calloc(1, sizeof(lxw_metadata)); 31 | GOTO_LABEL_ON_MEM_ERROR(metadata, mem_error); 32 | 33 | return metadata; 34 | 35 | mem_error: 36 | lxw_metadata_free(metadata); 37 | return NULL; 38 | } 39 | 40 | /* 41 | * Free a metadata object. 42 | */ 43 | void 44 | lxw_metadata_free(lxw_metadata *metadata) 45 | { 46 | if (!metadata) 47 | return; 48 | 49 | free(metadata); 50 | } 51 | 52 | /***************************************************************************** 53 | * 54 | * XML functions. 55 | * 56 | ****************************************************************************/ 57 | 58 | /* 59 | * Write the XML declaration. 60 | */ 61 | STATIC void 62 | _metadata_xml_declaration(lxw_metadata *self) 63 | { 64 | lxw_xml_declaration(self->file); 65 | } 66 | 67 | /* 68 | * Write the element. 69 | */ 70 | STATIC void 71 | _metadata_write_metadata(lxw_metadata *self) 72 | { 73 | struct xml_attribute_list attributes; 74 | struct xml_attribute *attribute; 75 | char xmlns[] = "http://schemas.openxmlformats.org/" 76 | "spreadsheetml/2006/main"; 77 | char xmlns_xda[] = "http://schemas.microsoft.com/office/" 78 | "spreadsheetml/2017/dynamicarray"; 79 | 80 | LXW_INIT_ATTRIBUTES(); 81 | LXW_PUSH_ATTRIBUTES_STR("xmlns", xmlns); 82 | LXW_PUSH_ATTRIBUTES_STR("xmlns:xda", xmlns_xda); 83 | 84 | lxw_xml_start_tag(self->file, "metadata", &attributes); 85 | 86 | LXW_FREE_ATTRIBUTES(); 87 | } 88 | 89 | /* 90 | * Write the element. 91 | */ 92 | STATIC void 93 | _metadata_write_metadata_type(lxw_metadata *self) 94 | { 95 | struct xml_attribute_list attributes; 96 | struct xml_attribute *attribute; 97 | 98 | LXW_INIT_ATTRIBUTES(); 99 | LXW_PUSH_ATTRIBUTES_STR("name", "XLDAPR"); 100 | LXW_PUSH_ATTRIBUTES_INT("minSupportedVersion", 120000); 101 | LXW_PUSH_ATTRIBUTES_INT("copy", 1); 102 | LXW_PUSH_ATTRIBUTES_INT("pasteAll", 1); 103 | LXW_PUSH_ATTRIBUTES_INT("pasteValues", 1); 104 | LXW_PUSH_ATTRIBUTES_INT("merge", 1); 105 | LXW_PUSH_ATTRIBUTES_INT("splitFirst", 1); 106 | LXW_PUSH_ATTRIBUTES_INT("rowColShift", 1); 107 | LXW_PUSH_ATTRIBUTES_INT("clearFormats", 1); 108 | LXW_PUSH_ATTRIBUTES_INT("clearComments", 1); 109 | LXW_PUSH_ATTRIBUTES_INT("assign", 1); 110 | LXW_PUSH_ATTRIBUTES_INT("coerce", 1); 111 | LXW_PUSH_ATTRIBUTES_INT("cellMeta", 1); 112 | 113 | lxw_xml_empty_tag(self->file, "metadataType", &attributes); 114 | 115 | LXW_FREE_ATTRIBUTES(); 116 | } 117 | 118 | /* 119 | * Write the element. 120 | */ 121 | STATIC void 122 | _metadata_write_metadata_types(lxw_metadata *self) 123 | { 124 | struct xml_attribute_list attributes; 125 | struct xml_attribute *attribute; 126 | 127 | LXW_INIT_ATTRIBUTES(); 128 | LXW_PUSH_ATTRIBUTES_INT("count", 1); 129 | 130 | lxw_xml_start_tag(self->file, "metadataTypes", &attributes); 131 | 132 | /* Write the metadataType element. */ 133 | _metadata_write_metadata_type(self); 134 | 135 | lxw_xml_end_tag(self->file, "metadataTypes"); 136 | 137 | LXW_FREE_ATTRIBUTES(); 138 | } 139 | 140 | /* 141 | * Write the element. 142 | */ 143 | STATIC void 144 | _metadata_write_xda_dynamic_array_properties(lxw_metadata *self) 145 | { 146 | struct xml_attribute_list attributes; 147 | struct xml_attribute *attribute; 148 | 149 | LXW_INIT_ATTRIBUTES(); 150 | LXW_PUSH_ATTRIBUTES_STR("fDynamic", "1"); 151 | LXW_PUSH_ATTRIBUTES_STR("fCollapsed", "0"); 152 | 153 | lxw_xml_empty_tag(self->file, "xda:dynamicArrayProperties", &attributes); 154 | 155 | LXW_FREE_ATTRIBUTES(); 156 | } 157 | 158 | /* 159 | * Write the element. 160 | */ 161 | STATIC void 162 | _metadata_write_ext(lxw_metadata *self) 163 | { 164 | struct xml_attribute_list attributes; 165 | struct xml_attribute *attribute; 166 | 167 | LXW_INIT_ATTRIBUTES(); 168 | LXW_PUSH_ATTRIBUTES_STR("uri", "{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}"); 169 | 170 | lxw_xml_start_tag(self->file, "ext", &attributes); 171 | 172 | /* Write the xda:dynamicArrayProperties element. */ 173 | _metadata_write_xda_dynamic_array_properties(self); 174 | 175 | lxw_xml_end_tag(self->file, "ext"); 176 | 177 | LXW_FREE_ATTRIBUTES(); 178 | } 179 | 180 | /* 181 | * Write the element. 182 | */ 183 | STATIC void 184 | _metadata_write_future_metadata(lxw_metadata *self) 185 | { 186 | struct xml_attribute_list attributes; 187 | struct xml_attribute *attribute; 188 | 189 | LXW_INIT_ATTRIBUTES(); 190 | LXW_PUSH_ATTRIBUTES_STR("name", "XLDAPR"); 191 | LXW_PUSH_ATTRIBUTES_INT("count", 1); 192 | 193 | lxw_xml_start_tag(self->file, "futureMetadata", &attributes); 194 | 195 | lxw_xml_start_tag(self->file, "bk", NULL); 196 | 197 | lxw_xml_start_tag(self->file, "extLst", NULL); 198 | 199 | /* Write the ext element. */ 200 | _metadata_write_ext(self); 201 | 202 | lxw_xml_end_tag(self->file, "extLst"); 203 | 204 | lxw_xml_end_tag(self->file, "bk"); 205 | 206 | lxw_xml_end_tag(self->file, "futureMetadata"); 207 | 208 | LXW_FREE_ATTRIBUTES(); 209 | } 210 | 211 | /* 212 | * Write the element. 213 | */ 214 | STATIC void 215 | _metadata_write_rc(lxw_metadata *self) 216 | { 217 | struct xml_attribute_list attributes; 218 | struct xml_attribute *attribute; 219 | 220 | LXW_INIT_ATTRIBUTES(); 221 | LXW_PUSH_ATTRIBUTES_STR("t", "1"); 222 | LXW_PUSH_ATTRIBUTES_STR("v", "0"); 223 | 224 | lxw_xml_empty_tag(self->file, "rc", &attributes); 225 | 226 | LXW_FREE_ATTRIBUTES(); 227 | } 228 | 229 | /* 230 | * Write the element. 231 | */ 232 | STATIC void 233 | _metadata_write_cell_metadata(lxw_metadata *self) 234 | { 235 | struct xml_attribute_list attributes; 236 | struct xml_attribute *attribute; 237 | 238 | LXW_INIT_ATTRIBUTES(); 239 | LXW_PUSH_ATTRIBUTES_STR("count", "1"); 240 | 241 | lxw_xml_start_tag(self->file, "cellMetadata", &attributes); 242 | 243 | lxw_xml_start_tag(self->file, "bk", NULL); 244 | 245 | /* Write the rc element. */ 246 | _metadata_write_rc(self); 247 | 248 | lxw_xml_end_tag(self->file, "bk"); 249 | 250 | lxw_xml_end_tag(self->file, "cellMetadata"); 251 | 252 | LXW_FREE_ATTRIBUTES(); 253 | } 254 | 255 | /***************************************************************************** 256 | * 257 | * XML file assembly functions. 258 | * 259 | ****************************************************************************/ 260 | 261 | /* 262 | * Assemble and write the XML file. 263 | */ 264 | void 265 | lxw_metadata_assemble_xml_file(lxw_metadata *self) 266 | { 267 | /* Write the XML declaration. */ 268 | _metadata_xml_declaration(self); 269 | 270 | /* Write the metadata element. */ 271 | _metadata_write_metadata(self); 272 | 273 | /* Write the metadataTypes element. */ 274 | _metadata_write_metadata_types(self); 275 | 276 | /* Write the futureMetadata element. */ 277 | _metadata_write_future_metadata(self); 278 | 279 | /* Write the cellMetadata element. */ 280 | _metadata_write_cell_metadata(self); 281 | 282 | lxw_xml_end_tag(self->file, "metadata"); 283 | } 284 | -------------------------------------------------------------------------------- /libxlsxwriter/src/relationships.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * relationships - A library for creating Excel XLSX relationships files. 3 | * 4 | * Used in conjunction with the libxlsxwriter library. 5 | * 6 | * Copyright 2014-2022, John McNamara, jmcnamara@cpan.org. See LICENSE.txt. 7 | * 8 | */ 9 | 10 | #include 11 | #include "xlsxwriter/xmlwriter.h" 12 | #include "xlsxwriter/relationships.h" 13 | #include "xlsxwriter/utility.h" 14 | 15 | /* 16 | * Forward declarations. 17 | */ 18 | 19 | /***************************************************************************** 20 | * 21 | * Private functions. 22 | * 23 | ****************************************************************************/ 24 | 25 | /* 26 | * Create a new relationships object. 27 | */ 28 | lxw_relationships * 29 | lxw_relationships_new(void) 30 | { 31 | lxw_relationships *rels = calloc(1, sizeof(lxw_relationships)); 32 | GOTO_LABEL_ON_MEM_ERROR(rels, mem_error); 33 | 34 | rels->relationships = calloc(1, sizeof(struct lxw_rel_tuples)); 35 | GOTO_LABEL_ON_MEM_ERROR(rels->relationships, mem_error); 36 | STAILQ_INIT(rels->relationships); 37 | 38 | return rels; 39 | 40 | mem_error: 41 | lxw_free_relationships(rels); 42 | return NULL; 43 | } 44 | 45 | /* 46 | * Free a relationships object. 47 | */ 48 | void 49 | lxw_free_relationships(lxw_relationships *rels) 50 | { 51 | lxw_rel_tuple *relationship; 52 | 53 | if (!rels) 54 | return; 55 | 56 | if (rels->relationships) { 57 | while (!STAILQ_EMPTY(rels->relationships)) { 58 | relationship = STAILQ_FIRST(rels->relationships); 59 | STAILQ_REMOVE_HEAD(rels->relationships, list_pointers); 60 | free(relationship->type); 61 | free(relationship->target); 62 | free(relationship->target_mode); 63 | free(relationship); 64 | } 65 | 66 | free(rels->relationships); 67 | } 68 | 69 | free(rels); 70 | } 71 | 72 | /***************************************************************************** 73 | * 74 | * XML functions. 75 | * 76 | ****************************************************************************/ 77 | 78 | /* 79 | * Write the XML declaration. 80 | */ 81 | STATIC void 82 | _relationships_xml_declaration(lxw_relationships *self) 83 | { 84 | lxw_xml_declaration(self->file); 85 | } 86 | 87 | /* 88 | * Write the element. 89 | */ 90 | STATIC void 91 | _write_relationship(lxw_relationships *self, const char *type, 92 | const char *target, const char *target_mode) 93 | { 94 | struct xml_attribute_list attributes; 95 | struct xml_attribute *attribute; 96 | char r_id[LXW_MAX_ATTRIBUTE_LENGTH] = { 0 }; 97 | 98 | self->rel_id++; 99 | lxw_snprintf(r_id, LXW_ATTR_32, "rId%d", self->rel_id); 100 | 101 | LXW_INIT_ATTRIBUTES(); 102 | LXW_PUSH_ATTRIBUTES_STR("Id", r_id); 103 | LXW_PUSH_ATTRIBUTES_STR("Type", type); 104 | LXW_PUSH_ATTRIBUTES_STR("Target", target); 105 | 106 | if (target_mode) 107 | LXW_PUSH_ATTRIBUTES_STR("TargetMode", target_mode); 108 | 109 | lxw_xml_empty_tag(self->file, "Relationship", &attributes); 110 | 111 | LXW_FREE_ATTRIBUTES(); 112 | } 113 | 114 | /* 115 | * Write the element. 116 | */ 117 | STATIC void 118 | _write_relationships(lxw_relationships *self) 119 | { 120 | struct xml_attribute_list attributes; 121 | struct xml_attribute *attribute; 122 | lxw_rel_tuple *rel; 123 | 124 | LXW_INIT_ATTRIBUTES(); 125 | LXW_PUSH_ATTRIBUTES_STR("xmlns", LXW_SCHEMA_PACKAGE); 126 | 127 | lxw_xml_start_tag(self->file, "Relationships", &attributes); 128 | 129 | STAILQ_FOREACH(rel, self->relationships, list_pointers) { 130 | _write_relationship(self, rel->type, rel->target, rel->target_mode); 131 | } 132 | 133 | LXW_FREE_ATTRIBUTES(); 134 | } 135 | 136 | /***************************************************************************** 137 | * 138 | * XML file assembly functions. 139 | * 140 | ****************************************************************************/ 141 | 142 | /* 143 | * Assemble and write the XML file. 144 | */ 145 | void 146 | lxw_relationships_assemble_xml_file(lxw_relationships *self) 147 | { 148 | /* Write the XML declaration. */ 149 | _relationships_xml_declaration(self); 150 | 151 | _write_relationships(self); 152 | 153 | /* Close the relationships tag. */ 154 | lxw_xml_end_tag(self->file, "Relationships"); 155 | } 156 | 157 | /* 158 | * Add a generic container relationship to XLSX .rels xml files. 159 | */ 160 | STATIC void 161 | _add_relationship(lxw_relationships *self, const char *schema, 162 | const char *type, const char *target, 163 | const char *target_mode) 164 | { 165 | lxw_rel_tuple *relationship; 166 | 167 | if (!schema || !type || !target) 168 | return; 169 | 170 | relationship = calloc(1, sizeof(lxw_rel_tuple)); 171 | GOTO_LABEL_ON_MEM_ERROR(relationship, mem_error); 172 | 173 | relationship->type = calloc(1, LXW_MAX_ATTRIBUTE_LENGTH); 174 | GOTO_LABEL_ON_MEM_ERROR(relationship->type, mem_error); 175 | 176 | /* Add the schema to the relationship type. */ 177 | lxw_snprintf(relationship->type, LXW_MAX_ATTRIBUTE_LENGTH, "%s%s", 178 | schema, type); 179 | 180 | relationship->target = lxw_strdup(target); 181 | GOTO_LABEL_ON_MEM_ERROR(relationship->target, mem_error); 182 | 183 | if (target_mode) { 184 | relationship->target_mode = lxw_strdup(target_mode); 185 | GOTO_LABEL_ON_MEM_ERROR(relationship->target_mode, mem_error); 186 | } 187 | 188 | STAILQ_INSERT_TAIL(self->relationships, relationship, list_pointers); 189 | 190 | return; 191 | 192 | mem_error: 193 | if (relationship) { 194 | free(relationship->type); 195 | free(relationship->target); 196 | free(relationship->target_mode); 197 | free(relationship); 198 | } 199 | } 200 | 201 | /***************************************************************************** 202 | * 203 | * Public functions. 204 | * 205 | ****************************************************************************/ 206 | 207 | /* 208 | * Add a document relationship to XLSX .rels xml files. 209 | */ 210 | void 211 | lxw_add_document_relationship(lxw_relationships *self, const char *type, 212 | const char *target) 213 | { 214 | _add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, NULL); 215 | } 216 | 217 | /* 218 | * Add a package relationship to XLSX .rels xml files. 219 | */ 220 | void 221 | lxw_add_package_relationship(lxw_relationships *self, const char *type, 222 | const char *target) 223 | { 224 | _add_relationship(self, LXW_SCHEMA_PACKAGE, type, target, NULL); 225 | } 226 | 227 | /* 228 | * Add a MS schema package relationship to XLSX .rels xml files. 229 | */ 230 | void 231 | lxw_add_ms_package_relationship(lxw_relationships *self, const char *type, 232 | const char *target) 233 | { 234 | _add_relationship(self, LXW_SCHEMA_MS, type, target, NULL); 235 | } 236 | 237 | /* 238 | * Add a worksheet relationship to sheet .rels xml files. 239 | */ 240 | void 241 | lxw_add_worksheet_relationship(lxw_relationships *self, const char *type, 242 | const char *target, const char *target_mode) 243 | { 244 | _add_relationship(self, LXW_SCHEMA_DOCUMENT, type, target, target_mode); 245 | } 246 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/dtoa/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Simplied Makefile to build the emyg_dtoa library for libxlsxwriter. 4 | # 5 | 6 | # Keep the output quiet by default. 7 | Q=@ 8 | ifdef V 9 | Q= 10 | endif 11 | 12 | UNAME := $(shell uname) 13 | 14 | # Check for MinGW/MinGW64/Cygwin environments. 15 | ifneq (,$(findstring MINGW, $(UNAME))) 16 | MING_LIKE = y 17 | endif 18 | ifneq (,$(findstring MSYS, $(UNAME))) 19 | MING_LIKE = y 20 | endif 21 | ifneq (,$(findstring CYGWIN, $(UNAME))) 22 | MING_LIKE = y 23 | endif 24 | 25 | FPIC = -fPIC 26 | 27 | # Change make options on MinGW/MinGW64/Cygwin. 28 | ifdef MING_LIKE 29 | FPIC = 30 | CC = gcc 31 | endif 32 | 33 | all: emyg_dtoa.o emyg_dtoa.so 34 | 35 | %.o : %.c 36 | $(Q)$(CC) -c $(CFLAGS) $< 37 | 38 | %.so : %.c 39 | $(Q)$(CC) $(FPIC) -c $(CFLAGS) $< -o $@ 40 | 41 | clean: 42 | $(Q)rm -f *.o *.so 43 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/dtoa/emyg_dtoa.h: -------------------------------------------------------------------------------- 1 | /* emyg_dtoa.h 2 | ** Copyright (C) 2015 Doug Currie 3 | ** based on dtoa_milo.h 4 | ** Copyright (C) 2014 Milo Yip 5 | ** 6 | ** Permission is hereby granted, free of charge, to any person obtaining a copy 7 | ** of this software and associated documentation files (the "Software"), to deal 8 | ** in the Software without restriction, including without limitation the rights 9 | ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | ** copies of the Software, and to permit persons to whom the Software is 11 | ** furnished to do so, subject to the following conditions: 12 | ** 13 | ** The above copyright notice and this permission notice shall be included in 14 | ** all copies or substantial portions of the Software. 15 | ** 16 | ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | ** THE SOFTWARE. 23 | */ 24 | 25 | /* Source from https://github.com/miloyip/dtoa-benchmark */ 26 | void emyg_dtoa (double value, char* buffer); 27 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/md5/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Simplied Makefile to build the openwall md5 library for libxlsxwriter. 4 | # 5 | 6 | # Keep the output quiet by default. 7 | Q=@ 8 | ifdef V 9 | Q= 10 | endif 11 | 12 | UNAME := $(shell uname) 13 | 14 | # Check for MinGW/MinGW64/Cygwin environments. 15 | ifneq (,$(findstring MINGW, $(UNAME))) 16 | MING_LIKE = y 17 | endif 18 | ifneq (,$(findstring MSYS, $(UNAME))) 19 | MING_LIKE = y 20 | endif 21 | ifneq (,$(findstring CYGWIN, $(UNAME))) 22 | MING_LIKE = y 23 | endif 24 | 25 | FPIC = -fPIC 26 | 27 | # Change make options on MinGW/MinGW64/Cygwin. 28 | ifdef MING_LIKE 29 | FPIC = 30 | CC = gcc 31 | endif 32 | 33 | all: md5.o md5.so 34 | 35 | %.o : %.c 36 | $(Q)$(CC) -c $(CFLAGS) $(TARGET_ARCH) $< 37 | 38 | %.so : %.c 39 | $(Q)$(CC) $(FPIC) -c $(CFLAGS) $(TARGET_ARCH) $< -o $@ 40 | 41 | clean: 42 | $(Q)rm -f *.o *.so 43 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/md5/md5.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc. 3 | * MD5 Message-Digest Algorithm (RFC 1321). 4 | * 5 | * Homepage: 6 | * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 7 | * 8 | * Author: 9 | * Alexander Peslyak, better known as Solar Designer 10 | * 11 | * This software was written by Alexander Peslyak in 2001. No copyright is 12 | * claimed, and the software is hereby placed in the public domain. 13 | * In case this attempt to disclaim copyright and place the software in the 14 | * public domain is deemed null and void, then the software is 15 | * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the 16 | * general public under the following terms: 17 | * 18 | * Redistribution and use in source and binary forms, with or without 19 | * modification, are permitted. 20 | * 21 | * There's ABSOLUTELY NO WARRANTY, express or implied. 22 | * 23 | * See md5.c for more information. 24 | */ 25 | 26 | #ifdef HAVE_OPENSSL 27 | #include 28 | #elif !defined(_MD5_H) 29 | #define _MD5_H 30 | 31 | /* Any 32-bit or wider unsigned integer data type will do */ 32 | typedef unsigned int MD5_u32plus; 33 | 34 | typedef struct { 35 | MD5_u32plus lo, hi; 36 | MD5_u32plus a, b, c, d; 37 | unsigned char buffer[64]; 38 | MD5_u32plus block[16]; 39 | } MD5_CTX; 40 | 41 | extern void MD5_Init(MD5_CTX *ctx); 42 | extern void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size); 43 | extern void MD5_Final(unsigned char *result, MD5_CTX *ctx); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Simplied Makefile to build the minizip objects for the libxlsxwriter library. 4 | # 5 | 6 | # Keep the output quiet by default. 7 | Q=@ 8 | ifdef V 9 | Q= 10 | endif 11 | 12 | UNAME := $(shell uname -sr) 13 | 14 | # Check for MinGW/MinGW64/Cygwin environments. 15 | ifneq (,$(findstring MINGW, $(UNAME))) 16 | MING_LIKE = y 17 | endif 18 | ifneq (,$(findstring MSYS, $(UNAME))) 19 | MING_LIKE = y 20 | endif 21 | ifneq (,$(findstring CYGWIN, $(UNAME))) 22 | MING_LIKE = y 23 | endif 24 | 25 | FPIC = -fPIC 26 | CFLAGS += -O3 -DNOCRYPT -DNOUNCRYPT 27 | 28 | # Change make options on MinGW/MinGW64/Cygwin. 29 | ifdef MING_LIKE 30 | FPIC = 31 | CC = gcc 32 | CFLAGS += -DUSE_FILE32API 33 | endif 34 | 35 | all: ioapi.o zip.o ioapi.so zip.so 36 | 37 | %.o : %.c 38 | $(Q)$(CC) -c $(CFLAGS) $(TARGET_ARCH) $< 39 | 40 | %.so : %.c 41 | $(Q)$(CC) $(FPIC) -c $(CFLAGS) $(TARGET_ARCH) $< -o $@ 42 | 43 | clean: 44 | $(Q)rm -f *.o *.so 45 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/Makefile.am: -------------------------------------------------------------------------------- 1 | lib_LTLIBRARIES = libminizip.la 2 | 3 | if COND_DEMOS 4 | bin_PROGRAMS = miniunzip minizip 5 | endif 6 | 7 | zlib_top_srcdir = $(top_srcdir)/../.. 8 | zlib_top_builddir = $(top_builddir)/../.. 9 | 10 | AM_CPPFLAGS = -I$(zlib_top_srcdir) 11 | AM_LDFLAGS = -L$(zlib_top_builddir) 12 | 13 | if WIN32 14 | iowin32_src = iowin32.c 15 | iowin32_h = iowin32.h 16 | endif 17 | 18 | libminizip_la_SOURCES = \ 19 | ioapi.c \ 20 | mztools.c \ 21 | unzip.c \ 22 | zip.c \ 23 | ${iowin32_src} 24 | 25 | libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz 26 | 27 | minizip_includedir = $(includedir)/minizip 28 | minizip_include_HEADERS = \ 29 | crypt.h \ 30 | ioapi.h \ 31 | mztools.h \ 32 | unzip.h \ 33 | zip.h \ 34 | ${iowin32_h} 35 | 36 | pkgconfigdir = $(libdir)/pkgconfig 37 | pkgconfig_DATA = minizip.pc 38 | 39 | EXTRA_PROGRAMS = miniunzip minizip 40 | 41 | miniunzip_SOURCES = miniunz.c 42 | miniunzip_LDADD = libminizip.la 43 | 44 | minizip_SOURCES = minizip.c 45 | minizip_LDADD = libminizip.la -lz 46 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/Makefile.orig: -------------------------------------------------------------------------------- 1 | CC=cc 2 | CFLAGS := $(CFLAGS) -O -I../.. 3 | 4 | UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a 5 | ZIP_OBJS = minizip.o zip.o ioapi.o ../../libz.a 6 | 7 | .c.o: 8 | $(CC) -c $(CFLAGS) $*.c 9 | 10 | all: miniunz minizip 11 | 12 | miniunz: $(UNZ_OBJS) 13 | $(CC) $(CFLAGS) -o $@ $(UNZ_OBJS) 14 | 15 | minizip: $(ZIP_OBJS) 16 | $(CC) $(CFLAGS) -o $@ $(ZIP_OBJS) 17 | 18 | test: miniunz minizip 19 | @rm -f test.* 20 | @echo hello hello hello > test.txt 21 | ./minizip test test.txt 22 | ./miniunz -l test.zip 23 | @mv test.txt test.old 24 | ./miniunz test.zip 25 | @cmp test.txt test.old 26 | @rm -f test.* 27 | 28 | clean: 29 | /bin/rm -f *.o *~ minizip miniunz test.* 30 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/MiniZip64_Changes.txt: -------------------------------------------------------------------------------- 1 | 2 | MiniZip 1.1 was derived from MiniZip at version 1.01f 3 | 4 | Change in 1.0 (Okt 2009) 5 | - **TODO - Add history** 6 | 7 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/MiniZip64_info.txt: -------------------------------------------------------------------------------- 1 | MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson 2 | 3 | Introduction 4 | --------------------- 5 | MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html ) 6 | 7 | When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0. 8 | All possible work was done for compatibility. 9 | 10 | 11 | Background 12 | --------------------- 13 | When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 14 | support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ ) 15 | 16 | That was used as a starting point. And after that ZIP64 support was added to zip.c 17 | some refactoring and code cleanup was also done. 18 | 19 | 20 | Changed from MiniZip 1.0 to MiniZip 1.1 21 | --------------------------------------- 22 | * Added ZIP64 support for unzip ( by Even Rouault ) 23 | * Added ZIP64 support for zip ( by Mathias Svensson ) 24 | * Reverted some changed that Even Rouault did. 25 | * Bunch of patches received from Gulles Vollant that he received for MiniZip from various users. 26 | * Added unzip patch for BZIP Compression method (patch create by Daniel Borca) 27 | * Added BZIP Compress method for zip 28 | * Did some refactoring and code cleanup 29 | 30 | 31 | Credits 32 | 33 | Gilles Vollant - Original MiniZip author 34 | Even Rouault - ZIP64 unzip Support 35 | Daniel Borca - BZip Compression method support in unzip 36 | Mathias Svensson - ZIP64 zip support 37 | Mathias Svensson - BZip Compression method support in zip 38 | 39 | Resources 40 | 41 | ZipLayout http://result42.com/projects/ZipFileLayout 42 | Command line tool for Windows that shows the layout and information of the headers in a zip archive. 43 | Used when debugging and validating the creation of zip files using MiniZip64 44 | 45 | 46 | ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT 47 | Zip File specification 48 | 49 | 50 | Notes. 51 | * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined. 52 | 53 | License 54 | ---------------------------------------------------------- 55 | Condition of use and distribution are the same than zlib : 56 | 57 | This software is provided 'as-is', without any express or implied 58 | warranty. In no event will the authors be held liable for any damages 59 | arising from the use of this software. 60 | 61 | Permission is granted to anyone to use this software for any purpose, 62 | including commercial applications, and to alter it and redistribute it 63 | freely, subject to the following restrictions: 64 | 65 | 1. The origin of this software must not be misrepresented; you must not 66 | claim that you wrote the original software. If you use this software 67 | in a product, an acknowledgment in the product documentation would be 68 | appreciated but is not required. 69 | 2. Altered source versions must be plainly marked as such, and must not be 70 | misrepresented as being the original software. 71 | 3. This notice may not be removed or altered from any source distribution. 72 | 73 | ---------------------------------------------------------- 74 | 75 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/README.txt: -------------------------------------------------------------------------------- 1 | The souce files in this directory are included in libxlsxwriter from the 2 | contrib/minizip/ directory of zlib-1.2.8. 3 | 4 | The files zip.h and ioapi.h have had a small number of comments modifed from 5 | C++ to C style to avoid warnings with -pedantic -ansi. 6 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_INIT([minizip], [1.3.0], [bugzilla.redhat.com]) 5 | AC_CONFIG_SRCDIR([minizip.c]) 6 | AM_INIT_AUTOMAKE([foreign]) 7 | LT_INIT 8 | 9 | AC_MSG_CHECKING([whether to build example programs]) 10 | AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs])) 11 | AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes]) 12 | if test "$enable_demos" = yes 13 | then 14 | AC_MSG_RESULT([yes]) 15 | else 16 | AC_MSG_RESULT([no]) 17 | fi 18 | 19 | case "${host}" in 20 | *-mingw* | mingw*) 21 | WIN32="yes" 22 | ;; 23 | *) 24 | ;; 25 | esac 26 | AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"]) 27 | 28 | 29 | AC_SUBST([HAVE_UNISTD_H], [0]) 30 | AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], []) 31 | AC_CONFIG_FILES([Makefile minizip.pc]) 32 | AC_OUTPUT 33 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/crypt.h: -------------------------------------------------------------------------------- 1 | /* crypt.h -- base code for crypt/uncrypt ZIPfile 2 | 3 | 4 | Version 1.01e, February 12th, 2005 5 | 6 | Copyright (C) 1998-2005 Gilles Vollant 7 | 8 | This code is a modified version of crypting code in Infozip distribution 9 | 10 | The encryption/decryption parts of this source code (as opposed to the 11 | non-echoing password parts) were originally written in Europe. The 12 | whole source package can be freely distributed, including from the USA. 13 | (Prior to January 2000, re-export from the US was a violation of US law.) 14 | 15 | This encryption code is a direct transcription of the algorithm from 16 | Roger Schlafly, described by Phil Katz in the file appnote.txt. This 17 | file (appnote.txt) is distributed with the PKZIP program (even in the 18 | version without encryption capabilities). 19 | 20 | If you don't need crypting in your application, just define symbols 21 | NOCRYPT and NOUNCRYPT. 22 | 23 | This code support the "Traditional PKWARE Encryption". 24 | 25 | The new AES encryption added on Zip format by Winzip (see the page 26 | http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong 27 | Encryption is not supported. 28 | */ 29 | 30 | #define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) 31 | 32 | /*********************************************************************** 33 | * Return the next byte in the pseudo-random sequence 34 | */ 35 | static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab) { 36 | unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an 37 | * unpredictable manner on 16-bit systems; not a problem 38 | * with any known compiler so far, though */ 39 | 40 | (void)pcrc_32_tab; 41 | temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; 42 | return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); 43 | } 44 | 45 | /*********************************************************************** 46 | * Update the encryption keys with the next byte of plain text 47 | */ 48 | static int update_keys(unsigned long* pkeys, const z_crc_t* pcrc_32_tab, int c) { 49 | (*(pkeys+0)) = CRC32((*(pkeys+0)), c); 50 | (*(pkeys+1)) += (*(pkeys+0)) & 0xff; 51 | (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; 52 | { 53 | register int keyshift = (int)((*(pkeys+1)) >> 24); 54 | (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); 55 | } 56 | return c; 57 | } 58 | 59 | 60 | /*********************************************************************** 61 | * Initialize the encryption keys and the random header according to 62 | * the given password. 63 | */ 64 | static void init_keys(const char* passwd, unsigned long* pkeys, const z_crc_t* pcrc_32_tab) { 65 | *(pkeys+0) = 305419896L; 66 | *(pkeys+1) = 591751049L; 67 | *(pkeys+2) = 878082192L; 68 | while (*passwd != '\0') { 69 | update_keys(pkeys,pcrc_32_tab,(int)*passwd); 70 | passwd++; 71 | } 72 | } 73 | 74 | #define zdecode(pkeys,pcrc_32_tab,c) \ 75 | (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) 76 | 77 | #define zencode(pkeys,pcrc_32_tab,c,t) \ 78 | (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), (Byte)t^(c)) 79 | 80 | #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED 81 | 82 | #define RAND_HEAD_LEN 12 83 | /* "last resort" source for second part of crypt seed pattern */ 84 | # ifndef ZCR_SEED2 85 | # define ZCR_SEED2 3141592654UL /* use PI as default pattern */ 86 | # endif 87 | 88 | static unsigned crypthead(const char* passwd, /* password string */ 89 | unsigned char* buf, /* where to write header */ 90 | int bufSize, 91 | unsigned long* pkeys, 92 | const z_crc_t* pcrc_32_tab, 93 | unsigned long crcForCrypting) { 94 | unsigned n; /* index in random header */ 95 | int t; /* temporary */ 96 | int c; /* random byte */ 97 | unsigned char header[RAND_HEAD_LEN-2]; /* random header */ 98 | static unsigned calls = 0; /* ensure different random header each time */ 99 | 100 | if (bufSize> 7) & 0xff; 115 | header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); 116 | } 117 | /* Encrypt random header (last two bytes is high word of crc) */ 118 | init_keys(passwd, pkeys, pcrc_32_tab); 119 | for (n = 0; n < RAND_HEAD_LEN-2; n++) 120 | { 121 | buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); 122 | } 123 | buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); 124 | buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); 125 | return n; 126 | } 127 | 128 | #endif 129 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/ioapi.h: -------------------------------------------------------------------------------- 1 | /* ioapi.h -- IO base function header for compress/uncompress .zip 2 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 3 | 4 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 5 | 6 | Modifications for Zip64 support 7 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 8 | 9 | For more info read MiniZip_info.txt 10 | 11 | Changes 12 | 13 | Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this) 14 | Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux. 15 | More if/def section may be needed to support other platforms 16 | Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows. 17 | (but you should use iowin32.c for windows instead) 18 | 19 | */ 20 | 21 | 22 | /* Pragma added by libxlsxwriter to avoid warnings with -pedantic -ansi. */ 23 | #ifndef _WIN32 24 | #pragma GCC system_header 25 | #endif 26 | 27 | #ifndef _ZLIBIOAPI64_H 28 | #define _ZLIBIOAPI64_H 29 | 30 | #if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__)) 31 | 32 | // Linux needs this to support file operation on files larger then 4+GB 33 | // But might need better if/def to select just the platforms that needs them. 34 | 35 | #ifndef __USE_FILE_OFFSET64 36 | #define __USE_FILE_OFFSET64 37 | #endif 38 | #ifndef __USE_LARGEFILE64 39 | #define __USE_LARGEFILE64 40 | #endif 41 | #ifndef _LARGEFILE64_SOURCE 42 | #define _LARGEFILE64_SOURCE 43 | #endif 44 | #ifndef _FILE_OFFSET_BIT 45 | #define _FILE_OFFSET_BIT 64 46 | #endif 47 | 48 | #endif 49 | 50 | #include 51 | #include 52 | #include "zlib.h" 53 | 54 | #if defined(USE_FILE32API) 55 | #define fopen64 fopen 56 | #define ftello64 ftell 57 | #define fseeko64 fseek 58 | #else 59 | #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__HAIKU__) || defined(MINIZIP_FOPEN_NO_64) 60 | #define fopen64 fopen 61 | #define ftello64 ftello 62 | #define fseeko64 fseeko 63 | #endif 64 | #ifdef _MSC_VER 65 | #define fopen64 fopen 66 | #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) 67 | #define ftello64 _ftelli64 68 | #define fseeko64 _fseeki64 69 | #else // old MSC 70 | #define ftello64 ftell 71 | #define fseeko64 fseek 72 | #endif 73 | #endif 74 | #endif 75 | 76 | /* 77 | #ifndef ZPOS64_T 78 | #ifdef _WIN32 79 | #define ZPOS64_T fpos_t 80 | #else 81 | #include 82 | #define ZPOS64_T uint64_t 83 | #endif 84 | #endif 85 | */ 86 | 87 | #ifdef HAVE_MINIZIP64_CONF_H 88 | #include "mz64conf.h" 89 | #endif 90 | 91 | /* a type chosen by DEFINE */ 92 | #ifdef HAVE_64BIT_INT_CUSTOM 93 | typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; 94 | #else 95 | #ifdef HAS_STDINT_H 96 | #include "stdint.h" 97 | typedef uint64_t ZPOS64_T; 98 | #else 99 | 100 | 101 | 102 | #if defined(_MSC_VER) || defined(__BORLANDC__) 103 | typedef unsigned __int64 ZPOS64_T; 104 | #else 105 | typedef unsigned long long int ZPOS64_T; 106 | #endif 107 | #endif 108 | #endif 109 | 110 | /* Maximum unsigned 32-bit value used as placeholder for zip64 */ 111 | #ifndef MAXU32 112 | #define MAXU32 (0xffffffff) 113 | #endif 114 | 115 | #ifdef __cplusplus 116 | extern "C" { 117 | #endif 118 | 119 | 120 | #define ZLIB_FILEFUNC_SEEK_CUR (1) 121 | #define ZLIB_FILEFUNC_SEEK_END (2) 122 | #define ZLIB_FILEFUNC_SEEK_SET (0) 123 | 124 | #define ZLIB_FILEFUNC_MODE_READ (1) 125 | #define ZLIB_FILEFUNC_MODE_WRITE (2) 126 | #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) 127 | 128 | #define ZLIB_FILEFUNC_MODE_EXISTING (4) 129 | #define ZLIB_FILEFUNC_MODE_CREATE (8) 130 | 131 | 132 | #ifndef ZCALLBACK 133 | #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) 134 | #define ZCALLBACK CALLBACK 135 | #else 136 | #define ZCALLBACK 137 | #endif 138 | #endif 139 | 140 | 141 | 142 | 143 | typedef voidpf (ZCALLBACK *open_file_func) (voidpf opaque, const char* filename, int mode); 144 | typedef uLong (ZCALLBACK *read_file_func) (voidpf opaque, voidpf stream, void* buf, uLong size); 145 | typedef uLong (ZCALLBACK *write_file_func) (voidpf opaque, voidpf stream, const void* buf, uLong size); 146 | typedef int (ZCALLBACK *close_file_func) (voidpf opaque, voidpf stream); 147 | typedef int (ZCALLBACK *testerror_file_func) (voidpf opaque, voidpf stream); 148 | 149 | typedef long (ZCALLBACK *tell_file_func) (voidpf opaque, voidpf stream); 150 | typedef long (ZCALLBACK *seek_file_func) (voidpf opaque, voidpf stream, uLong offset, int origin); 151 | 152 | 153 | /* here is the "old" 32 bits structure structure */ 154 | typedef struct zlib_filefunc_def_s 155 | { 156 | open_file_func zopen_file; 157 | read_file_func zread_file; 158 | write_file_func zwrite_file; 159 | tell_file_func ztell_file; 160 | seek_file_func zseek_file; 161 | close_file_func zclose_file; 162 | testerror_file_func zerror_file; 163 | voidpf opaque; 164 | } zlib_filefunc_def; 165 | 166 | typedef ZPOS64_T (ZCALLBACK *tell64_file_func) (voidpf opaque, voidpf stream); 167 | typedef long (ZCALLBACK *seek64_file_func) (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin); 168 | typedef voidpf (ZCALLBACK *open64_file_func) (voidpf opaque, const void* filename, int mode); 169 | 170 | typedef struct zlib_filefunc64_def_s 171 | { 172 | open64_file_func zopen64_file; 173 | read_file_func zread_file; 174 | write_file_func zwrite_file; 175 | tell64_file_func ztell64_file; 176 | seek64_file_func zseek64_file; 177 | close_file_func zclose_file; 178 | testerror_file_func zerror_file; 179 | voidpf opaque; 180 | } zlib_filefunc64_def; 181 | 182 | void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def); 183 | void fill_fopen_filefunc(zlib_filefunc_def* pzlib_filefunc_def); 184 | 185 | /* now internal definition, only for zip.c and unzip.h */ 186 | typedef struct zlib_filefunc64_32_def_s 187 | { 188 | zlib_filefunc64_def zfile_func64; 189 | open_file_func zopen32_file; 190 | tell_file_func ztell32_file; 191 | seek_file_func zseek32_file; 192 | } zlib_filefunc64_32_def; 193 | 194 | 195 | #define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 196 | #define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) 197 | //#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) 198 | //#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) 199 | #define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) 200 | #define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) 201 | 202 | voidpf call_zopen64(const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode); 203 | long call_zseek64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin); 204 | ZPOS64_T call_ztell64(const zlib_filefunc64_32_def* pfilefunc,voidpf filestream); 205 | 206 | void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); 207 | 208 | #define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) 209 | #define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) 210 | #define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) 211 | 212 | #ifdef __cplusplus 213 | } 214 | #endif 215 | 216 | #endif 217 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/iowin32.h: -------------------------------------------------------------------------------- 1 | /* iowin32.h -- IO base function header for compress/uncompress .zip 2 | Version 1.1, February 14h, 2010 3 | part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html ) 4 | 5 | Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html ) 6 | 7 | Modifications for Zip64 support 8 | Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com ) 9 | 10 | For more info read MiniZip_info.txt 11 | 12 | */ 13 | 14 | #include 15 | 16 | 17 | #ifdef __cplusplus 18 | extern "C" { 19 | #endif 20 | 21 | void fill_win32_filefunc(zlib_filefunc_def* pzlib_filefunc_def); 22 | void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def); 23 | void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def); 24 | void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def); 25 | 26 | #ifdef __cplusplus 27 | } 28 | #endif 29 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/make_vms.com: -------------------------------------------------------------------------------- 1 | $ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig 2 | $ open/write zdef vmsdefs.h 3 | $ copy sys$input: zdef 4 | $ deck 5 | #define unix 6 | #define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from 7 | #define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator 8 | #define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord 9 | #define Write_EndOfCentralDirectoryRecord Write_EoDRecord 10 | $ eod 11 | $ close zdef 12 | $ copy vmsdefs.h,ioapi.h_orig ioapi.h 13 | $ cc/include=[--]/prefix=all ioapi.c 14 | $ cc/include=[--]/prefix=all miniunz.c 15 | $ cc/include=[--]/prefix=all unzip.c 16 | $ cc/include=[--]/prefix=all minizip.c 17 | $ cc/include=[--]/prefix=all zip.c 18 | $ link miniunz,unzip,ioapi,[--]libz.olb/lib 19 | $ link minizip,zip,ioapi,[--]libz.olb/lib 20 | $ mcr []minizip test minizip_info.txt 21 | $ mcr []miniunz -l test.zip 22 | $ rename minizip_info.txt; minizip_info.txt_old 23 | $ mcr []miniunz test.zip 24 | $ delete test.zip;* 25 | $exit 26 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/miniunzip.1: -------------------------------------------------------------------------------- 1 | .\" Hey, EMACS: -*- nroff -*- 2 | .TH miniunzip 1 "Nov 7, 2001" 3 | .\" Please adjust this date whenever revising the manpage. 4 | .\" 5 | .\" Some roff macros, for reference: 6 | .\" .nh disable hyphenation 7 | .\" .hy enable hyphenation 8 | .\" .ad l left justify 9 | .\" .ad b justify to both left and right margins 10 | .\" .nf disable filling 11 | .\" .fi enable filling 12 | .\" .br insert line break 13 | .\" .sp insert n+1 empty lines 14 | .\" for manpage-specific macros, see man(7) 15 | .SH NAME 16 | miniunzip - uncompress and examine ZIP archives 17 | .SH SYNOPSIS 18 | .B miniunzip 19 | .RI [ -exvlo ] 20 | zipfile [ files_to_extract ] [-d tempdir] 21 | .SH DESCRIPTION 22 | .B minizip 23 | is a simple tool which allows the extraction of compressed file 24 | archives in the ZIP format used by the MS-DOS utility PKZIP. It was 25 | written as a demonstration of the 26 | .IR zlib (3) 27 | library and therefore lack many of the features of the 28 | .IR unzip (1) 29 | program. 30 | .SH OPTIONS 31 | A number of options are supported. With the exception of 32 | .BI \-d\ tempdir 33 | these must be supplied before any 34 | other arguments and are: 35 | .TP 36 | .BI \-l\ ,\ \-\-v 37 | List the files in the archive without extracting them. 38 | .TP 39 | .B \-o 40 | Overwrite files without prompting for confirmation. 41 | .TP 42 | .B \-x 43 | Extract files (default). 44 | .PP 45 | The 46 | .I zipfile 47 | argument is the name of the archive to process. The next argument can be used 48 | to specify a single file to extract from the archive. 49 | 50 | Lastly, the following option can be specified at the end of the command-line: 51 | .TP 52 | .BI \-d\ tempdir 53 | Extract the archive in the directory 54 | .I tempdir 55 | rather than the current directory. 56 | .SH SEE ALSO 57 | .BR minizip (1), 58 | .BR zlib (3), 59 | .BR unzip (1). 60 | .SH AUTHOR 61 | This program was written by Gilles Vollant. This manual page was 62 | written by Mark Brown . The -d tempdir option 63 | was added by Dirk Eddelbuettel . 64 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/minizip.1: -------------------------------------------------------------------------------- 1 | .\" Hey, EMACS: -*- nroff -*- 2 | .TH minizip 1 "May 2, 2001" 3 | .\" Please adjust this date whenever revising the manpage. 4 | .\" 5 | .\" Some roff macros, for reference: 6 | .\" .nh disable hyphenation 7 | .\" .hy enable hyphenation 8 | .\" .ad l left justify 9 | .\" .ad b justify to both left and right margins 10 | .\" .nf disable filling 11 | .\" .fi enable filling 12 | .\" .br insert line break 13 | .\" .sp insert n+1 empty lines 14 | .\" for manpage-specific macros, see man(7) 15 | .SH NAME 16 | minizip - create ZIP archives 17 | .SH SYNOPSIS 18 | .B minizip 19 | .RI [ -o ] 20 | zipfile [ " files" ... ] 21 | .SH DESCRIPTION 22 | .B minizip 23 | is a simple tool which allows the creation of compressed file archives 24 | in the ZIP format used by the MS-DOS utility PKZIP. It was written as 25 | a demonstration of the 26 | .IR zlib (3) 27 | library and therefore lack many of the features of the 28 | .IR zip (1) 29 | program. 30 | .SH OPTIONS 31 | The first argument supplied is the name of the ZIP archive to create or 32 | .RI -o 33 | in which case it is ignored and the second argument treated as the 34 | name of the ZIP file. If the ZIP file already exists it will be 35 | overwritten. 36 | .PP 37 | Subsequent arguments specify a list of files to place in the ZIP 38 | archive. If none are specified then an empty archive will be created. 39 | .SH SEE ALSO 40 | .BR miniunzip (1), 41 | .BR zlib (3), 42 | .BR zip (1). 43 | .SH AUTHOR 44 | This program was written by Gilles Vollant. This manual page was 45 | written by Mark Brown . 46 | 47 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/minizip.pc.in: -------------------------------------------------------------------------------- 1 | prefix=@prefix@ 2 | exec_prefix=@exec_prefix@ 3 | libdir=@libdir@ 4 | includedir=@includedir@/minizip 5 | 6 | Name: minizip 7 | Description: Minizip zip file manipulation library 8 | Requires: 9 | Version: @PACKAGE_VERSION@ 10 | Libs: -L${libdir} -lminizip 11 | Libs.private: -lz 12 | Cflags: -I${includedir} 13 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/minizip/mztools.h: -------------------------------------------------------------------------------- 1 | /* 2 | Additional tools for Minizip 3 | Code: Xavier Roche '2004 4 | License: Same as ZLIB (www.gzip.org) 5 | */ 6 | 7 | #ifndef _zip_tools_H 8 | #define _zip_tools_H 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #ifndef _ZLIB_H 15 | #include "zlib.h" 16 | #endif 17 | 18 | #include "unzip.h" 19 | 20 | /* Repair a ZIP file (missing central directory) 21 | file: file to recover 22 | fileOut: output file after recovery 23 | fileOutTmp: temporary file name used for recovery 24 | */ 25 | extern int ZEXPORT unzRepair(const char* file, 26 | const char* fileOut, 27 | const char* fileOutTmp, 28 | uLong* nRecovered, 29 | uLong* bytesRecovered); 30 | 31 | 32 | #ifdef __cplusplus 33 | } 34 | #endif 35 | 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/tmpfileplus/Makefile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # 3 | # Simplied Makefile to build tmpfileplus for the libxlsxwriter library. 4 | # 5 | 6 | # Keep the output quiet by default. 7 | Q=@ 8 | ifdef V 9 | Q= 10 | endif 11 | 12 | UNAME := $(shell uname) 13 | 14 | # Check for MinGW/MinGW64/Cygwin environments. 15 | ifneq (,$(findstring MINGW, $(UNAME))) 16 | MING_LIKE = y 17 | endif 18 | ifneq (,$(findstring MSYS, $(UNAME))) 19 | MING_LIKE = y 20 | endif 21 | ifneq (,$(findstring CYGWIN, $(UNAME))) 22 | MING_LIKE = y 23 | endif 24 | 25 | FPIC = -fPIC 26 | 27 | # Change make options on MinGW/MinGW64/Cygwin. 28 | ifdef MING_LIKE 29 | FPIC = 30 | CC = gcc 31 | endif 32 | 33 | all: tmpfileplus.o tmpfileplus.so 34 | 35 | %.o : %.c 36 | $(Q)$(CC) -c $(CFLAGS) $(TARGET_ARCH) $< 37 | 38 | %.so : %.c 39 | $(Q)$(CC) $(FPIC) -c $(CFLAGS) $(TARGET_ARCH) $< -o $@ 40 | 41 | clean: 42 | $(Q)rm -f *.o *.so 43 | -------------------------------------------------------------------------------- /libxlsxwriter/third_party/tmpfileplus/tmpfileplus.h: -------------------------------------------------------------------------------- 1 | /* $Id: tmpfileplus.h $ */ 2 | /* 3 | * $Date: 2016-06-01 03:31Z $ 4 | * $Revision: 2.0.0 $ 5 | * $Author: dai $ 6 | */ 7 | 8 | /* 9 | * This Source Code Form is subject to the terms of the Mozilla Public 10 | * License, v. 2.0. If a copy of the MPL was not distributed with this 11 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. 12 | * 13 | * Copyright (c) 2012-16 David Ireland, DI Management Services Pty Ltd 14 | * . 15 | */ 16 | 17 | #if _MSC_VER > 1000 18 | #pragma once 19 | #endif 20 | 21 | #ifndef TMPFILEPLUS_H_ 22 | #define TMPFILEPLUS_H_ 23 | 24 | #include 25 | 26 | /** Create a unique temporary file. 27 | @param dir (optional) directory to create file. If NULL use default TMP directory. 28 | @param prefix (optional) prefix for file name. If NULL use "tmp.". 29 | @param pathname (optional) pointer to a buffer to receive the temp filename. 30 | Allocated using `malloc()`; user to free. Ignored if NULL. 31 | @param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing. 32 | Otherwise file is automatically deleted when closed. 33 | @return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error. 34 | @exception ENOMEM Not enough memory to allocate filename. 35 | */ 36 | FILE *tmpfileplus(const char *dir, const char *prefix, char **pathname, int keep); 37 | 38 | 39 | /** Create a unique temporary file with filename stored in a fixed-length buffer. 40 | @param dir (optional) directory to create file. If NULL use default directory. 41 | @param prefix (optional) prefix for file name. If NULL use "tmp.". 42 | @param pathnamebuf (optional) buffer to receive full pathname of temporary file. Ignored if NULL. 43 | @param pathsize Size of buffer to receive filename and its terminating null character. 44 | @param keep If `keep` is nonzero and `pathname` is not NULL, then keep the file after closing. 45 | Otherwise file is automatically deleted when closed. 46 | @return Pointer to stream opened in binary read/write (w+b) mode, or a null pointer on error. 47 | @exception E2BIG Resulting filename is too big for the buffer `pathnamebuf`. 48 | */ 49 | FILE *tmpfileplus_f(const char *dir, const char *prefix, char *pathnamebuf, size_t pathsize, int keep); 50 | 51 | #define TMPFILE_KEEP 1 52 | 53 | #endif /* end TMPFILEPLUS_H_ */ 54 | -------------------------------------------------------------------------------- /libxlsxwriter/version.txt: -------------------------------------------------------------------------------- 1 | 2023-12-29 19:18:35 +0700 e3ede9d -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | sonar.sources=. 2 | sonar.language=ruby 3 | sonar.ruby.coverage.reportPaths=coverage/.resultset.json 4 | sonar.exclusions=**/*_test.rb,**/coverage/** 5 | -------------------------------------------------------------------------------- /test/auto_width_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel text_width" do 4 | 5 | it "should calculate text width" do 6 | workbook = FastExcel.open(constant_memory: false) 7 | sheet = workbook.add_worksheet 8 | sheet.auto_width = true 9 | 10 | sheet.append_row([ 11 | "tini", 12 | "Longer", 13 | "Some longer text!", 14 | "This gem is FFI binding for libxlsxwriter C library" 15 | ]) 16 | 17 | assert_equal(sheet.calculated_column_widths, {0 => 3.52, 1 => 5.28, 2 => 14.96, 3 => 44.88}) 18 | end 19 | 20 | it "should set the default column width for an empty column on close" do 21 | workbook = FastExcel.open(constant_memory: false) 22 | sheet = workbook.add_worksheet 23 | sheet.auto_width = true 24 | 25 | sheet.append_row([ 26 | nil, 27 | "tini", 28 | "Longer", 29 | "Some longer text!", 30 | "This gem is FFI binding for libxlsxwriter C library" 31 | ]) 32 | 33 | assert_equal(sheet.calculated_column_widths, {0 => nil, 1 => 3.52, 2 => 5.28, 3 => 14.96, 4 => 44.88}) 34 | 35 | workbook.close 36 | 37 | assert_equal(sheet.calculated_column_widths, {0 => FastExcel::DEF_COL_WIDTH, 1 => 3.52, 2 => 5.28, 3 => 14.96, 4 => 44.88}) 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /test/date_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel.date_num" do 4 | 5 | it "should save correct date" do 6 | workbook = FastExcel.open("test.xlsx", constant_memory: true) 7 | worksheet = workbook.add_worksheet("Payments Report") 8 | 9 | date_format = workbook.number_format("[$-409]m/d/yy h:mm AM/PM;@") 10 | worksheet.set_column(0, 0, 20, date_format) 11 | 12 | date = DateTime.parse('2017-03-01 15:15:15 +0000').to_time 13 | 14 | worksheet.write_number(0, 0, FastExcel.date_num(date), nil) 15 | workbook.close 16 | 17 | data = parse_xlsx_as_matrix("test.xlsx") 18 | 19 | assert_equal(data[0][0].to_time, date) 20 | end 21 | 22 | end 23 | 24 | describe "FastExcel.write_value" do 25 | 26 | it "should save correct datetime" do 27 | workbook = FastExcel.open(constant_memory: true) 28 | worksheet = workbook.add_worksheet 29 | 30 | format = workbook.number_format("yyyy-mm-dd hh:mm:ss") 31 | value = DateTime.parse('2017-03-01 15:15:15 +0000') 32 | 33 | worksheet.write_value(0, 0, value, format) 34 | workbook.close 35 | 36 | data = parse_xlsx_as_matrix(workbook.filename) 37 | 38 | assert_equal(data[0][0], value) 39 | end 40 | 41 | it "should save correct date" do 42 | workbook = FastExcel.open(constant_memory: true) 43 | worksheet = workbook.add_worksheet 44 | 45 | format = workbook.number_format("yyyy-mm-dd") 46 | value = Date.parse('2017-03-01') 47 | 48 | worksheet.write_value(0, 0, value, format) 49 | workbook.close 50 | 51 | data = parse_xlsx_as_matrix(workbook.filename) 52 | 53 | assert_equal(data[0][0], value) 54 | end 55 | 56 | end 57 | -------------------------------------------------------------------------------- /test/default_format_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel default_format" do 4 | 5 | it "should set default format values on init" do 6 | workbook = FastExcel.open(default_format: { 7 | font_size: 17, 8 | font_family: "ArialFoo", 9 | bold: true 10 | }) 11 | 12 | # FastExcel.print_ffi_obj(workbook.default_format) 13 | 14 | assert_equal("ArialFoo", workbook.default_format.font_family) 15 | assert_equal(17, workbook.default_format.font_size) 16 | assert_equal(1, workbook.default_format.bold) 17 | end 18 | 19 | end 20 | -------------------------------------------------------------------------------- /test/format_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel::FormatExt align" do 4 | 5 | before do 6 | @workbook = FastExcel.open(constant_memory: true) 7 | @format = @workbook.add_format 8 | end 9 | 10 | it "should give default aligns" do 11 | assert_equal({horizontal: :align_none, vertical: :align_none}, @format.align) 12 | end 13 | 14 | it "should set align by full name" do 15 | @format.align = :align_center 16 | assert_equal({horizontal: :align_center, vertical: :align_none}, @format.align) 17 | end 18 | 19 | it "should set by string" do 20 | @format.align = "align_center" 21 | assert_equal({horizontal: :align_center, vertical: :align_none}, @format.align) 22 | end 23 | 24 | it "should set by short name" do 25 | @format.align = :center 26 | assert_equal({horizontal: :align_center, vertical: :align_none}, @format.align) 27 | end 28 | 29 | it "should set by hash" do 30 | @format.align = {v: "center", h: "center"} 31 | assert_equal({horizontal: :align_center, vertical: :align_vertical_center}, @format.align) 32 | end 33 | 34 | it "should raise exception for unknown value" do 35 | error = assert_raises(ArgumentError) do 36 | @format.align = :aaa 37 | end 38 | 39 | assert_equal(error.message, "Can not set align = :aaa, possible values are: [:align_none, :align_left, "\ 40 | ":align_center, :align_right, :align_fill, :align_justify, :align_center_across, :align_distributed, "\ 41 | ":align_vertical_top, :align_vertical_bottom, :align_vertical_center, :align_vertical_justify, :align_vertical_distributed]") 42 | end 43 | 44 | it "should raise exception for unknown hash key" do 45 | error = assert_raises(ArgumentError) do 46 | @format.align = {aaa: 1} 47 | end 48 | 49 | assert_equal(error.message, "Not allowed keys for align: [:aaa], possible keys: [:horizontal, :h, :vertical, :v]") 50 | end 51 | 52 | it "should get and set" do 53 | @format.align = {h: :center, v: :center} 54 | format2 = @workbook.add_format(align: @format.align) 55 | 56 | assert_equal({horizontal: :align_center, vertical: :align_vertical_center}, format2.align) 57 | end 58 | 59 | end 60 | 61 | 62 | describe "FastExcel::FormatExt colors" do 63 | 64 | before do 65 | workbook = FastExcel.open(constant_memory: true) 66 | @format = workbook.add_format 67 | end 68 | 69 | it "should set font color as hex num" do 70 | @format.font_color = 0xFF0000 71 | assert_equal(0xFF0000, @format.font_color) 72 | end 73 | 74 | it "should set font color as hex string" do 75 | @format.font_color = '0xFF0000' 76 | assert_equal(0xFF0000, @format.font_color) 77 | end 78 | 79 | it "should set font color as css hex string" do 80 | @format.font_color = '#FF0000' 81 | assert_equal(0xFF0000, @format.font_color) 82 | end 83 | 84 | it "should set font color as short hex string" do 85 | @format.font_color = 'FF0000' 86 | assert_equal(0xFF0000, @format.font_color) 87 | end 88 | 89 | it "should set font color as name" do 90 | @format.font_color = 'red' 91 | assert_equal(0xFF0000, @format.font_color) 92 | end 93 | 94 | it "should set font css color" do 95 | @format.font_color = 'alice_blue' 96 | assert_equal(0xF0F8FF, @format.font_color) 97 | end 98 | 99 | it "should allow to use symbol" do 100 | @format.font_color = :alice_blue 101 | assert_equal(0xF0F8FF, @format.font_color) 102 | end 103 | 104 | it "should have long method for border colors" do 105 | @format.border_bottom_color = :alice_blue 106 | assert_equal(0xF0F8FF, @format.border_bottom_color) 107 | assert_equal(0xF0F8FF, @format.bottom_color) 108 | end 109 | 110 | it "should raise for unexpected type" do 111 | error = assert_raises(ArgumentError) do 112 | @format.font_color = {aaa: 1} 113 | end 114 | 115 | if error.message =~ /=>/ 116 | assert_equal(error.message, "Can not use Hash ({:aaa=>1}) for color value, expected String or Hex Number") 117 | else 118 | assert_equal(error.message, "Can not use Hash ({aaa: 1}) for color value, expected String or Hex Number") 119 | end 120 | end 121 | 122 | it "should raise for unexpected color" do 123 | error = assert_raises(ArgumentError) do 124 | @format.font_color = :aaa 125 | end 126 | 127 | assert_equal(error.message, "Unknown color value :aaa, expected hex string or color name") 128 | end 129 | 130 | end 131 | 132 | 133 | describe "FastExcel::FormatExt border" do 134 | 135 | before do 136 | workbook = FastExcel.open(constant_memory: true) 137 | @format = workbook.add_format 138 | end 139 | 140 | it "should set border as symbol" do 141 | @format.bottom = :border_thin 142 | assert_equal(:border_thin, @format.bottom) 143 | end 144 | 145 | it "should set border as short symbol" do 146 | @format.bottom = :thin 147 | assert_equal(:border_thin, @format.bottom) 148 | end 149 | 150 | it "should set border as string" do 151 | @format.bottom = "thin" 152 | assert_equal(:border_thin, @format.bottom) 153 | end 154 | 155 | it "should set border as number" do 156 | @format.bottom = 1 157 | assert_equal(:border_thin, @format.bottom) 158 | end 159 | 160 | it "should set border with long prop name" do 161 | error = assert_raises(ArgumentError) do 162 | @format.border_bottom = :aaa 163 | end 164 | 165 | assert_equal(error.message, "Unknown value :aaa for border. Possible values: "\ 166 | "[:none, :thin, :medium, :dashed, :dotted, :thick, :double, :hair, :medium_dashed, "\ 167 | ":dash_dot, :medium_dash_dot, :dash_dot_dot, :medium_dash_dot_dot, :slant_dash_dot]") 168 | end 169 | 170 | it "should get value with long name" do 171 | @format.bottom = "thin" 172 | assert_equal(:border_thin, @format.border_bottom) 173 | end 174 | 175 | it "should define aliases" do 176 | @format.font_size = 20 177 | assert_equal(@format.font_size, 20) 178 | 179 | @format.font_name = "XXX" 180 | assert_equal(@format.font_name, "XXX") 181 | end 182 | 183 | end 184 | -------------------------------------------------------------------------------- /test/reopen_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel::Worksheet" do 4 | 5 | it "should get_worksheet_by_name" do 6 | workbook = FastExcel.open(constant_memory: false) 7 | workbook.add_worksheet("Page1") 8 | 9 | ws = workbook.get_worksheet_by_name("Page1") 10 | ws.write_row(0, ['1']) 11 | 12 | workbook.close 13 | 14 | error = assert_raises do 15 | FastExcel.open(workbook.filename, constant_memory: false) 16 | end 17 | 18 | assert_equal(error.class, ArgumentError) 19 | assert_equal(error.message, "File '#{workbook.filename}' already exists. FastExcel can not open existing files, only create new files") 20 | end 21 | 22 | end -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require "simplecov" 2 | 3 | SimpleCov.start do 4 | add_filter 'test' 5 | end 6 | 7 | require 'bundler/setup' 8 | require 'minitest/autorun' 9 | require "minitest/reporters" 10 | require 'pp' 11 | require 'date' 12 | 13 | 14 | Minitest::Reporters.use!( 15 | Minitest::Reporters::DefaultReporter.new(color: true) 16 | ) 17 | 18 | require_relative '../lib/fast_excel' 19 | 20 | def parse_xlsx(file_path) 21 | require 'roo' 22 | Roo::Excelx.new(file_path) 23 | ensure 24 | File.delete(file_path) 25 | end 26 | 27 | def get_arrays(workbook) 28 | workbook.close 29 | parse_xlsx_as_matrix(workbook.filename) 30 | end 31 | 32 | def parse_xlsx_as_array(file_path) 33 | data = parse_xlsx_as_matrix(file_path) 34 | headers = data.shift 35 | 36 | data.map do |row| 37 | Hash[ [headers, row].transpose ] 38 | end 39 | end 40 | 41 | def parse_xlsx_as_matrix(file_path) 42 | excel = parse_xlsx(file_path) 43 | 44 | sheet = excel.sheet(0) 45 | 46 | rows = [] 47 | if sheet.last_row 48 | 1.upto(sheet.last_row) do |row_number| 49 | row = 1.upto(sheet.last_column).map do |col| 50 | sheet.cell(row_number, col) 51 | end 52 | 53 | rows << row 54 | end 55 | end 56 | 57 | return rows 58 | end 59 | -------------------------------------------------------------------------------- /test/tmpfile_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel" do 4 | 5 | it "should create temporary file if filename is nil" do 6 | workbook = FastExcel.open(constant_memory: true) 7 | 8 | assert(workbook.tmp_file) 9 | assert_match(/fast_excel.xlsx$/, workbook.filename) 10 | 11 | result = workbook.read_string 12 | assert(result.size > 1000) 13 | end 14 | 15 | it "should close workbook and delete tmp file when read_string" do 16 | workbook = FastExcel.open 17 | workbook.read_string 18 | 19 | refute(File.exist?(workbook.filename)) 20 | refute(File.exist?(File.dirname(workbook.filename))) 21 | refute(workbook.is_open) 22 | end 23 | 24 | end 25 | -------------------------------------------------------------------------------- /test/validations_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel validations" do 4 | 5 | it "should raise error when duplicate sheet name" do 6 | workbook = FastExcel.open(constant_memory: true) 7 | 8 | workbook.add_worksheet("Payments Report") 9 | error = assert_raises do 10 | workbook.add_worksheet("Payments Report") 11 | end 12 | 13 | assert_equal(ArgumentError, error.class) 14 | assert_equal("Invalid worksheet name 'Payments Report': (17 - error_sheetname_already_used) Worksheet name is already in use.", error.message) 15 | end 16 | 17 | it "should not raise error when worksheet name is null" do 18 | workbook = FastExcel.open(constant_memory: true) 19 | 20 | ws1 = workbook.add_worksheet() 21 | ws2 = workbook.add_worksheet() 22 | ws2.write_value(0, 2, "aaa") 23 | 24 | assert_equal("Sheet1", ws1[:name]) 25 | assert_equal("Sheet2", ws2[:name]) 26 | end 27 | 28 | it "should raise error when the sheet name exceeds maximum length" do 29 | workbook = FastExcel.open(constant_memory: true) 30 | 31 | error = assert_raises do 32 | workbook.add_worksheet("ABCDEFGHIJKLMNOPQRSTUVWXYZ012345") 33 | end 34 | 35 | assert_equal(ArgumentError, error.class) 36 | assert_equal("Invalid worksheet name 'ABCDEFGHIJKLMNOPQRSTUVWXYZ012345': (14 - error_sheetname_length_exceeded) Worksheet name exceeds Excel's limit of 31 characters.", error.message) 37 | end 38 | 39 | it "should not raise error when the sheet name is at maximum length" do 40 | workbook = FastExcel.open(constant_memory: true) 41 | 42 | worksheet = workbook.add_worksheet("ABCDEFGHIJKLMNOPQRSTUVWXYZ01234") 43 | worksheet.append_row(["aaa", "bbb", "ccc"]) 44 | 45 | assert_equal("ABCDEFGHIJKLMNOPQRSTUVWXYZ01234", worksheet[:name]) 46 | end 47 | 48 | it "should validate using Libxlsxwriter validation" do 49 | workbook = FastExcel.open(constant_memory: true) 50 | error = assert_raises do 51 | worksheet = workbook.add_worksheet('a?') 52 | worksheet.write_value(1, 1, 'a') # without the validation, this method will crash the process 53 | end 54 | 55 | assert_equal(ArgumentError, error.class) 56 | assert_equal("Invalid worksheet name 'a?': (15 - error_invalid_sheetname_character) Worksheet name cannot contain invalid characters: '[ ] : * ? / \\'", error.message) 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /test/worksheet_test.rb: -------------------------------------------------------------------------------- 1 | require_relative 'test_helper' 2 | 3 | describe "FastExcel::WorksheetExt append_row" do 4 | 5 | before do 6 | @workbook = FastExcel.open(constant_memory: false) 7 | @worksheet = @workbook.add_worksheet 8 | end 9 | 10 | it "should have last_row_number = -1" do 11 | assert_equal(-1, @worksheet.last_row_number) 12 | end 13 | 14 | it "should write_value and update last_row_number" do 15 | @worksheet.write_value(0, 2, "aaa") 16 | assert_equal(0, @worksheet.last_row_number) 17 | assert_equal([[nil, nil, "aaa"]], get_arrays(@workbook)) 18 | end 19 | 20 | it "should append row and update last_row_number" do 21 | @worksheet.append_row(["aaa", "bbb", "ccc"]) 22 | @worksheet.append_row(["ddd", "eee", "fff"]) 23 | 24 | assert_equal(1, @worksheet.last_row_number) 25 | assert_equal([["aaa", "bbb", "ccc"], ["ddd", "eee", "fff"]], get_arrays(@workbook)) 26 | end 27 | 28 | it "should write_row then append and update last_row_number" do 29 | @worksheet.write_row(3, ["aaa", "bbb", "ccc"]) 30 | @worksheet.append_row(["ddd", "eee", "fff"]) 31 | 32 | assert_equal(4, @worksheet.last_row_number) 33 | assert_equal( 34 | [ 35 | [nil, nil, nil], 36 | [nil, nil, nil], 37 | [nil, nil, nil], 38 | ["aaa", "bbb", "ccc"], 39 | ["ddd", "eee", "fff"] 40 | ], 41 | get_arrays(@workbook) 42 | ) 43 | end 44 | 45 | it "should not reduce last_row_number" do 46 | @worksheet.append_row(["aaa", "bbb", "ccc"]) 47 | @worksheet.append_row(["ddd", "eee", "fff"]) 48 | @worksheet.write_value(0, 4, "foo") 49 | @worksheet.append_row(["111", "222", "333"]) 50 | 51 | assert_equal(2, @worksheet.last_row_number) 52 | assert_equal( 53 | [ 54 | ["aaa", "bbb", "ccc", nil, "foo"], 55 | ["ddd", "eee", "fff", nil, nil], 56 | ["111", "222", "333", nil, nil] 57 | ], 58 | get_arrays(@workbook) 59 | ) 60 | end 61 | 62 | it "should not allow to write rows that already saved" do 63 | @workbook = FastExcel.open(constant_memory: true) 64 | @worksheet = @workbook.add_worksheet 65 | 66 | @worksheet.append_row(["aaa", "bbb", "ccc"]) 67 | @worksheet.append_row(["ddd", "eee", "fff"]) 68 | 69 | error = assert_raises(ArgumentError) do 70 | @worksheet.write_value(0, 4, "foo") 71 | end 72 | 73 | assert_equal("Can not write to saved row in constant_memory mode (attempted row: 0, last saved row: 1)", error.message) 74 | end 75 | 76 | it "should write bigdecimal as a number" do 77 | require 'bigdecimal' 78 | 79 | @workbook = FastExcel.open(constant_memory: true) 80 | @worksheet = @workbook.add_worksheet 81 | 82 | @worksheet.append_row([BigDecimal("0.1234")]) 83 | 84 | assert_equal([[0.1234]], get_arrays(@workbook)) 85 | end 86 | 87 | it "should set name correctly" do 88 | workbook = FastExcel.open(constant_memory: true) 89 | ws1 = workbook.add_worksheet("foo") 90 | ws2 = workbook.add_worksheet("") 91 | 92 | assert_equal("foo", ws1[:name]) 93 | assert_equal("", ws2[:name]) 94 | end 95 | 96 | it "should map fields correctly" do 97 | workbook = FastExcel.open(constant_memory: true) 98 | 99 | ws = workbook.add_worksheet("1 should map fields correctly") 100 | 101 | ws.set_right_to_left 102 | 103 | assert_equal(ws[:right_to_left], 1) 104 | 105 | ws = workbook.add_worksheet 106 | ws.center_vertically 107 | assert_equal(ws[:print_options_changed], 1) 108 | assert_equal(ws[:vcenter], 1) 109 | 110 | ws = workbook.add_worksheet 111 | ws.print_row_col_headers 112 | assert_equal(ws[:print_headers], 1) 113 | assert_equal(ws[:print_options_changed], 1) 114 | 115 | ws = workbook.add_worksheet 116 | ws.set_margins(1.5, 2.5, 3.5, 4.5) 117 | assert_equal(ws[:margin_left], 1.5) 118 | assert_equal(ws[:margin_right], 2.5) 119 | assert_equal(ws[:margin_top], 3.5) 120 | assert_equal(ws[:margin_bottom], 4.5) 121 | 122 | assert_equal(ws[:vbreaks_count], 0) 123 | 124 | breaks = [20, 40, 60, 20, 0] 125 | FFI::MemoryPointer.new(:uint16, breaks.size) do |buffer| 126 | buffer.write_array_of_uint16(breaks) 127 | ws.set_v_pagebreaks(buffer) 128 | end 129 | 130 | # FastExcel.print_ffi_obj(ws) 131 | 132 | assert_equal(ws[:vbreaks_count], 4) 133 | end 134 | end 135 | --------------------------------------------------------------------------------