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 เป็น ID ที่อ้างอิงได้ (XLCellFormat :: setNumberFormatid) แต่แทนที่จะกำหนดรูปแบบการกำหนดรูปแบบ โดย MS. โดยทั่วไปสำหรับรูปแบบที่กำหนดเองขอแนะนำให้ใช้ IDS> 100
ในรายการสิ่งที่ต้องทำ:
สองสามวันที่ผ่านมาในที่สุดฉันก็มีเวลาเรียนรู้ฟังก์ชั่น GIT เพียงพอที่จะสามารถทำงานกับสาขาได้ ดังนั้นฉันจึงสร้างสาขาการพัฒนาด้วยคุณสมบัติใหม่ล่าสุดที่ฉันได้กล่าวถึงในคำขอ / ปัญหาการดึงบางอย่าง อย่าลังเลที่จะดู วิธีนี้คุณไม่ต้องรอจนกว่าพื้นที่เก็บข้อมูลหลักจะได้รับการอัปเดต
ปิดคำขอดึงจำนวนมากที่ดำเนินการในการอัปเดตพฤษภาคม 2024 โดยใช้งานบรรณาธิการอีกสองครั้งจาก PR #246 และ #253
หลังจากไม่มีการใช้งานมานานฉันได้ตัดสินใจที่จะดำเนินการพัฒนา 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 | |
|---|---|---|---|
| หน้าต่าง | Mingw | Mingw | - |
| ซิงวิน | - | - | N/A |
| แม็กอส | - | - | N/A |
| ลินเวกซ์ | - | - | N/A |
เวอร์ชันคอมไพเลอร์ต่อไปนี้ควรจะสามารถรวบรวม openxlsx ได้โดยไม่มีข้อผิดพลาด:
Clang 7 ควรจะสามารถรวบรวม OpenXLSX ได้ แต่เห็นได้ชัดว่ามีข้อผิดพลาดในการใช้งาน STD :: Variant ซึ่งทำให้เกิดข้อผิดพลาดของคอมไพเลอร์
Visual Studio 2017 ควรใช้งานได้ แต่ยังไม่ได้รับการทดสอบ
OpenXLSX ใช้ CMAKE เป็นระบบบิลด์ (หรือสร้างตัวสร้างระบบให้แน่นอน) ดังนั้นคุณต้องติดตั้ง CMake ก่อนเพื่อสร้าง openxlsx คุณสามารถค้นหาคำแนะนำการติดตั้งได้ที่ www.cmake.org
ไลบรารี OpenXLSX ตั้งอยู่ในไดเรกทอรีย่อย OpenXLSX ไปยัง repo นี้ ไดเรกทอรีย่อย OpenXLSX เป็นโครงการ CMAKE ที่มีอยู่ในตัวเอง หากคุณใช้ CMake สำหรับโครงการของคุณเองคุณสามารถเพิ่มโฟลเดอร์ OpenXLSX เป็นไดเรกทอรีย่อยในโครงการของคุณเอง หรือคุณสามารถใช้ CMake เพื่อสร้างไฟล์หรือไฟล์โครงการสำหรับเครื่องมือเครื่องมือที่คุณเลือก ทั้งสองวิธีมีการอธิบายไว้ในต่อไปนี้
ด้วยวิธีที่ง่ายที่สุดในการใช้ OpenXLSX ในโครงการของคุณเองคือใช้ CMAKE ด้วยตัวเองจากนั้นเพิ่มโฟลเดอร์ OpenXLSX เป็นไดเรกทอรีย่อยไปยังแผนผังต้นทางของโครงการของคุณเอง โครงการสนับสนุน CMake ของ IDE หลายโครงการโดยเฉพาะอย่างยิ่ง Visual Studio 2019, Jetbrains Clion และ QT Creator หากใช้ Visual Studio คุณต้องเลือก 'CMake Project' โดยเฉพาะเมื่อสร้างโครงการใหม่
ประโยชน์หลักของการรวมไลบรารี OpenXLSX เป็นโฟลเดอร์ย่อยต้นทางคือไม่จำเป็นต้องค้นหาไฟล์ไลบรารีและส่วนหัวโดยเฉพาะ Cmake จะดูแลสิ่งนั้นให้คุณ นอกจากนี้ไลบรารีจะสร้างโดยใช้การกำหนดค่าเดียวกัน (ดีบัก, ปล่อย ฯลฯ ) เป็นโครงการของคุณ โดยเฉพาะอย่างยิ่งสิ่งนี้เป็นประโยชน์ต่อ 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 ใหม่ชื่อ 'spriptsheet.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 และเครื่องมือคอมไพเลอร์ที่คุณเลือก
จากบรรทัดคำสั่งนำทางไดเรกทอรีย่อย OpenXLSX ของรูทโครงการและดำเนินการคำสั่งต่อไปนี้:
mkdir build
cd build
cmake ..
คำสั่งสุดท้ายจะกำหนดค่าโครงการ สิ่งนี้จะกำหนดค่าโครงการโดยใช้เครื่องมือเริ่มต้น หากคุณต้องการระบุ Toolchain ให้พิมพ์ 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 บน Windows) คุณสามารถตั้งค่าตำแหน่งอื่นโดยใช้อาร์กิวเมนต์ -PREFIX
โปรดทราบว่าขึ้นอยู่กับแพลตฟอร์มอาจไม่สามารถติดตั้งทั้งการดีบักและปล่อยไลบรารี บน Linux และ MacOS นี่ไม่ใช่ปัญหาใหญ่เนื่องจากสามารถใช้ไลบรารีการเปิดตัวได้สำหรับการดีบักและการเปิดตัว ไม่เช่นนั้นสำหรับ Windows ที่การกำหนดค่าของไลบรารีจะต้องเหมือนกับการเชื่อมโยงที่ปฏิบัติการได้ ด้วยเหตุผลดังกล่าวบน Windows มันง่ายกว่ามากที่จะรวมโฟลเดอร์ OpenXLSX Source เป็นไดเรกทอรีย่อยไปยังโครงการ 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 archive ภายใน OpenXLSX ใช้ไลบรารี MINIZ เพื่อบีบอัด/คลายการเก็บถาวร. ZIP และปรากฎว่า Miniz มีขีด จำกัด สูงสุดเกี่ยวกับขนาดไฟล์ที่สามารถจัดการได้
ขนาดไฟล์ที่อนุญาตสูงสุดสำหรับไฟล์ในไฟล์เก็บถาวร (เช่นรายการ EN ใน. ZIP เก็บถาวรไม่ใช่ที่เก็บถาวรเอง) คือ 4 GB (ไม่บีบอัด) โดยปกติแล้วไฟล์ที่ใหญ่ที่สุดในไฟล์. xlsx/เก็บถาวรจะเป็นไฟล์. xml ที่ถือข้อมูลแผ่นงาน เช่นข้อมูลแผ่นงานอาจไม่เกิน 4 GB สิ่งที่แปลว่าในแง่ของแถวและคอลัมน์ขึ้นอยู่กับประเภทของข้อมูลมาก แต่ 1,048,576 แถว x 128 คอลัมน์ที่เต็มไปด้วยจำนวนเต็ม 4 หลักจะใช้เวลาประมาณ 4 GB ขนาดของคลังเก็บที่ถูกบีบอัดยังขึ้นอยู่กับข้อมูลที่จัดขึ้นในแผ่นงานรวมถึงอัลกอริทึมการบีบอัดที่ใช้ แต่สมุดงานที่มีแผ่นงานเดียว 4 GB มักจะมีขนาดบีบอัด 300-350 MB
ข้อ จำกัด 4 GB นั้นเกี่ยวข้องกับรายการเดียวในการเก็บถาวรไม่ใช่ขนาดเก็บถาวรทั้งหมด นั่นหมายความว่าหากการเก็บถาวรมีหลายรายการที่มีขนาด 4GB มินิซยังสามารถจัดการได้ สำหรับ OpenXLSX ซึ่งหมายความว่าสมุดงานที่มีแผ่นงานขนาดใหญ่หลายแผ่นยังสามารถเปิดได้
OpenXLSX ใช้ไลบรารี PUGIXML สำหรับการแยกวิเคราะห์และจัดการไฟล์. xml ใน. xlsx Archive Pugixml เป็นตัวแยกวิเคราะห์ Dom ซึ่งอ่านเอกสาร. xml ทั้งหมดลงในหน่วยความจำ นั่นทำให้การแยกวิเคราะห์และการจัดการอย่างรวดเร็วอย่างไม่น่าเชื่อ
อย่างไรก็ตามตัวเลือกทั้งหมดมีผลที่ตามมาและการใช้ตัวแยกวิเคราะห์ DOM สามารถเรียกร้องหน่วยความจำได้มาก สำหรับสเปรดชีตขนาดเล็กมันไม่ควรเป็นปัญหา แต่ถ้าคุณต้องการจัดการสเปรดชีตขนาดใหญ่คุณอาจต้องมีหน่วยความจำมากมาย
ตารางด้านล่างแสดงให้เห็นว่าสามารถจัดการข้อมูลได้กี่คอลัมน์โดย OpenXLSX (สมมติว่า 1,048,576 แถว):
| คอลัมน์ | |
|---|---|
| RAM 8 GB | 8-16 |
| RAM 16 GB | 32-64 |
| 32 GB RAM | 128-256 |
ระยะทางของคุณอาจแตกต่างกันไป ประสิทธิภาพของ OpenXLSX จะขึ้นอยู่กับประเภทของข้อมูลในสเปรดชีต
โปรดทราบว่าขอแนะนำให้ใช้ OpenXLSX ในโหมด 64 บิต แม้ว่าจะสามารถใช้งานได้อย่างง่ายดายในโหมด 32 บิต แต่สามารถเข้าถึง RAM 4 GB ได้เพียง 4 GB ซึ่งจะ จำกัด ประโยชน์อย่างรุนแรงเมื่อจัดการสเปรดชีตขนาดใหญ่
หากการใช้หน่วยความจำเป็นปัญหาสำหรับคุณคุณสามารถสร้างไลบรารี OpenXLSX ในโหมดกะทัดรัด (ค้นหา enable_compact_mode ในไฟล์ cmakelists.txt) ซึ่งจะเปิดใช้งานโหมดกะทัดรัดของ PugixML OpenXLSX จะใช้หน่วยความจำน้อยลง แต่ยังทำงานช้าลง ดูรายละเอียดเพิ่มเติมในเอกสาร PugixML ที่นี่ กรณีทดสอบทำงานบน Linux VM ด้วย RAM 8 GB เปิดเผยว่า OpenXLSX สามารถจัดการแผ่นงานที่มี 1,048,576 แถว x 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 :: ซึ่งเป็นการเข้ารหัส Agnostic แต่สามารถใช้สำหรับการเข้ารหัส UTF-8 ได้อย่างง่ายดาย นอกจากนี้ Excel ใช้การเข้ารหัส UTF-8 ภายใน (ที่จริงแล้วมันอาจเป็นไปได้ที่จะใช้การเข้ารหัสอื่น ๆ แต่ฉันไม่แน่ใจเกี่ยวกับเรื่องนั้น)
ด้วยเหตุผลข้างต้น หากคุณทำงานกับการเข้ารหัสข้อความอื่น ๆ คุณต้องแปลงเป็น/จาก UTF-8 ด้วยตัวคุณเอง มีตัวเลือกมากมาย (เช่น boost.nowide หรือ boost.text) ภายใน OpenXLSX ใช้ boost.nowide; มันมีคุณสมบัติที่มีประโยชน์มากมายสำหรับการเปิดไฟล์และการแปลงระหว่าง std :: string และ std :: wstring ฯลฯ ฉันจะแนะนำให้คุณดูการนำเสนอของ James McNellis ที่ CPPCON 2014 และอ่านบล็อกของ Joel Spolsky
Unicode on Windows เป็นสิ่งที่ท้าทายเป็นพิเศษ ในขณะที่ UTF-8 ได้รับการสนับสนุนอย่างดีใน Linux และ MacOS การสนับสนุนบน Windows นั้นมี จำกัด มากขึ้น ตัวอย่างเช่นผลลัพธ์ของอักขระที่ไม่ใช่ ASCII (เช่นอักขระจีนหรือญี่ปุ่น) ไปยังหน้าต่างเทอร์มินัลจะดูเหมือนคำพูดพล่อยๆ ดังที่ได้กล่าวไว้บางครั้งคุณก็ต้องคำนึงถึงการเข้ารหัสข้อความของไฟล์ต้นฉบับด้วยตัวเอง ผู้ใช้บางคนมีปัญหาเกี่ยวกับ OpenXLSX ที่ล้มเหลวเมื่อเปิด/สร้างไฟล์. xLSX ที่มีชื่อไฟล์ที่ไม่ใช่ ASCII ซึ่งกลับกลายเป็นว่า ซอร์สโค้ด สำหรับโปรแกรมทดสอบอยู่ในการเข้ารหัสที่ไม่ใช่ UTF-8 เพื่อให้มีสติอยู่ฉันขอแนะนำว่าไฟล์ซอร์สโค้ดอยู่ในไฟล์ UTF-8 เสมอ IDE ทั้งหมดที่ฉันรู้สามารถจัดการไฟล์ซอร์สโค้ดในการเข้ารหัส UTF-8 ยินดีต้อนรับสู่โลกมหัศจรรย์ของ Unicode บน Windows?
ไฟล์ Excel เป็นเพียงไฟล์. xml จำนวนมากที่ห่อหุ้มอยู่ในไฟล์เก็บถาวร. zip OpenXLSX ใช้ไลบรารีบุคคลที่สามเพื่อแยกไฟล์. xML ออกจากไฟล์. ZIP Archive ไลบรารีเริ่มต้นที่ใช้โดย OpenXLSX คือ zippy ซึ่งเป็น wrapper เชิงวัตถุรอบ miniz ห้องสมุด Miniz นั้นรวดเร็วและเป็นส่วนหัวเท่านั้นซึ่งเหมาะสำหรับ OpenXLSX
อย่างไรก็ตามมันเป็นไปได้ที่จะใช้ zip-library ที่แตกต่างกันหากคุณต้องการ ในบางกรณีคุณอาจประสบปัญหาความมั่นคงกับมินิซ ในกรณีเหล่านั้นอาจเป็นประโยชน์ในการลองใช้ Zip-Library ที่แตกต่างกัน
การใช้ห้องสมุด zippy/miniz ไม่จำเป็นต้องใช้ความพยายามพิเศษ มันจะทำงานตรงออกจากกล่อง อย่างไรก็ตามการใช้ Zip-Library ที่แตกต่างกันจะต้องทำงานบางอย่าง
ในการใช้ zip-library อื่นคุณต้องสร้างคลาส wrapper ที่สอดคล้องกับอินเตอร์เฟสที่ระบุโดยคลาส iziparchive โปรดทราบว่าสิ่งนี้ถูกนำไปใช้โดยใช้ การลบประเภท ซึ่งหมายความว่าไม่จำเป็นต้องมีการสืบทอด คลาสเพียงแค่ต้องมีอินเทอร์เฟซที่สอดคล้องกันนั่นคือทั้งหมด หลังจากนั้นให้วัตถุของคลาสและจัดหาให้กับตัวสร้าง OpenXLSX
หากต้องการดูตัวอย่างของวิธีการทำสิ่งนี้ให้ดูที่ Demo1a ในโฟลเดอร์ตัวอย่าง ตัวอย่างนี้ใช้คลาสที่เรียกว่า CustomZip (โดยใช้ libzip เป็นไลบรารี zip) ซึ่งสามารถพบได้ภายใต้ตัวอย่าง/ภายนอก/customzip ในการสร้างโปรแกรมตัวอย่างตรวจสอบให้แน่ใจว่ามีการติดตั้ง libzip (และการพึ่งพา) บนคอมพิวเตอร์ของคุณและเปิดใช้งานตัวเลือก openxlsx_enable_libzip ในไฟล์ cmakelists.txt ในรูท OpenXLSX
ดังที่ได้กล่าวไว้โปรแกรมตัวอย่าง Demo1a ใช้ libzip Libzip เป็นห้องสมุดที่มีเสถียรภาพมากและใช้กันอย่างแพร่หลาย อย่างไรก็ตามประสบการณ์ของฉันคือมันค่อนข้างช้าสำหรับไฟล์ซิปขนาดใหญ่เช่นสเปรดชีตขนาดใหญ่ ด้วยเหตุผลดังกล่าว Libzip อาจไม่ใช่วิธีแก้ปัญหาในอุดมคติ แต่ก็มีประโยชน์สำหรับการแสดงให้เห็นว่าสามารถใช้ไลบรารีซิปที่แตกต่างกันได้อย่างไร
ในโฟลเดอร์ 'ตัวอย่าง' คุณจะพบโปรแกรมตัวอย่างหลายโปรแกรมที่แสดงวิธีการใช้ OpenXLSX การศึกษาโปรแกรมตัวอย่างเหล่านั้นเป็นวิธีที่ดีที่สุดในการเรียนรู้วิธีใช้ OpenXLSX โปรแกรมตัวอย่างมีคำอธิบายประกอบดังนั้นจึงควรเข้าใจได้ง่ายว่าเกิดอะไรขึ้น
OpenXLSX สามารถใช้ไลบรารี ZIP อื่น ๆ ได้นอกเหนือจากไลบรารี Zippy/Miniz เริ่มต้น ดู demo1a เป็นตัวอย่างของวิธีการทำ
รุ่นนี้มีช่วงแถวและตัววนซ้ำ นอกจากนี้ยังสนับสนุนการกำหนดคอนเทนเนอร์ของค่าเซลล์ให้กับวัตถุ XLROW นี่คือเร็วกว่าอย่างมาก (สูงสุด x2) มากกว่าการใช้ช่วงเซลล์หรือเข้าถึงเซลล์โดยการอ้างอิงเซลล์
สถาปัตยกรรมภายในของ OpenXLSX ได้รับการออกแบบใหม่อย่างมีนัยสำคัญตั้งแต่รุ่นก่อนหน้า เหตุผลก็คือห้องสมุดเปลี่ยนเป็นโคลนก้อนใหญ่และมันก็ยากมากที่จะเพิ่มคุณสมบัติและแก้ไขข้อบกพร่อง ด้วยสถาปัตยกรรมใหม่มันจะง่ายต่อการจัดการและเพิ่มคุณสมบัติใหม่
เนื่องจากการออกแบบสถาปัตยกรรมใหม่มีการเปลี่ยนแปลงเล็กน้อยในส่วนต่อประสานสาธารณะ อย่างไรก็ตามการเปลี่ยนแปลงเหล่านี้ไม่สำคัญและควรอัปเดตง่าย:
ฉันรู้ว่าการเปลี่ยนแปลงเหล่านี้อาจทำให้เกิดปัญหาสำหรับผู้ใช้บางคน ด้วยเหตุนี้ OpenXLSX เวอร์ชันก่อนหน้าสามารถพบได้ในสาขา "มรดก" ของที่เก็บนี้ อย่างไรก็ตามฉันขอแนะนำอย่างยิ่งให้คุณเปลี่ยนไปใช้เวอร์ชันใหม่แทน
ดูเหมือนว่า MS Office จะไม่ทนต่อการจัดรูปแบบโหนด XML ใด ๆ ก่อนที่จะมี Node <mergeCells> XML - เพื่อกำจัดข้อความแสดงข้อผิดพลาดตามที่กำหนดล่าสุดจะปรับเปลี่ยนฟังก์ชั่น XLSheet::merges เพื่อแทรก <mergeCells> โหนดโดยตรงหลังจาก <sheetData> Node> Node
ค่าเริ่มต้นที่หายไปเหล่านี้อาจนำไปสู่ข้อผิดพลาดในการติดตามเมื่อดัชนีรูปแบบใด ๆ ของเซลล์นี้ถูกสันนิษฐานในภายหลังว่าถูกต้องในการเข้าถึงสไตล์ดังกล่าวตามดัชนี (ยกเว้นถ้าดัชนีไม่อยู่ในช่วงที่ถูกต้อง) ดัชนีสไตล์ทั้งหมดที่มีอยู่ในรูปแบบเซลล์ตอนนี้เป็นศูนย์ - เริ่มต้น (โดยไม่มีสมมติฐานว่าสไตล์ที่มีดัชนี 0 อาจกำหนดค่าเป็นค่าเริ่มต้น - หากคุณต้องการให้แน่ใจว่าให้รูปแบบที่รู้จักกันในเซลล์
XLDocument.hpp : เพิ่ม showWarnings() (การตั้งค่าเริ่มต้น) และ suppressWarnings()XLStyles.hpp : เพิ่มพารามิเตอร์ suppressWarnings ไปยังตัวสร้าง (ค่าเริ่มต้น: false )XLDocument::open suppressWarnings()XLDocument::open : การตั้งค่า m_suppressWarnings ถูกส่งต่อไปยัง Xlstyles ConstructorXLException.hpp : เพิ่ม #include <string> ที่หายไปXLDocument::open _rels/.relsXLDocument::create และ XLDocument::saveAs แต่ทำเครื่องหมายว่า [[deprecated]] อินเทอร์เฟซใหม่ต้องการข้อกำหนดที่ชัดเจนของ XLForceOverwrite หรือ XLDoNotOverwrite เมื่อสามารถลบคำจำกัดความของฟังก์ชั่นที่เลิกใช้แล้ว XLDoNotOverwrite อาจกลายเป็นพฤติกรรมเริ่มต้นใหม่OpenXLSX/external/nowide/nowideDemo0 / เก็บไว้ใน makefile เป็นยานพาหนะทดสอบNotes โฟลเดอร์Scripts ที่สร้างขึ้นด้วย xml-format.sh (ผ้าใบ XML, มีประโยชน์ในการวิเคราะห์เนื้อหาซิป XLSX ในตัวแก้ไขข้อความ)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 ที่กำหนดเองNotes/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) - เซลล์ unmerge ที่กำหนดโดย RangeTounMergevoid unmergeCells(const std::string& rangeReference) - เซลล์ unmerge ที่กำหนดโดย 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) - ค้นหาการผสานที่มี xlcellreference cellrefsize_t count() - รับ Count of Merges ที่กำหนดไว้ในแผ่นงานconst char* merge(int32_t index) - รับสตริงอ้างอิงผสานที่ดัชนีconst char* operator[](int32_t index) - overload of Operator [] เป็นทางลัดเป็น :: Mergeint32_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 แสดงให้เห็นถึงการใช้ฟังก์ชั่น XLSTYLES และการรวมเซลล์ใหม่XLCellIterator ที่ไม่ได้สร้าง: ตอนนี้สามารถวนซ้ำในช่วงและทดสอบ XLCellIterator::cellExists ก่อนที่จะเข้าถึงได้ สิ่งนี้ช่วยให้สามารถข้ามเซลล์ที่ไม่มีอยู่ได้โดยไม่ต้องสร้างworkbook##.xml , Namespaces XML และตัวระบุตัวระบุความสัมพันธ์ 64 บิต (ความสัมพันธ์) แบบสุ่มxl/workbook.xml ) ชื่อ Workbook XML ได้รับการยอมรับหากมีการอ้างอิงอย่างถูกต้องใน _rels/.rels<x:row r="1"> bool OpenXLSX::enable_xml_namespaces() ต้องใช้เพื่อเปิดใช้งานการสนับสนุนเนมสเป x ก่อนที่insert_child_before("x:row", curRow ) ใน <y:sheetData> โหนดจะตัด x: และแทรกองค์ประกอบแถวชื่อ <y:row> โดยใช้ namespace ของโหนดแม่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##" โดยที่ ## เป็นหมายเลขลำดับและเมื่อมีการเพิ่มส่วนประกอบใหม่ลงในเวิร์กบุ๊กรหัสความสัมพันธ์ใหม่จะถูกกำหนดโดยการใช้ค่าสูงสุดที่มีอยู่ภายในเวิร์ก ในระหว่างการตรวจสอบ [#254] สมุดงานถูกพบว่าใช้ (ดูเหมือน) สุ่ม 64 บิตจำนวนเต็มเก็บไว้ในแบบฟอร์ม r:id="Rxx" โดย xx เป็นตัวแทนหกเหลี่ยมของจำนวนเต็ม 64 บิตOpenXLSX::UseRandomIDs() จะต้องเรียกใช้เพื่อสลับฟังก์ชันการทำงานของ ID ก่อนที่ จะเปิดเอกสารดังกล่าวOpenXLSX::UseSequentialIDs() สามารถใช้เพื่อกู้คืนฟังก์ชัน ID ความสัมพันธ์เริ่มต้น (ลำดับ) หมายเหตุ เกี่ยวกับ enable_xml_namespaces : การสนับสนุนเนมสเปซมีความโปร่งใสและสามารถใช้กับเอกสารที่ไม่ใช้เนมสเปซดังกล่าว อย่างไรก็ตามมันอาจมีผลกระทบด้านประสิทธิภาพเล็กน้อย (<5%) ในเวิร์กบุ๊กขนาดใหญ่และเป็นทางเลือกที่จะเปิดใช้งาน
ข้อควรระวัง ด้วย UseRandomIDs : โปรดทราบว่าโหมดผสมซึ่งมีการเปิดเอกสารหนึ่งฉบับด้วยการสนับสนุน ID แบบสุ่มและอีกรายการที่ไม่มีรหัสความสัมพันธ์ตามลำดับไม่รองรับในขณะนี้ หากคุณต้องทำงานกับเอกสารประเภทต่าง ๆ คุณควรกำหนดค่าพฤติกรรม ID ความสัมพันธ์ที่ต้องการสำหรับเอกสารถัดไปทำงานกับสิ่งนั้นปิดและเปลี่ยนการกำหนดค่า ID ความสัมพันธ์ก่อนที่จะเปิดเอกสารถัดไป
โปรดเพิกเฉยต่อตัวอย่าง/demo0.cpp และตัวอย่าง/การสาธิต cpp สำหรับตอนนี้ (Demo0 เป็นเรื่องเล็กน้อยและใช้เพื่อทดสอบการสนับสนุนสมุดงานที่ไม่ได้มาตรฐานและ Demo9 ต้องมีการตรวจสอบด้วยความคิดเห็นที่ดีกว่า) Demo9 แสดงวิธีการใช้ XLCellassignable ใหม่เพื่อคัดลอกเนื้อหาเซลล์ (เช่น Excel Copy & Paste)
XLCellIterator ไม่ได้สร้างเซลล์ที่ว่างเปล่าอีกต่อไปเพื่อวนซ้ำและให้ ::cellExists() เพื่อทดสอบว่าเซลล์ชี้ไปที่อยู่ในปัจจุบันอยู่ในแผ่นงาน XML ก่อนที่จะเข้าถึงได้XLStylesXLWorksheet ให้การสนับสนุน XLMergeCells สำหรับช่วงการรวม / unmerging cellDemo10.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. In short: