OpenXLSX هي مكتبة C ++ للقراءة والكتابة وإنشاء وتعديل ملفات Microsoft Excel® ، مع تنسيق .xlsx.
كما يقول العنوان - أحدث "إصدار" يظهر على https://github.com/troldal/openxlsx/releases هو من 2021-11-06 ، ويصبح قديمًا للغاية - يرجى سحب/تنزيل أحدث إصدار SW مباشرة من المستودع في حالته الحالية. رابط لأولئك الذين لا يريدون استخدام git : https://github.com/troldal/openxlsx/archive/refs/heads/master.zip
استعرض رمز XLDATETime استجابةً لـ #299 وقم بإصلاح خطأ أعتقد أنني قد أدخلت نفسي. الاعتذارات ، يجب الآن بناء التواريخ بشكل صحيح من double ، struct tm و time_t وتحويلها مرة أخرى إلى struct tm .
تم العثور على تاريخ التغيير في سجل التغيير التفصيلي.
اليوم ، وصلت الميزات من فرع التطوير أخيرًا إلى الفرع الرئيسي :) للحصول على التفاصيل ، يرجى الرجوع إلى سجل التغيير المفصل أدناه.
في ملخص:
OpenXLSX/headers/XLStyles.hpp : تمت إضافة فئة XLSTYLES (والكثير من الفئات الفرعية) ، مما يوفر وصولاً كاملاً تقريبًا إلى جميع إمكانيات تنسيق Excel.OpenXLSX/headers/XLMergeCells.hpp و XLSheet.hpp : يمكن الوصول إلى فئة XlmergeCells من خلال XLWorksheet من أجل إنشاء/حذف دمج الخلاياExamples/Demo10.cpp توضح كيف يتم استخدام الأنماط والدمج ملاحظة: القسم الذي يتم تعطيله باستخدام testBasics = false سوف يكسر جدول بيانات Excel الناتج إذا تم تمكينه ، فإن الغرض الوحيد هو إظهار الوصول إلى جميع الفئات والأساليب الجديدة. إذا كنت ترغب في استخدامها ، فتأكد من استخدامها بشكل صحيحملاحظة على xlnumberformat (s) : على عكس جميع عناصر XLStyles الأخرى ، لا تستخدم هذه الفهرس داخل XML كمعرف قابل للإحالة (xlcellformat :: setNumberformatid) ، ولكن بدلاً من ذلك ، فإن معرف محدد من قبل المستخدم يمكن تعيينه عبر الشكل xlnumberformat: محددة مسبقا من قبل MS. بشكل عام ، للتنسيقات المخصصة ، يوصى باستخدام IDS> 100.
في قائمة المهام:
قبل يومين ، كان لدي وقت أخيرًا لتعلم ما يكفي من وظائف GIT لأتمكن من العمل مع الفروع. لذلك قمت بإنشاء فرع تطوير مع أحدث الميزات التي ذكرتها في بعض طلبات السحب / المشكلات. لا تتردد في إلقاء نظرة. وبهذه الطريقة ، لا يتعين عليك الانتظار حتى يتم تحديث المستودع الرئيسي.
أغلقت العديد من طلبات السحب التي تم تنفيذها في تحديث مايو 2024 ، وقامت بتنفيذ اثنين من التحريرات من PR #246 و #253.
بعد فترة طويلة من عدم النشاط ، قررت استئناف تطوير OpenXLSX. تم تنظيف الكود وتم إصلاح عدد كبير من الأخطاء. تم اختبار المكتبة على Windows و MacOS و Linux ، ويجب أن تعمل على جميع المنصات.
أود أن أقدم خالص شكري لجميع الأشخاص الذين ساهموا في المشروع ، إما عن طريق الإبلاغ عن الأخطاء ، أو اقتراح الميزات أو عن طريق تقديم طلبات السحب. أود أيضًا أن أشكر جميع الأشخاص الذين قاموا ببطولة المشروع ، والذين أبدوا اهتمامًا بالمشروع.
على وجه الخصوص ، أود أن أشكر لارس أوفمان (https://codeberg.org/lars_uffmann/) على مساهماته في المشروع. قضى لارس وقتًا وجهد كبيرًا في تنظيف الكود ، وإصلاح الأخطاء وتنفيذ ميزات جديدة. بدون مساعدته ، لم يكن المشروع في الولاية اليوم.
تتمتع العديد من لغات البرمجة بالقدرة على تعديل ملفات Excel ، سواء أصلاً أو في شكل مكتبات مفتوحة المصدر. وهذا يشمل Python و Java و C#. بالنسبة لـ C ++ ، ومع ذلك ، فإن الأمور مبعثرة. على الرغم من وجود بعض المكتبات ، إلا أنها أقل نضجًا بشكل عام ولها مجموعة ميزة أصغر من اللغات الأخرى.
نظرًا لعدم وجود مكتبة مفتوحة المصدر قامت بتركيب احتياجاتي بالكامل ، قررت تطوير مكتبة OpenXLSX.
الطموح هو أن OpenXLSX يجب أن يكون قادرًا على قراءة ملفات Excel وكتابتها وتعديلها (البيانات وكذلك التنسيق) ، والقيام بذلك مع عدد قليل من التبعيات. حاليًا ، يعتمد OpenXLSX على مكتبات الطرف الثالث التالي:
هذه المكتبات كلها رأس فقط وتضمين في المستودع ، أي ليس من الضروري تنزيل وبناء منفصلة.
أيضًا ، تم التركيز على السرعة ، وليس استخدام الذاكرة (على الرغم من وجود خيارات لتقليل استخدام الذاكرة ، بتكلفة السرعة ؛ المزيد حول ذلك لاحقًا).
تم اختبار OpenXLSX على المنصات/المترجمين التالية. لاحظ أن "-" لا يعني أن OpenXlsx لا يعمل ؛ هذا يعني فقط أنه لم يتم اختباره:
| مجلس التعاون الخليجي | كلانج | MSVC | |
|---|---|---|---|
| النوافذ | Mingw | Mingw | + |
| سيجوين | - | - | ن/أ |
| ماكوس | + | + | ن/أ |
| Linux | + | + | ن/أ |
يجب أن تكون إصدارات المترجم التالية قادرة على تجميع OpenXLSX دون أخطاء:
يجب أن تكون Clang 7 قادرة على تجميع OpenXlsx ، ولكن يبدو أن هناك خطأ في تنفيذ STD :: Variant ، والذي يسبب أخطاء المترجم.
يجب أن يعمل Visual Studio 2017 أيضًا ، ولكن لم يتم اختباره.
يستخدم OpenXLSX CMake كنظام بناء (أو مولد نظام البناء ، على وجه الدقة). لذلك ، يجب عليك تثبيت Cmake أولاً ، من أجل إنشاء OpenXlsx. يمكنك العثور على تعليمات التثبيت على www.cmake.org.
توجد مكتبة OpenXlsx في دليل OpenXLSX الفرعي لهذا الريبو. دليل OpenXLSX الفرعي هو مشروع CMAKE القائم بذاته ؛ إذا كنت تستخدم CMake لمشروعك الخاص ، فيمكنك إضافة مجلد OpenXLSX كدليل فرعي لمشروعك. بدلاً من ذلك ، يمكنك استخدام CMake لإنشاء ملفات أو ملفات المشروع لمجموعة أدوات من اختيارك. يتم وصف كلتا الطريقتين في ما يلي.
إلى حد بعيد أسهل طريقة لاستخدام OpenXlsx في مشروعك الخاص ، هي استخدام Cmake بنفسك ، ثم إضافة مجلد OpenXlsx كدليل فرعي لشجرة المصدر لمشروعك. العديد من مشاريع دعم IDE CMAKE ، وأبرزها Visual Studio 2019 و JetBrains Clion و QT Creator. إذا كنت تستخدم Visual Studio ، فيجب عليك تحديد "مشروع CMake" على وجه التحديد عند إنشاء مشروع جديد.
إن الفائدة الرئيسية لتشمل مكتبة OpenXLSX كمجلد فرعي للمصدر ، هي أنه لا توجد حاجة لتحديد موقع ملفات المكتبة والرأس على وجه التحديد ؛ سيهتم Cmake بذلك من أجلك. أيضًا ، سيتم إنشاء المكتبة باستخدام نفس التكوين (Debug ، الإصدار ، إلخ) كمشروعك. على وجه الخصوص ، هذه الفائدة على Windows ، حيث لا يمكن استخدام مكتبات الإصدار في مشروع تصحيح الأخطاء (والعكس بالعكس) عندما يتم تمرير كائنات STL عبر واجهة المكتبة ، لأنها موجودة في OpenXLSX. عند تضمين مصدر OpenXLSX ، لن يكون هذا يمثل مشكلة.
باستخدام الأمر add_subdirectory() في ملف cmakelists.txt لمشروعك ، يمكنك الوصول إلى الرؤوس وملفات المكتبة من OpenXlsx. يمكن لـ OpenXLSX إنشاء مكتبة مشتركة أو مكتبة ثابتة. بشكل افتراضي ، ستنتج مكتبة مشتركة ، ولكن يمكنك تغيير ذلك في ملف OpenXlsx Cmakelists.txt. تقع المكتبة في مساحة اسم تسمى OpenXlsx ؛ وبالتالي فإن الاسم الكامل للمكتبة هو OpenXLSX::OpenXLSX .
المقتطف التالي هو ملف cmakelists.txt الأدنى لمشروعك الخاص ، والذي يتضمن OpenXLSX كدليل فرعي. لاحظ أنه يتم تعيين موقع إخراج الثنائيات على دليل مشترك. على 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)باستخدام ما سبق ، يجب أن تكون قادرًا على تجميع الكود التالي وتشغيله ، والذي سيقوم بإنشاء ملف Excel جديد يسمى "Termsheet.xlsx":
# 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 و Compiler Toolchain من اختيارك.
من سطر الأوامر ، انتقل إلى دليل 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/local/on linux و macOS ، و c: program files على Windows). يمكنك تعيين موقع مختلف باستخدام وسيطة -prefix.
لاحظ أنه بناءً على النظام الأساسي ، قد لا يكون من الممكن تثبيت كل من مكتبات التصحيح والإصدار. في Linux و MacOS ، هذه ليست مشكلة كبيرة ، حيث يمكن استخدام مكتبات الإصدار لكل من Debug and RecordeaBs. ليس كذلك بالنسبة لنظام التشغيل Windows ، حيث يجب أن يكون تكوين المكتبة هو نفسه بالنسبة للربط القابل للتنفيذ به. لهذا السبب ، على Windows ، من الأسهل بكثير تضمين مجلد Source OpenXLSX كدليل فرعي لمشروع CMAKE الخاص بك ؛ سيوفر لك الكثير من الصداع.
OpenXLSX لا يزال يعمل قيد التقدم. فيما يلي قائمة بالميزات التي تم تنفيذها ويجب أن تعمل بشكل صحيح:
لم يتم تنفيذ الميزات المتعلقة بالتنسيق ، والمؤامرات والأرقام ، ولا يتم التخطيط ليكون في المستقبل القريب.
تجدر الإشارة إلى أن إنشاء كائنات const xldocument ، لا يعمل حاليًا!
الجدول أدناه هو الإخراج من معيار (باستخدام مكتبة Google Benchmark) ، مما يدل على أنه يمكن إجراء الوصول إلى القراءة/الكتابة بمعدل حوالي 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 هو في الأساس مجموعة من ملفات .xml في أرشيف .zip. داخليًا ، يستخدم OpenXLSX مكتبة Miniz لضغط/إلغاء ضغط أرشيف .zip ، واتضح أن Miniz لديها حد أعلى فيما يتعلق بأحجام الملفات التي يمكنه التعامل معها.
الحد الأقصى لحجم الملف المسموح به لملف في أرشيف (أي إدخال في أرشيف .zip ، وليس الأرشيف نفسه) هو 4 جيجابايت (غير مضغوط). عادةً ما يكون الملف الأكبر في ملف/أرشيف .xlsx ، هو ملفات .xml التي تحمل بيانات ورقة العمل. أي ، قد لا تتجاوز بيانات ورقة العمل 4 جيجابايت. ما يترجم إليه من حيث الصفوف والأعمدة يعتمد كثيرًا على نوع البيانات ، لكن 1048،576 صفوف × 128 عمودًا مملوءة بأكاس عدد من الأعداد الصحيحة ستأخذ تقريبًا. 4 غيغابايت. يعتمد حجم الأرشيف المضغوط أيضًا على البيانات المحتفظ بها في ورقة العمل ، وكذلك خوارزمية الضغط المستخدمة ، ولكن عادةً ما يكون للمصنف الذي يحتوي على ورقة عمل واحدة تبلغ 4 جيجابايت حجم مضغوط يتراوح بين 300 و 350 ميجابايت.
يرتبط الحد من 4 جيجابايت فقط بإدخال واحد في الأرشيف ، وليس حجم الأرشيف الكلي. هذا يعني أنه إذا كان الأرشيف يحمل إدخالات متعددة بحجم 4 جيجابايت ، فلا يزال بإمكان Miniz التعامل معها. بالنسبة إلى OpenXLSX ، هذا يعني أنه لا يزال من الممكن فتح مصنف مع العديد من أوراق العمل الكبيرة.
يستخدم OpenXLSX مكتبة Pugixml لتحليل ملفات .xml مع معالجتها في أرشيف .xlsx. Pugixml هو محلل DOM ، الذي يقرأ مستند .xml بالكامل في الذاكرة. وهذا يجعل التحليل والتلاعب بسرعة لا تصدق.
ومع ذلك ، فإن جميع الخيارات لها عواقب ، ويمكن استخدام محلل DOM أيضًا أن يطلب الكثير من الذاكرة. بالنسبة لجداول البيانات الصغيرة ، لا ينبغي أن تكون مشكلة ، ولكن إذا كنت بحاجة إلى معالجة جداول البيانات الكبيرة ، فقد تحتاج إلى الكثير من الذاكرة.
يعطي الجدول أدناه إشارة إلى عدد أعمدة البيانات التي يمكن معالجتها بواسطة OpenXLSX (بافتراض 1،048،576 صفًا):
| الأعمدة | |
|---|---|
| 8 جيجابايت ذاكرة الوصول العشوائي | 8-16 |
| 16 جيجابايت ذاكرة الوصول العشوائي | 32-64 |
| 32 جيجابايت ذاكرة الوصول العشوائي | 128-256 |
قد تختلف Milage الخاص بك. يعتمد أداء OpenXLSX على نوع البيانات في جدول البيانات.
لاحظ أيضًا أنه يوصى باستخدام OpenXLSX في وضع 64 بت. على الرغم من أنه يمكن استخدامه بسهولة في وضع 32 بت ، إلا أنه يمكنه الوصول فقط إلى 4 جيجابايت من ذاكرة الوصول العشوائي ، مما يحد بشدة من الفائدة عند التعامل مع جداول البيانات الكبيرة.
إذا كان استهلاك الذاكرة يمثل مشكلة بالنسبة لك ، فيمكنك إنشاء مكتبة OpenXLSX في الوضع المدمج (ابحث عن enable_compact_mode في ملف cmakelists.txt) ، والذي سيمكن وضع Pugixml المدمج. سيستخدم OpenXLSX ذاكرة أقل ، ولكن أيضًا تشغيل أبطأ. انظر المزيد من التفاصيل في وثائق Pugixml هنا. كشفت حالة اختبار على Linux VM مع ذاكرة الوصول العشوائي 8 غيغابايت أن OpenXLSX يمكن أن يتعامل مع ورقة عمل مع 1،048،576 صفوف × 32 عمود في الوضع المضغوط ، مقابل 1،048،576 صفوف X 16 في الوضع الافتراضي.
إلى حد بعيد ، فإن معظم الأسئلة التي أحصل عليها حول OpenXlsx على Github ، ترتبط بـ Unicode. يبدو أنه (ومن المفهوم) مصدرًا كبيرًا للارتباك الكبير لكثير من الناس.
في وقت مبكر ، قررت أن OpenXlsx يجب أن يركز على جزء Excel ، ولا تكون أداة ترميز/تحويل نصية أيضًا. لذلك ، يجب أن تكون جميع إدخال/إخراج النص إلى OpenXlsx في ترميز UTF-8 ... وإلا فلن يعمل كما هو متوقع. قد يكون من الضروري أيضًا حفظ ملفات التعليمات البرمجية المصدر بتنسيق UTF-8. على سبيل المثال ، إذا تم حفظ ملف مصدر بتنسيق UTF-16 ، فسيكون أي حرفي سلسلة في UTF-16. لذا ، إذا كان لديك أي حرفية سلسلة متشابهة في رمز المصدر الخاص بك ، فيجب حفظ الملف المصدر أيضًا بتنسيق UTF-8.
تستخدم جميع معالجات السلسلة والاستخدام في OpenXlsx سلسلة C ++ Std :: ، والتي ترميز غيرأى ، ولكن يمكن استخدامها بسهولة في ترميز UTF-8. أيضًا ، يستخدم Excel ترميز UTF-8 داخليًا (في الواقع ، قد يكون من الممكن استخدام الترميزات الأخرى ، لكنني لست متأكدًا من ذلك).
للسبب أعلاه ، إذا كنت تعمل مع ترميزات نصية أخرى ، فيجب عليك التحويل إلى/من UTF-8 بنفسك . هناك عدد من الخيارات (على سبيل المثال boost.nowide أو boost.text). داخليًا ، يستخدم OpenXlsx Boost.Nowide ؛ يحتوي على عدد من الميزات المفيدة لفتح الملفات والتحويل بين STD :: String و Std :: Wstring وما إلى ذلك. سأقترح أيضًا أن تشاهد عرض James McNellis في CPPCON 2014 ، وقراءة مدونة Joel Spolsky.
يونيكود على Windows يمثل تحديًا خاصًا. على الرغم من أن UTF-8 مدعوم جيدًا على Linux و MacOS ، إلا أن الدعم على Windows محدود. على سبيل المثال ، سيبدو ناتج الأحرف غير ASCII (مثل الأحرف الصينية أو اليابانية) إلى النافذة الطرفية مثل الرطوبة. كما ذكرنا ، في بعض الأحيان ، عليك أيضًا أن تضع في اعتبارك ترميز النص لملفات المصدر نفسها. واجه بعض المستخدمين مشاكل في تعطل OpenXLSX عند فتح/إنشاء ملفات .xlsx بأسماء ملفات غير ASCII ، حيث اتضح أن الكود المصدري لبرنامج الاختبار كان في ترميز غير UTF-8 ، وبالتالي كانت سلسلة الإدخال إلى OpenXLSX غير UTF-8 أيضًا. للبقاء عاقلًا ، أوصي أن تكون ملفات التعليمات البرمجية المصدر دائمًا في ملفات UTF-8 ؛ جميع IDE's التي أعرفها يمكنها التعامل مع ملفات التعليمات البرمجية المصدر في ترميز UTF-8. مرحبًا بك في عالم Unicode الرائع على Windows؟
ملف Excel هو في الأساس مجرد مجموعة من ملفات .xml ملفوفة في أرشيف .zip. يستخدم OpenXLSX مكتبة طرف ثالثة لاستخراج ملفات .xml من أرشيف .zip. المكتبة الافتراضية التي تستخدمها OpenXlsx هي Zippy ، وهو غلاف موجه للكائنات حول Miniz. مكتبة Miniz سريعة ، وهي رأس فقط ، وهي مثالية لـ OpenXlsx.
ومع ذلك ، من الممكن استخدام مكتبة مضغوطة مختلفة ، إذا كنت ترغب في ذلك. في حالات نادرة ، قد تواجه مشاكل الاستقرار مع Miniz. في هذه الحالات ، قد يكون من المفيد تجربة مكتبة مضافة مختلفة.
لا يتطلب استخدام مكتبة Zippy/Miniz جهودًا خاصة ؛ ستعمل مباشرة خارج الصندوق. باستخدام مكتبة مضغوطة مختلفة ، سيتطلب بعض العمل.
من أجل استخدام مكتبة مضغوطة مختلفة ، يجب عليك إنشاء فئة غلاف تتوافق مع الواجهة المحددة بواسطة فئة Iziparchive. لاحظ أن هذا يتم تنفيذه باستخدام محو النوع ، مما يعني أنه لا يلزم وجود ميراث ؛ يحتاج الفصل فقط إلى وجود واجهة مطابقة ، وهذا كل شيء. بعد ذلك ، قدم كائنًا للفئة وقم بتزويده بمنشئ OpenXLSX.
لمعرفة مثال على كيفية القيام بذلك ، ألق نظرة على Demo1a في مجلد الأمثلة. يستخدم هذا المثال فئة تسمى CustomZip (باستخدام libzip كمكتبة zip) والتي يمكن العثور عليها تحت أمثلة/خارجي/customzip. من أجل إنشاء برنامج المثال ، تأكد من تثبيت LiBzip (وتبعياته) على جهاز الكمبيوتر الخاص بك ، وتمكين خيار OpenXLSX_ENABLE_LIBZIP في ملف cmakelists.txt في جذر OpenXLSX.
كما ذكرنا ، يستخدم برنامج مثال DEMO1A libzip. Libzip هي مكتبة مستقرة للغاية وتستخدم على نطاق واسع. ومع ذلك ، فإن تجربتي هي أنها بطيئة جدًا بالنسبة لملفات zip الكبيرة ، مثل جداول البيانات الكبيرة. لهذا السبب ، قد لا يكون Libzip هو الحل المثالي ، ولكنه مفيد لإظهار كيف يمكن استخدام مكتبة مضافة مختلفة.
في مجلد "الأمثلة" ، ستجد عدة برامج مثال ، توضح كيفية استخدام OpenXLSX. إن دراسة هذه البرامج المثال هي أفضل طريقة لمعرفة كيفية استخدام OpenXLSX. تم شرح برامج المثال ، لذلك يجب أن يكون من السهل نسبيًا فهم ما يجري.
يمكن الآن استخدام OpenXLSX مكتبات zip أخرى من مكتبة Zippy/Miniz الافتراضية. انظر Demo1a كمثال على كيفية القيام به
يتضمن هذا الإصدار نطاقات الصف والتكرار. كما يدعم تعيين حاويات قيم الخلايا إلى كائنات XLROW. هذا أسرع بكثير (حتى x2) من استخدام نطاقات الخلايا أو الوصول إلى الخلايا بواسطة مراجع الخلايا.
تم إعادة تصميم الهندسة المعمارية الداخلية لـ OpenXLSX بشكل كبير منذ الإصدار السابق. والسبب هو أن المكتبة كانت تتحول إلى كرة كبيرة من الطين ، وكان من الصعب بشكل متزايد إضافة ميزات وإصلاح الأخطاء. مع الهندسة المعمارية الجديدة ، سيكون (نأمل) أسهل في إدارة وإضافة ميزات جديدة.
بسبب إعادة تصميم العمارة ، هناك بعض التغييرات على الواجهة العامة. ومع ذلك ، فإن هذه التغييرات ليست كبيرة ، ويجب أن يكون من السهل تحديثها:
أدرك أن هذه التغييرات قد تسبب مشاكل لبعض المستخدمين. ولهذا السبب ، يمكن العثور على الإصدار السابق من OpenXlsx في الفرع "Legacy" لهذا المستودع. ومع ذلك ، أوصي بشدة أن تنتقل إلى الإصدار الجديد بدلاً من ذلك.
يبدو أن MS Office لا يتسامح مع أي تنسيق لعقد XML قبل <mergeCells> XML Node - من أجل التخلص من رسالة الخطأ وفقًا للرسالة ، يقوم الالتزام الأخير بتعديل وظيفة XLSheet::merges لإدراج عقدة <mergeCells> التي تم إنشاؤها حديثًا مباشرة بعد <sheetData> .
يمكن أن تؤدي هذه التخلف عن السداد المفقود إلى أخطاء المتابعة عندما تم افتراض أي فهرس نمط لهذه الخلية لاحقًا للوصول إلى النمط المذكور حسب الفهرس (استثناء إذا لم يكن الفهرس في نطاق صالح). أصبحت جميع فهارس الأنماط المتوفرة بتنسيق خلية الآن صفرًا (دون أي افتراضات يمكن تكوين النمط مع الفهرس 0 على أنها ، عادةً ما يكون افتراضيًا - إذا كنت تريد التأكد ، فزود خلية بتنسيق معروف كقالب نسخ من xlcellformats :: إنشاء).
XLDocument.hpp : تمت إضافة showWarnings() (الإعداد الافتراضي) و suppressWarnings()XLStyles.hpp : أضيفت معلمة suppressWarnings إلى مُنشئ (افتراضي: false )XLDocument::open : إذا تم استدعاء suppressWarnings() ، فقم بقمع التحذيرات حول تعليقات XML التي تم تجاهلها وعناصر المصنف غير المتجانسةXLDocument::open : m_suppressWarnings إعداد إلى مُنشئ XLSTYLESXLException.hpp : أضيفت #include <string>XLDocument::open ستقوم بإنشاء علاقة مصنف مفقودة في _rels/.rels if ، وفقط إذا ، يوجد مصنف مع المسار الافتراضي xl/workbook.xml في الأرشيفXLDocument::create و XLDocument::saveAs واجهات وظيفة ، ولكن وضع علامة عليها على أنها [[deprecated]] . تتطلب الواجهات الجديدة مواصفات صريحة لـ XLForceOverwrite أو XLDoNotOverwrite . بمجرد إزالة تعريفات الوظائف المنهكة ، يمكن أن يصبح XLDoNotOverwrite السلوك الافتراضي الجديدOpenXLSX/external/nowide/nowideDemo0 / احتفظ به في Makefile كوسيلة اختبارNotes محدثScripts التي تم إنشاؤها مع xml-format.sh (Linting XML ، مفيد لتحليل محتويات XLSX zip في محرر نصية)make-gnu.sh إلى Scripts/make-gnu.shScripts/cmake-cleanup.sh لإعداد (عدم تنفيذ!) أوامر تزيل جميع الملفات المؤقتة التي تم إنشاؤها بواسطة CMakeScripts/demos-cleanup.sh لإزالة جميع ملفات XLSX التي تم إنشاؤها بواسطة العروض التوضيحيةvoid setSavingDeclaration(XLXmlSavingDeclaration const& savingDeclaration) باستخدام class XLXmlSavingDeclaration (محددة في XLXmlData.hpp ) يمكن استخدامها لتمرير نسخة XML مخصصة ، والترميز ، والممتلكات المستقلة إلى pugixmlNotes/todo-list.txt تسمح XLWorksheet الآن بالوصول إلى كائن يدير نطاقات الخلايا المدمجة في ورقة العمل
XLMergeCells XLWorksheet::merges() - الوصول إلى فئة Xlmergecells لورقة العمل مباشرةvoid mergeCells(XLCellRange const& rangeToMerge, bool emptyHiddenCells = false) - دمج الخلايا المحددة بواسطة rangetomergevoid mergeCells(const std::string& rangeReference, bool emptyHiddenCells = false) - دمج الخلايا المحددة بواسطة rangereferencevoid unmergeCells(XLCellRange const& rangeToUnmerge) - خلايا غير محددة بواسطة Rangetounmergevoid unmergeCells(const std::string& rangeReference) - خلايا unerge التي تحددها 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 cellrefint32_t XLMergeCells::findMergeByCell(XLCellReference cellRef) - ابحث عن دمج يحتوي على XLCELLREFERENCEsize_t count() - احصل على عدد الاندماج المحدد في ورقة العملconst char* merge(int32_t index) - احصل على سلسلة مرجعية للدمج في الفهرسconst char* operator[](int32_t index) - overload من المشغل [] كاختصار إلى :: دمجint32_t appendMerge(const std::string& reference) - تحديد دمج جديد ، استدعى بواسطة Xlworksheet :: mergecellsvoid deleteMerge(int32_t index) - حذف الدمج مع الفهرس المحدد من ورقة العمل (= خلايا unmerge) ، التي تم استدعاؤها بواسطة xlworksheet :: unmergecells إضافة مثال على الاستخدام هذه الوظيفة إلى Demo10.cpp
XLDocument::open سوف تتجاهل الآن مجلدات فرعية غير معروفة (لا تزال غير معدلة ولا يمكن الوصول إليها في الرمز البريدي في الذاكرة والبقاء في الأرشيف عند الادخار). هذا يمنع رمي استثناء لأي ملف XLSX الذي كتبه تطبيق "إبداعي" يضاف عناصر غير معروفة لهذه المكتبةconstexpr من const unsigned int pugi_parse_settings ونقله إلى XLDocument.hpp بحيث يصبح const متاحًا لـ xlstyles و xlsharedstringsXLStyles - في OpenXLSX/headers/XLStyles.hppExamples/Demo10.cpp توضح استخدام وظائف دمج XLSTYLELS و Cell الجديدةXLCellIterator غير المخلوق: يمكن الآن التكرار على نطاق واختبار XLCellIterator::cellExists قبل الوصول إليه. هذا يسمح بتخطي الخلايا غير الموجودة دون إنشائها.workbook##.xml_rels/.rels == ليس xl/workbook.xml )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> على النحو الوارد أعلاه ، ستقوم بإدخال عنصر صف يسمى x:rowid="rId##" حيث يكون ## هو رقم التسلسل ، وعندما تتم إضافة مكون جديد إلى المصنف ، يتم تحديد معرف العلاقة الجديد عن طريق أخذ أعلى قيمة موجودة داخل كتاب المصنف ، وإضافة +1 إليه. أثناء التحقيق في [#254] تم العثور على مصنف لاستخدام (على ما يبدو) أعداد صحيحة عشوائية 64 بت ، مخزنة في النموذج r:id="Rxx" ، مع xx كونه تمثيل سداسي عشري لعدد عدد صحيح 64 بت.OpenXLSX::UseRandomIDs() لتبديل وظائف المعرف قبل فتح مثل هذا المستندOpenXLSX::UseSequentialIDs() لاستعادة وظيفة معرف العلاقة الافتراضية (المتسلسلة) ملاحظة على enable_xml_namespaces : دعم مساحة الاسم شفاف ويمكن استخدامه مع المستندات التي لا تستخدم مساحات الأسماء هذه. ومع ذلك ، يمكن أن يكون لها تأثير الأداء صغير (<5 ٪) على المصنفات الكبيرة وبالتالي فهو اختياري لتمكين.
تحذير مع UseRandomIDs : يرجى العلم أن الوضع المختلط ، حيث يتم فتح مستند واحد بدعم معرف عشوائي وآخر بدون معرفات العلاقة المتسلسلة ، لا يتم دعمه في الوقت الحالي. إذا كان عليك العمل مع مستندات من أنواع مختلفة ، فيجب عليك دائمًا تكوين سلوك معرف العلاقة المطلوب للوثيقة التالية ، والعمل مع ذلك ، وإغلاقه ، وتغيير تكوين معرف العلاقة قبل فتح المستند التالي.
يرجى تجاهل الأمثلة/demo0.cpp والأمثلة/demo9.cpp في الوقت الحالي (Demo0 تافهة وتم استخدامها لاختبار دعم المصنف غير القياسي ، ويتطلب Demo9 مراجعة مع تعليقات أفضل). يعرض Demo9 كيفية استخدام XLCellAssignable الجديد لنسخ محتويات الخلايا (مثل Excel Copy & Paste).
XLCellIterator ينشئ خلايا فارغة فقط للتكرار عليها ، ويوفر ::cellExists() لاختبار ما إذا كانت الخلية المشددة حاليًا في ورقة العمل XML ، قبل الوصول إليهاXLStylesXLWorksheet الآن دعم XLMergeCells لدمج / نطاقات الخلايا المزعومةDemo10.cpp لديه الكثير من الأمثلة حول كيفية استخدام وظائف XLStyles الجديدةcustomXml وما إلى ذلك في أرشيف XLSXXLProperties.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. باختصار: