OpenXLSXは、.XLSX形式を使用して、MicrosoftExcel®ファイルを読み取り、書き、作成、変更するためのC ++ライブラリです。
見出しが言うように - https://github.com/troldal/openxlsx/releasesに表示されている最新の「リリース」は2021-11-06のもので、現在の状態のリポジトリから最新のSWバージョンを直接プル/ダウンロードしてください。 gitを使用したくない人のためのリンク:https://github.com/troldal/openxlsx/archive/refs/heads/master.zip
#299に応じてXLDateTimeコードを確認し、自分自身を紹介したかもしれないと思うバグを修正しました。謝罪、日付は、 double 、 struct tm 、およびtime_tから正しく構築し、 struct tmに変換する必要があります。
変更履歴は、詳細な変更ログにあります。
今日、開発ブランチの機能がついにメインブランチになりました:)詳細については、以下の詳細な変更ログを参照してください。
要約すれば:
OpenXLSX/headers/XLStyles.hpp :xlstylesクラス(および多くのサブクラス)が追加され、すべてのExcelフォーマット機能にほぼ完全にアクセスできます。OpenXLSX/headers/XLMergeCells.hpp and XLSheet.hpp :xlmergecellsクラスは、セルの合併を作成/削除するためにxlworksheetを介してアクセス可能になりますExamples/Demo10.cpp 、スタイルとマージの使用方法を示しています注: testBasics = falseで無効になっているセクションは、結果として得られるExcelスプレッドシートを破壊します。それらを使用したい場合は、必ず正しく使用してくださいXlNumberFormat(s)に関する注意:他のすべてのXLStyles要素とは反対に、これらはXML内のインデックスを紹介可能なID(XLCellFormat :: SetNumberFormatID)として使用するのではなく、XLNumberFormat :: SetNumberFormatidを介して設定できるユーザー定義IDを使用します。 MSによって事前に定義されています。一般に、カスタム形式の場合は、IDを100> 100を使用することをお勧めします。
To-Doリストで:
数日前、私はついにブランチを操作できるように十分なgit機能を学ぶ時間がありました。そこで、いくつかのプルリクエスト /問題で言及した最新の機能を備えた開発ブランチを作成しました。お気軽にご覧ください。これにより、メインリポジトリが更新されるまで待つ必要はありません。
2024年5月のアップデートで実装された多数のプルリクエストを閉鎖し、PR#246と#253からさらに2つのエディトリアルを実装しました。
長い期間の不活動の後、私はOpenXLSXの開発を再開することにしました。コードはクリーンアップされており、かなりの数のバグが修正されています。ライブラリはWindows、MacOS、Linuxでテストされており、すべてのプラットフォームで動作するはずです。
バグを報告したり、機能を提案したり、プルリクエストを送信したりすることにより、プロジェクトに貢献したすべての人々に心から感謝します。また、プロジェクトを主演し、プロジェクトに関心を示したすべての人々に感謝したいと思います。
特に、プロジェクトへの貢献について、Lars Uffmann(https://codeberg.org/lars_uffmann/)に感謝したいと思います。 Larsは、コードのクリーンアップ、バグの修正、新しい機能の実装に多大な時間と労力を費やしてきました。彼の助けがなければ、プロジェクトは今日ではなかっただろう。
多くのプログラミング言語には、ネイティブまたはオープンソースライブラリの形でExcelファイルを変更する機能があります。これには、Python、Java、C#が含まれます。ただし、C ++の場合、物事はより散らばっています。いくつかのライブラリがありますが、一般的には成熟度が低く、他の言語よりも小さな機能セットがあります。
私のニーズを完全に適合させるオープンソースライブラリがないため、OpenXLSXライブラリを開発することにしました。
野望は、OpenXLSXがExcelファイル(データとフォーマット)を読み取り、書き込み、作成、変更できる必要があることであり、できるだけ少ない依存関係を使用して行うことができるはずです。現在、OpenXLSXは次のサードパーティライブラリに依存します。
これらのライブラリはすべてヘッダーのみであり、リポジトリに含まれています。つまり、個別にダウンロードして構築する必要はありません。
また、メモリの使用量ではなく速度に焦点が置かれています(ただし、メモリ使用量を削減するためのオプションが速度で削減されていますが、後で詳しく説明します)。
OpenXLSXは、次のプラットフォーム/コンパイラでテストされています。 ' - 'はopenxlsxが機能しないという意味ではないことに注意してください。それはただテストされていないことを意味します:
| GCC | クラン | MSVC | |
|---|---|---|---|
| Windows | Mingw | Mingw | + |
| Cygwin | - | - | n/a |
| macos | + | + | n/a |
| Linux | + | + | n/a |
次のコンパイラバージョンは、エラーなしでOpenXLSXをコンパイルできる必要があります。
Clang 7はOpenXLSXをコンパイルできるはずですが、STD :: Variantの実装にバグがあるようです。これにより、コンパイラエラーが発生します。
Visual Studio 2017も機能するはずですが、テストされていません。
OpenXLSXは、CMAKEをビルドシステムとして使用します(正確にはシステムジェネレーターをビルド)。したがって、OpenXLSXを構築するには、最初にCMakeをインストールする必要があります。 www.cmake.orgでインストール手順を見つけることができます。
OpenXLSXライブラリは、OpenXLSXサブディレクトリにあるこのレポのサブディレクトリにあります。 OpenXLSXサブディレクトリは、自己完結型のCMAKEプロジェクトです。独自のプロジェクトにCmakeを使用する場合は、OpenXLSXフォルダーを独自のプロジェクトのサブディレクトリとして追加できます。または、Cmakeを使用して、選択したツールチェーン用のMakeファイルまたはプロジェクトファイルを生成することもできます。両方の方法については、以下で説明します。
独自のプロジェクトでOpenXLSXを使用する最も簡単な方法は、自分でCMakeを使用してから、OpenXLSXフォルダーを独自のプロジェクトのソースツリーのサブディレクトリとして追加することです。いくつかのIDEのサポートCmakeプロジェクト、特にVisual Studio 2019、Jetbrains Clion、QT Creator。 Visual Studioを使用する場合は、新しいプロジェクトを作成するときに「Cmakeプロジェクト」を具体的に選択する必要があります。
OpenXLSXライブラリをソースサブフォルダーとして含めることの主な利点は、ライブラリとヘッダーファイルを具体的に見つける必要がないことです。 cmakeはあなたのためにそれの世話をします。また、ライブラリは、プロジェクトと同じ構成(デバッグ、リリースなど)を使用して構築されます。特に、これはWindowsでの利点です。ここでは、STLオブジェクトがOpenXLSXにあるため、STLオブジェクトがライブラリインターフェイスに渡されている場合(およびその逆)、デバッグプロジェクトでリリースライブラリを使用することはできません。 OpenXLSXソースを含める場合、これは問題ではありません。
プロジェクトのcmakelists.txtファイルにadd_subdirectory()コマンドを使用することにより、OpenXLSXのヘッダーとライブラリファイルにアクセスできます。 OpenXLSXは、共有ライブラリまたは静的ライブラリのいずれかを生成できます。デフォルトでは、共有ライブラリが生成されますが、OpenXLSX cmakelists.txtファイルでそれを変更できます。ライブラリは、OpenXLSXと呼ばれる名前空間にあります。したがって、ライブラリのフルネームはOpenXLSX::OpenXLSXです。
次のスニペットは、独自のプロジェクトの最小cmakelists.txtファイルです。バイナリの出力場所は共通ディレクトリに設定されていることに注意してください。 LinuxとMacOSでは、これは実際には必要ありませんが、Windowsでは、実行するためにOpenXLSX共有ライブラリファイルを実行可能ファイルの場所にコピーする必要があるため、これはあなたの生活を楽にします。
cmake_minimum_required ( VERSION 3.15)
project (MyProject)
set (CMAKE_CXX_STANDARD 17)
# Set the build output location to a common directory
set ( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} / output )
set ( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} / output )
set ( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} / output )
add_subdirectory (OpenXLSX)
add_executable (MyProject main.cpp)
target_link_libraries (MyProject OpenXLSX::OpenXLSX)上記を使用して、次のコードをコンパイルして実行できるはずです。これにより、「SpreadSheet.XLSX」という名前の新しいExcelファイルが生成されます。
# include < OpenXLSX.hpp >
using namespace OpenXLSX ;
int main () {
XLDocument doc;
doc. create ( " Spreadsheet.xlsx " );
auto wks = doc. workbook (). worksheet ( " Sheet1 " );
wks. cell ( " A1 " ). value () = " Hello, OpenXLSX! " ;
doc. save ();
return 0 ;
}OpenXLSXバイナリを作成し、プロジェクトに自分で含める場合は、CMAKEと選択したコンパイラツールチェーンを使用して実行できます。
コマンドラインから、プロジェクトルートのOpenXLSXサブディレクトリをナビゲートし、次のコマンドを実行します。
mkdir build
cd build
cmake ..
最後のコマンドがプロジェクトを構成します。これにより、デフォルトのツールチェーンを使用してプロジェクトが構成されます。ツールチェーンを指定する場合は、 cmake -G "<toolchain>" .. <toolchain>を使用したいツールチェーン、たとえば「Unix Makefiles」、「Ninja」、「Xcode」、または「Visual Studio 16 2019」。詳細については、Cmakeドキュメントを参照してください。
最後に、コマンドを使用してライブラリを構築できます。
cmake --build . --target OpenXLSX --config Release
--targetおよび--config引数を使用したいものに変更することができます。
構築されると、次のコマンドを使用してインストールできます。
cmake --install .
このコマンドは、ライブラリとヘッダーファイルをプラットフォーム上のデフォルトの場所にインストールします(通常/USR/ローカル/LinuxおよびMacOSで、C:プログラムファイル)。 -prefix引数を使用して別の場所を設定できます。
プラットフォームによっては、デバッグとリリースの両方のライブラリをインストールすることはできない場合があることに注意してください。 LinuxとMacOSでは、これは大きな問題ではありません。リリースライブラリは、デバッグとリリースの実行可能ファイルの両方に使用できるからです。 Windowsではそうではありません。ここでは、ライブラリの構成が実行可能なリンクと同じでなければなりません。そのため、Windowsでは、CMAKEプロジェクトのサブディレクトリとしてOpenXLSXソースフォルダーを単に含めることがはるかに簡単です。それはあなたに多くの頭痛を救うでしょう。
OpenXLSXはまだ進行中です。以下は、実装されており、適切に機能する必要がある機能のリストです。
フォーマット、プロット、および数字に関連する機能は実装されておらず、近い将来に予定されていません。
const xldocumentオブジェクトの作成は現在機能していないことに注意してください。
以下の表は、ベンチマーク(Googleベンチマークライブラリを使用)からの出力です。これは、読み取り/書き込みアクセスが1秒あたり約4,000,000セルのレートで実行できることを示しています。 .xmlファイルの文字列からの変換により、フローティングポイント数はやや低くなります。
Run on (16 X 2300 MHz CPU s)
CPU Caches:
L1 Data 32 KiB (x8)
L1 Instruction 32 KiB (x8)
L2 Unified 256 KiB (x8)
L3 Unified 16384 KiB (x1)
Load Average: 2.46, 2.25, 2.19
---------------------------------------------------------------------------
Benchmark Time CPU Iterations UserCounters...
---------------------------------------------------------------------------
BM_WriteStrings 2484 ms 2482 ms 1 items=8.38861M items_per_second=3.37956M/s
BM_WriteIntegers 1949 ms 1949 ms 1 items=8.38861M items_per_second=4.30485M/s
BM_WriteFloats 4720 ms 4719 ms 1 items=8.38861M items_per_second=1.77767M/s
BM_WriteBools 2167 ms 2166 ms 1 items=8.38861M items_per_second=3.87247M/s
BM_ReadStrings 1883 ms 1882 ms 1 items=8.38861M items_per_second=4.45776M/s
BM_ReadIntegers 1641 ms 1641 ms 1 items=8.38861M items_per_second=5.11252M/s
BM_ReadFloats 4173 ms 4172 ms 1 items=8.38861M items_per_second=2.01078M/s
BM_ReadBools 1898 ms 1898 ms 1 items=8.38861M items_per_second=4.4205M/s
.xlsxファイルは、本質的に.zipアーカイブ内の.xmlファイルの束です。内部的には、OpenXLSXはMinizライブラリを使用して.Zipアーカイブを圧縮/解凍します。Minizは、処理できるファイルサイズに関して上限があることがわかります。
アーカイブ内のファイルの最大許容ファイルサイズ(つまり、アーカイブ自体ではなく.ZIPアーカイブのエントリ)は4 GB(非圧縮)です。通常、.xlsxファイル/アーカイブの最大のファイルは、ワークシートデータを保持している.xmlファイルです。つまり、ワークシートデータは4 GBを超えない場合があります。行と列の観点から翻訳されることは、データの種類に大きく依存しますが、4桁の整数で満たされた1,048,576行x 128列は約占有されます。 4ギガバイト。圧縮されたアーカイブのサイズは、ワークシートに保持されているデータと使用される圧縮アルゴリズムにも依存しますが、4 GBの単一のワークシートを備えたワークブックは通常、300〜350 MBの圧縮サイズです。
4 GBの制限は、アーカイブの合計サイズではなく、アーカイブの単一のエントリにのみ関連しています。つまり、アーカイブが4GBのサイズの複数のエントリを保持している場合、Minizはそれを処理できることを意味します。 OpenXLSXの場合、これは、いくつかの大きなワークシートを備えたワークブックを開いていることを意味します。
OpenXLSXは、.xlsxアーカイブの.xmlファイルを解析および操作するためにpugixmlライブラリを使用します。 pugixmlはdomパーサーであり、.xmlドキュメント全体をメモリに読み取ります。これにより、解析と操作が非常に速くなります。
ただし、すべての選択肢には結果があり、DOMパーサーを使用すると多くのメモリが必要になる場合があります。小さなスプレッドシートの場合、それは問題ではないはずですが、大きなスプレッドシートを操作する必要がある場合は、多くのメモリが必要になる場合があります。
以下の表は、OpenXLSX(1,048,576行を想定している)で処理できるデータの列の数を示しています。
| 列 | |
|---|---|
| 8 GB RAM | 8-16 |
| 16 GB RAM | 32-64 |
| 32 GB RAM | 128-256 |
あなたの走行距離は異なるかもしれません。 OpenXLSXのパフォーマンスは、スプレッドシートのデータの種類によって異なります。
また、64ビットモードでOpenXLSXを使用することをお勧めします。 32ビットモードで簡単に使用できますが、4 GBのRAMのみにアクセスできます。これにより、大きなスプレッドシートを処理するときに有用性が大幅に制限されます。
メモリの消費が問題である場合、CompactモードでOpenXLSXライブラリを構築できます(CMakelists.txtファイルのenable_compact_modeを探します)。 OpenXLSXは、より少ないメモリを使用しますが、遅く動作します。 PUGIXMLドキュメントの詳細については、こちらをご覧ください。 8 GB RAMでLinux VMで実行されるテストケースは、OpenXLSXがコンパクトモードで1,048,576行x 32列x 32列を備えたワークシートを処理できることを明らかにしました。
GitHubでOpenXLSXについて私が把握するほとんどの質問は、Unicodeに関連しています。それは明らかに(そして当然のことながら)多くの人々にとって大きな混乱の源です。
早い段階で、OpenXLSXはExcel部分に焦点を合わせ、テキストエンコード/変換ユーティリティでもないことを決定しました。したがって、 OpenXLSXへのすべてのテキスト入力/出力は、UTF-8エンコードにある必要があります...それ以外の場合は、予想どおりに機能しません。また、ソースコードファイルがUTF-8形式で保存される必要がある場合があります。たとえば、ソースファイルがUTF-16形式で保存されている場合、文字列リテラルもUTF-16になります。したがって、ソースコードにハードコーディングされた文字列リテラルがある場合は、ソースファイルもUTF-8形式で保存する必要があります。
OpenXLSXのすべての文字列操作と使用は、C ++ STD :: Stringを使用します。また、Excelは内部的にUTF-8エンコードを使用します(実際、他のエンコーディングを使用することは可能かもしれませんが、それについてはわかりません)。
上記の理由から、他のテキストエンコーディングを使用して作業する場合は、UTF-8から自分で変換する必要があります。多くのオプションがあります(例:boost.nowideまたはboost.text)。内部的には、OpenXLSXはboost.nowideを使用します。ファイルを開いてSTD :: StringとSTD :: WSTRINGなどの間で変換するための多くの便利な機能があります。また、CPPCON 2014でJames McNellisのプレゼンテーションを見て、Joel Spolskyのブログを読むことをお勧めします。
WindowsのUnicodeは特に困難です。 UTF-8はLinuxとMacOSで十分にサポートされていますが、Windowsでのサポートはより限られています。たとえば、ターミナルウィンドウへの非ASCII文字(中国語または日本語の文字など)の出力は、意味のように見えます。前述のように、ソースファイル自体のテキストエンコードにも注意する必要がある場合があります。一部のユーザーは、非ASCIIファイルを使用して.xlsxファイルを開く/作成するときにOpenXLSXがクラッシュするのに問題があり、テストプログラムのソースコードが非UTF-8エンコードであるため、OpenXLSXへの入力文字列も非UTF-8でした。正気を保つために、ソースコードファイルは常にUTF-8ファイルにあることをお勧めします。私が知っているすべてのIDEは、UTF-8エンコーディングのソースコードファイルを処理できます。 WindowsのUnicodeの素晴らしい世界へようこそ?
Excelファイルは、本質的に.ZIPアーカイブにラップされた.xmlファイルの束です。 OpenXLSXは、サードパーティライブラリを使用して、.ZIPアーカイブから.xmlファイルを抽出します。 OpenXLSXが使用するデフォルトのライブラリはZippyです。これは、Miniz周辺のオブジェクト指向のラッパーです。 Minizライブラリは高速で、Headerのみであり、OpenXLSXに最適です。
ただし、必要に応じて、別のzip-libraryを使用することができます。まれに、Minizで安定性の問題が発生する場合があります。そのような場合、別のziplibraryを試してみると便利かもしれません。
Zippy/Minizライブラリを使用するには、特別な努力は必要ありません。箱から出てすぐに動作します。ただし、別のziplibraryを使用するには、いくつかの作業が必要です。
別のzip-libraryを使用するには、iziparchiveクラスで指定されたインターフェイスに準拠するラッパークラスを作成する必要があります。これは、型消去を使用して実装されていることに注意してください。つまり、継承は必要ありません。クラスには、適合インターフェイスが必要です。その後、クラスのオブジェクトを提供し、OpenXLSXコンストラクターに供給します。
これがどのように行われるかの例を見るには、例フォルダーのDEMO1Aをご覧ください。この例では、customzip(zipライブラリとしてlibzipを使用)と呼ばれるクラスを使用します。サンプルプログラムを構築するために、libzip(および依存関係)がコンピューターにインストールされていることを確認し、cmakelists.txtファイルのopenxlsx_enable_libzipオプションをOpenXLSXルートのファイルに有効にします。
前述のように、DEMO1Aの例プログラムはLibzipを使用します。 Libzipは非常に安定したライブラリであり、広く使用されています。しかし、私の経験では、大きなスプレッドシートなどの大きなzipファイルでは非常に遅いということです。そのため、Libzipは理想的なソリューションではないかもしれませんが、別のZIPライブラリをどのように使用できるかを示すのに役立ちます。
「Examples」フォルダーには、OpenXLSXの使用方法を示すいくつかのサンプルプログラムがあります。これらの例を勉強することは、OpenXLSXの使用方法を学ぶための最良の方法です。プログラムの例には注釈が付けられているため、何が起こっているのかを理解するのは比較的簡単でなければなりません。
OpenXLSXは、デフォルトのZippy/Minizライブラリよりも他のZIPライブラリを使用できるようになりました。それがどのように行われるかの例として、demo1aを参照してください
このバージョンには、行の範囲とイテレーターが含まれています。また、セル値の容器のXLrowオブジェクトへの割り当てもサポートしています。これは、細胞範囲を使用したり、細胞参照による細胞へのアクセスよりもはるかに高速です(x2まで)。
OpenXLSXの内部アーキテクチャは、以前のバージョン以来大幅に再設計されています。その理由は、図書館が泥の大きなボールに変わり、機能を追加してバグを修正することはますます困難になっていたからです。新しいアーキテクチャを使用すると、(できれば)管理が容易になり、新しい機能が追加されます。
アーキテクチャの再設計により、パブリックインターフェイスにいくつかの変更があります。ただし、これらの変更は重要ではなく、更新するのは簡単なはずです。
これらの変更は、一部のユーザーに問題を引き起こす可能性があることを理解しています。そのため、OpenXLSXの以前のバージョンは、このリポジトリの「レガシー」ブランチにあります。ただし、代わりに新しいバージョンに移行することを強くお勧めします。
MS Officeは、 <mergeCells> XMLノードの前にフォーマットXMLノードに耐えられないように見えます - エラーメッセージを取り除くために、最新のコミットはXLSheet::merges FUNCTIONを変更して、 <sheetData>ノードの後に新しく作成された<mergeCells>ノードを直接挿入します。
これらの欠落しているデフォルトは、このセルの任意のスタイルインデックスが後でインデックスごとにSARDスタイルにアクセスするために有効になった場合にフォローアップエラーにつながる可能性があります(インデックスが有効な範囲にない場合は例外)。セル形式で利用可能なすべてのスタイルインデックスは現在ゼロイナイト化されています(インデックス0のスタイルがデフォルトとして構成される可能性のある仮定はありません。確かに、Xlcellformats :: Createのコピーフロムテンプレートとして既知の形式をセルに提供します)。
XLDocument.hpp : showWarnings() (デフォルト設定)とsuppressWarnings()を追加XLStyles.hpp : suppressWarningsパラメーターをコンストラクターに追加しました(デフォルト: false )XLDocument::open : suppressWarnings()が呼び出された場合、無視されたコメントxmlファイルと未処理のワークブックアイテムに関する警告を抑制しますXLDocument::open : m_suppressWarnings設定は、xlstylesコンストラクターに転送されますXLException.hpp :不足している#include <string>を追加しましたXLDocument::open 、 _rels/.relsで欠落しているワークブック関係を作成します。XLDocument::create and XLDocument::saveAs関数インターフェイスを再作成しましたが、 [[deprecated]]としてマークされました。新しいインターフェイスでは、 XLForceOverwriteまたはXLDoNotOverwriteの明示的な仕様が必要です。非推奨機能定義を削除できるようになると、 XLDoNotOverwrite新しいデフォルト動作になる可能性がありますOpenXLSX/external/nowide/nowideに戻りましたDemo0 /を削除 /テスト車両としてmakefileに保持しましたNotesフォルダーxml-format.shを使用したScriptsフォルダーを作成した(xml糸くず、テキストエディターのxlsx zipコンテンツを分析するのに役立ちます)make-gnu.sh Scripts/make-gnu.shに移動しましたScripts/cmake-cleanup.shを追加しましたScripts/demos-cleanup.shを追加しましたclass XLXmlSavingDeclaration void setSavingDeclaration(XLXmlSavingDeclaration const& savingDeclaration)を使用して、カスタムXMLバージョン、エンコーディング、およびスタンダルローンプロパティをPUGIXMLLONEプロパティに合格するために使用できるクラスXLXMLSAVINGDECLARATION( XLXmlData.hppで定義)を使用して、Void SetSavingDeclaration(XLXMLSavingDecLaration&SavingDeclaration)のサポートNotes/todo-list.txtを参照してくださいXLWorksheet 、ワークシートのマージされたセル範囲を管理するオブジェクトにアクセスできるようになりました
XLMergeCells XLWorksheet::merges() - ワークシートのxlmergecellsクラスに直接アクセスするvoid mergeCells(XLCellRange const& rangeToMerge, bool emptyHiddenCells = false) - rangeTomergeで定義されたセルのマージvoid mergeCells(const std::string& rangeReference, bool emptyHiddenCells = false)void unmergeCells(XLCellRange const& rangeToUnmerge) - rangeTounmergeによって定義されたマージセルvoid unmergeCells(const std::string& rangeReference) - rangereferenceによって定義されたマルジュセルXLMergeCells :追加方法
int32_t XLMergeCells::findMerge(const std::string& reference) - マージマッチマッチングリファレンスを見つけるbool mergeExists(const std::string& reference) - 参照とともにマージが存在するかどうかをテストしますint32_t XLMergeCells::findMergeByCell(const std::string& cellRef) - std :: string cellrefを含むマージを見つけるint32_t XLMergeCells::findMergeByCell(XLCellReference cellRef) - xlcellreference cellrefを含むマージを見つけるsize_t count() - ワークシートで定義されたマージのカウントを取得const char* merge(int32_t index) - インデックスでマージリファレンス文字列を取得しますconst char* operator[](int32_t index) - ::マージへのショートカットとしてのオペレーターのオーバーロード[]int32_t appendMerge(const std::string& reference) - xlworksheet :: mergecellsによって呼び出された新しいマージを定義しますvoid deleteMerge(int32_t index) - xlworksheet :: unmergecellsによって呼び出されたワークシートから指定されたインデックスとマージを削除するDemo10.cppにこの機能の使用例を追加しました
XLDocument::open未知のサブフォルダーを無視するようになります(それらはメモリのzipで変更されず、アクセスできないままであり、保存するとアーカイブにとどまります)。これにより、このライブラリに不明なアイテムを追加した「クリエイティブ」アプリケーションによって記述されたXLSXファイルの例外をスローするのを防ぎますconst unsigned int pugi_parse_settingsからconstexprを作成し、xlstylesとxlsharedstringsでconstが利用可能になるようにXLDocument.hppに移動しましたXLStylesクラスのワークシートスタイルの実装サポート - インターフェイスはOpenXLSX/headers/XLStyles.hppにありますExamples/Demo10.cpp新しいxlstyles&cellの合併機能の使用を実証していますXLCellIteratorのサポート:範囲を繰り返して、アクセスする前にXLCellIterator::cellExistsテストできます。これにより、存在しないセルを作成せずにスキップできます。workbook##.xml 、XMLネームスペース、ランダム64ビット(関係)識別子xl/workbook.xmlではない)ワークブックxml名は_rels/.relsで正しく参照されている場合に受け入れられました。bool OpenXLSX::enable_xml_namespaces()使用して、名前空間x (so: <x:row r="1"> )を使用してドキュメントを開く前に名前空間サポートを有効にする必要がありますinsert_child_before("x:row", curRow )の<y:sheetData>ノードはx: <y:row>という名前の行要素を挿入し、親ノードの名前空間を使用して挿入しますOpenXLSX/headers/XLXmlParser.hppを参照)は、ノード作成/アクセスのために関数に渡される名前空間を尊重するというbool force_nsをオプションの最後の引数として取得します。ヘルパーconst bool OpenXLSX::XLForceNamespace = trueコードの読みやすさに利用可能ですXMLNode::insert_child_before("x:row", curRow, XLForceNamespace) <y:sheetData> node x:rowid="rId##"に保存されていると想定しています。ここで、 ##はシーケンス番号です。新しいコンポーネントがワークブックに追加されると、新しい関係IDはワークブック内で最も高い既存の値を取得し、+1を追加することで決定されます。 [#254]の調査中、ワークブックは(一見)ランダムな64ビット整数を使用し、 r:id="Rxx"に保存され、 xxは64ビット整数の16進表現です。OpenXLSX::UseRandomIDs()そのようなドキュメントを開く前にID機能を切り替えるために呼び出される必要がありますOpenXLSX::UseSequentialIDs()使用して、デフォルト(シーケンシャル)関係ID機能を復元できますenable_xml_namespacesに注意:名前空間サポートは透明であり、そのような名前空間を使用しないドキュメントで使用できます。ただし、大規模なワークブックにパフォーマンスの影響が少ないため、有効にするためにオプションです。
UseRandomIDsには注意:ランダムIDサポートで1つのドキュメントが開かれ、連続的な関係IDがない別のドキュメントが当面の間サポートされていないことに注意してください。さまざまなタイプのドキュメントを操作する必要がある場合は、次のドキュメントの希望する関係ID動作を常に構成する必要があります。
例/demo0.cppとexamples/demo9.cppを無視してください(Demo0は些細なものであり、非標準のワークブックサポートのテストに使用され、Demo9はより良いコメントでレビューを必要とします)。 Demo9は、新しいXLCellassignableを使用する方法をコピーに割り当てるセルの内容(Excelコピー&ペーストなど)を紹介します。
XLCellIterator 、それらを繰り返すためだけに空のセルを作成しなくなり、 ::cellExists()を提供して、現在尖っている細胞がすでにワークシートXMLにあるかどうかをテストします。XLStylesサポートXLWorksheet 、 XLMergeCellsマージ /マースセル範囲のサポートを提供するようになりましたDemo10.cppは、新しいxlstyles機能の使用方法に関する多くの例がありますcustomXmlなどを無視しますXLProperties.cpp XLAppProperties to create <TitlesOfParts> and <HeadingPairs> nodes (and subnodes) if missing, added method alignWorksheets , called by XLDocument::open to ensure that all worksheets listed in the workbook xml are also accounted for in docProps/app.xml .XLProperties.cpp prettyInsertXmlNodeBefore , maybe this can eventually become a global function, paired with a TBW function prettyInsertXmlNodeAfter , and could be used by all classes, cleaning up the code for whitespace support substantially.XLProperties.cpp for <HeadingPairs> subnodes: pairCount -> pairValueParent , pairCountValue -> pairValue Code refactored in XLDocument::open to read the shared strings table while consistently ignoring phonetic tags, which were previously only ignored if the very first child of an <si> tag was a phonetic tag. Will now be ignored anywhere before, after or in between text <t> and rich text <r> tags.
Included a "dumb" fallback solution in XLRelationships.cpp GetTypeFromString to support previously unknown relationship domains, eg type="http://purl.oclc.org/ooxml/officeDocument/relationships/worksheet" . Altered behavior will initially test against the hardcoded relationship domains, and if that test fails to identify a relationship type string, the type string will be searched for an occurrence of /relationships/ and if that substring is found, the type detection fallback will try to evaluate the relationship type based on the substring starting with /relationships/ , ignoring the domain. For the above example, that would result in a test of typeString.substr( comparePos ) == "/relationships/worksheet" , where comparePos == 41 (the position at which substring /relationships/ begins).
In anticipation of a potential future need for a similar "dumb" fallback solution, repeating hardcoded strings in XLContentTypes.cpp GetTypeFromString were also replaced with string constants.
Updated .gitignore to a more generic version that excludes everything and explicitly re-includes all desired files.
BinaryAsHexString : replaced char array with std::string, as ISO C++ standard does not permit variable size arraysRand64 : added explicit type cast, as bitwise shift-left does not do integer promotion to long on the left operand-Wpedantic -Wextra and removed all previously disabled flags after below patchesf( param ) -> f(param) , a[ index ] -> a[index] and if( condition ) -> if (condition) )warning: enumerated and non-enumerated type in conditional expression [-Wextra]void ZipArchive::Save(std::ostream& stream)void ZipArchive::ExtractDir(const std::string& dir, const std::string& dest)void ZipArchive::ExtractAll(const std::string& dest)-Wunused-function by pragma for functions fileExists and isDirectoryuint32_t (was uint64_t ). CAUTION : there is no validity check on the underlying XML (nor was there ever one in case a value was inconsistent with OpenXLSX::MAX_ROWS)-Wsign-comparebool endReached() to eliminate -Wignored-qualifiers (ignored because const on trivial return types accomplishes nothing)OpenXLSX::ignore template, can be used to suppress -Wunused-parameter and -Wunused-variable like so: OpenXLSX::ignore(unusedValue)-Wunused-parameter#pragma warning lines in another pragma to disable -Wunknown-pragmas (on gcc/g++)#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wunknown-pragmas" // disable warning about below #pragma warning being unknown# pragma /* offending lines go here */#pragma GCC diagnostic popzippy.hppIZipArchive.hppXLCell.hppXLCellIterator.hppXLCellRange.hppXLCellReference.hppXLCellValue.hppXLColor.hppXLColumn.hppXLCommandQuery.hppXLContentTypes.hppXLDateTime.hppXLDocument.hppXLException.hppXLFormula.hppXLMergeCells.hppXLProperties.hppXLRelationships.hppXLRowData.hppXLRow.hppXLSharedStrings.hppXLSheet.hppXLStyles.hppXLWorkbook.hppXLXmlData.hppXLXmlFile.hppXLZipArchive.hppExamples/Demo5.cpp<Properties> (document) element, was previously wrongly appended to headingPairs/xl/worksheets/sheet* , /xl/sharedStrings.xml , /xl/styles.xml , /xl/theme/theme* ) and otherwise ignored. This fixes an issue when the workbook contains /xl/pivotCache/ and /xl/pivotTables/ entries until support for those is implemented (if ever ;P)<cols> element obtained via a rowNode parent's parentstd::vector< XLStyleIndex > m_columnStyles , and a method fetchColumnStyles that will populate the vector so that it can be passed to the XLCellIterator constructorXLCellIterator::cellExists() without creating the XML for the cell.<font><scheme val="major"/></font> )<font><vertAlign val="subscript"/></font> )<fills><fill><gradientFill>...</gradientFill></fill>...</fills> are now supportedPlease refer to Demo10 and XLStyles.hpp on how to set cell formatting.要するに: