OpenXlsx는 .xlsx 형식으로 Microsoft Excel® 파일을 읽고, 쓰기, 작성하고, 수정하고 수정하기위한 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 및 XLSheet.hpp : xlmergecells 클래스는 xlworksheet를 통해 액세스 할 수 있도록 셀 병합을 만들/삭제합니다.Examples/Demo10.cpp 스타일과 병합 사용 방법을 보여줍니다 . 참고 : testBasics = false 가 비활성화 된 섹션은 결과적으로 Excel 스프레드 시트를 깨뜨 립니다 . 유일한 목적은 모든 새로운 클래스 및 메소드에 대한 액세스를 보여주는 것입니다. 사용하려면 올바르게 사용하십시오.XlNumberformat에 대한 참고 : 다른 모든 Xlstyles 요소와는 달리, XML 내에서 인덱스를 참조 가능한 ID (XlCellFormat :: setNumberFormatID)로 사용하지 않고 XlNumberFormat :: setNumberformatid-를 통해 설정할 수있는 사용자 정의 ID를 사용하여 자체적으로 설정할 수 있습니다. MS에 의해 사전 정의되었습니다. 일반적으로 사용자 정의 형식의 경우 ID> 100을 사용하는 것이 좋습니다.
할 일 목록에서 :
며칠 전에 나는 마침내 지점과 함께 일할 수있는 충분한 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는 다음 플랫폼/컴파일러에서 테스트되었습니다. A '-'가 OpenXLSX가 작동하지 않는다는 것을 의미하지는 않습니다. 그것은 단지 테스트되지 않았 음을 의미합니다.
| GCC | 그 소리 | MSVC | |
|---|---|---|---|
| 창 | mingw | mingw | + |
| Cygwin | - | - | N/A |
| 마코스 | + | + | N/A |
| 리눅스 | + | + | N/A |
다음 컴파일러 버전은 오류없이 OpenXLSX를 컴파일 할 수 있어야합니다.
Clang 7은 OpenXLSX를 컴파일 할 수 있어야하지만 STD :: 변형 구현에는 버그가있어 컴파일러 오류가 발생합니다.
Visual Studio 2017도 작동하지만 테스트되지 않았습니다.
OpenXLSX는 CMAKE를 빌드 시스템 (또는 빌드 시스템 생성기, 정확히 빌드)로 사용합니다. 따라서 OpenXLSX를 빌드하려면 CMAKE를 먼저 설치해야합니다. www.cmake.org에서 설치 지침을 찾을 수 있습니다.
OpenXLSX 라이브러리는이 repo의 OpenXLSX 하위 디렉토리에 있습니다. OpenXLSX 하위 디렉토리는 자체 포함 된 CMAKE 프로젝트입니다. 자신의 프로젝트에 CMAKE를 사용하는 경우 OpenXLSX 폴더를 자신의 프로젝트에 하위 디렉토리로 추가 할 수 있습니다. 또는 CMAKE를 사용하여 선택한 툴체인을 위해 MAKE 파일 또는 프로젝트 파일을 생성 할 수 있습니다. 두 방법 모두 다음에 설명되어 있습니다.
자신의 프로젝트에서 OpenXLSX를 사용하는 가장 쉬운 방법은 CMAKE를 직접 사용한 다음 OpenXLSX 폴더를 자신의 프로젝트의 소스 트리에 하위 디렉토리로 추가하는 것입니다. 몇몇 IDE의 지원 CMAKE 프로젝트, 특히 Visual Studio 2019, JetBrains Clion 및 QT Creator. Visual Studio를 사용하는 경우 새 프로젝트를 만들 때 'Cmake Project'를 특별히 선택해야합니다.
OpenXLSX 라이브러리를 소스 하위 폴더로 포함시키는 주요 이점은 라이브러리 및 헤더 파일을 구체적으로 찾을 필요가 없다는 것입니다. Cmake는 당신을 위해 그것을 돌볼 것입니다. 또한 라이브러리는 프로젝트와 동일한 구성 (디버그, 릴리스 등)을 사용하여 빌드됩니다. 특히, 이것은 Windows의 이점입니다. 여기서 STL 객체가 Library 인터페이스를 통해 OpenXLSX에 전달 될 때 디버그 프로젝트에서 릴리스 라이브러리를 사용할 수 없습니다. OpenXLSX 소스를 포함시킬 때는 문제가되지 않습니다.
프로젝트에 cmakelists.txt 파일에서 add_subdirectory() 명령을 사용하면 OpenXLSX의 헤더 및 라이브러리 파일에 액세스 할 수 있습니다. OpenXLSX는 공유 라이브러리 또는 정적 라이브러리를 생성 할 수 있습니다. 기본적으로 공유 라이브러리를 생성하지만 OpenXLSX CMakelists.txt 파일에서 변경할 수 있습니다. 라이브러리는 OpenXLSX라는 네임 스페이스에 있습니다. 따라서 라이브러리의 전체 이름은 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/local/on linux 및 macOS, Windows의 C : Program 파일)에 설치합니다. -prefix 인수를 사용하여 다른 위치를 설정할 수 있습니다.
플랫폼에 따라 디버그 및 릴리스 라이브러리를 설치할 수는 없습니다. Linux 및 MacOS에서는 릴리스 라이브러리가 디버그 및 릴리스 실행 파일 모두에 사용할 수 있으므로 큰 문제는 아닙니다. 라이브러리 구성이 실행 파일 링크와 동일 해야하는 Windows의 경우 그렇지 않습니다. 이러한 이유로 Windows에서는 CMAKE 프로젝트의 하위 디렉토리로 OpenXLSX 소스 폴더를 포함시키는 것이 훨씬 쉽습니다. 그것은 당신에게 많은 두통을 절약 할 것입니다.
OpenXLSX는 여전히 진행 중입니다. 다음은 구현되었으며 제대로 작동 해야하는 기능 목록입니다.
서식, 플롯 및 수치와 관련된 기능은 구현되지 않았으며 가까운 시일 내에 계획되지 않았습니다.
const xldocument 객체를 만드는 것은 현재 작동하지 않는다는 점에 주목해야합니다!
아래 표는 벤치 마크 (Google Benchmark Library 사용)의 출력으로, 읽기/쓰기 액세스는 초당 약 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는 미니즈 라이브러리를 사용하여 .zip 아카이브를 압축/압축 압축하며 미니즈는 처리 할 수있는 파일 크기와 관련하여 상한이 있음이 밝혀졌습니다.
아카이브의 파일에 대한 최대 허용 파일 크기 (예 : 아카이브 자체가 아닌 .zip 아카이브의 항목)는 4GB (비 압축)입니다. 일반적으로 .xlsx 파일/아카이브의 가장 큰 파일은 워크 시트 데이터를 보유하는 .xml 파일입니다. 즉, 워크 시트 데이터는 4GB를 초과 할 수 없습니다. 행과 열의 측면에서 변환되는 것은 데이터 유형에 따라 크게 의존하지만 4 자리 정수로 채워진 1,048,576 행 x 128 열은 약을 차지합니다. 4GB. 압축 아카이브의 크기는 워크 시트에 보관 된 데이터와 사용 된 압축 알고리즘에 따라 다르지만 4GB의 단일 워크 시트가있는 통합 문서의 일반적으로 압축 크기는 300-350MB입니다.
4GB 제한은 총 아카이브 크기가 아닌 아카이브의 단일 항목과 관련이 있습니다. 즉, 아카이브에 크기가 4GB 인 여러 개의 항목을 보유하면 미니즈가 여전히 처리 할 수 있습니다. OpenXLSX의 경우 여러 대형 워크 시트가있는 통합 문서를 계속 열 수 있음을 의미합니다.
OpenXlsx는 .xlsx 아카이브에서 .xml 파일을 구문 분석하고 조작하기 위해 Pugixml 라이브러리를 사용합니다. Pugixml은 Dom Parser로 전체 .xml 문서를 메모리로 읽습니다. 그것은 구문 분석과 조작이 엄청나게 빠릅니다.
그러나 모든 선택에는 결과가 있으며 DOM 파서를 사용하면 많은 메모리가 필요할 수 있습니다. 작은 스프레드 시트의 경우 문제가되지 않아야하지만 큰 스프레드 시트를 조작 해야하는 경우 많은 메모리가 필요할 수 있습니다.
아래 표는 OpenXLSX에서 얼마나 많은 데이터를 처리 할 수 있는지 (1,048,576 행을 가정)를 표시합니다.
| 열 | |
|---|---|
| 8GB RAM | 8-16 |
| 16GB RAM | 32-64 |
| 32GB RAM | 128-256 |
마일리지는 다를 수 있습니다. OpenXLSX의 성능은 스프레드 시트의 데이터 유형에 따라 다릅니다.
64 비트 모드에서 OpenXLSX를 사용하는 것이 좋습니다. 32 비트 모드에서 쉽게 사용할 수 있지만 4GB의 RAM에만 액세스 할 수있어 큰 스프레드 시트를 처리 할 때 유용성을 심각하게 제한합니다.
메모리 소비가 귀하에게 문제 인 경우 CMAKELISS.TXT 파일에서 OpenXLSX 라이브러리를 컴팩트 모드 (ENABLE_COMPACT_MODE 찾기)를 구축 할 수 있습니다. OpenXLSX는 메모리를 적게 사용하지만 느리게 실행됩니다. Pugixml 문서의 자세한 내용은 여기를 참조하십시오. 8GB RAM으로 Linux VM에서 실행되는 테스트 케이스는 OpenXLSX가 소형 모드에서 1,048,576 행 X 32 열의 워크 시트를 처리 할 수 있으며, 1,048,576 행 x 16 열은 기본 모드에서 나타났습니다.
지금까지 Github의 OpenXlsx에 대해 얻는 가장 많은 의문은 유니 코드와 관련이 있습니다. 그것은 분명히 많은 사람들에게 큰 혼란의 원천입니다.
초기에 나는 OpenXLSX가 Excel 부분에 초점을 맞추고 텍스트 인코딩/변환 유틸리티가 아니라고 결정했습니다. 따라서 OpenXLSX에 대한 모든 텍스트 입력/출력은 UTF-8 인코딩에 있어야합니다 . 그렇지 않으면 예상대로 작동하지 않습니다. 소스 코드 파일이 UTF-8 형식으로 저장되어야 할 수도 있습니다. 예를 들어 소스 파일이 UTF-16 형식으로 저장되면 모든 문자열 리터럴도 UTF-16에 있습니다. 따라서 소스 코드에 하드 코딩 된 문자 리터럴이 있으면 소스 파일도 UTF-8 형식으로 저장 해야합니다 .
OpenXLSX의 모든 문자열 조작 및 사용법은 Agnostic을 인코딩하는 C ++ std :: String을 사용하지만 UTF-8 인코딩에 쉽게 사용할 수 있습니다. 또한 Excel은 내부적으로 UTF-8 인코딩을 사용합니다 (실제로는 다른 인코딩을 사용할 수 있지만 확실하지 않습니다).
위의 이유로, 다른 텍스트 인코딩으로 작업하는 경우 UTF-8에서 직접 전환해야합니다 . 여러 옵션이 있습니다 (예 : boost.nowide 또는 boost.text). 내부적으로 OpenXLSX는 boost.nowide를 사용합니다. 파일을 열고 std :: string과 std :: wstring 등을 변환하는 데 많은 편리한 기능이 있습니다. 또한 CPPCon 2014에서 James McNellis의 프레젠테이션을보고 Joel Spolsky의 블로그를 읽는 것이 좋습니다.
Windows의 유니 코드는 특히 도전적입니다. UTF-8은 Linux 및 MacOS에서 잘 지원되지만 Windows의 지원이 더 제한적입니다. 예를 들어, 터미널 창에 대한 비 ASCII 문자 (예 : 중국어 또는 일본 문자)의 출력은 gribberish처럼 보입니다. 언급했듯이 때로는 소스 파일 자체의 텍스트 인코딩을 염두에 두어야합니다. 일부 사용자는 ASCII 비자 이름으로 .xlsx 파일을 열거나 생성 할 때 OpenXLSX 충돌에 문제가 있었으며, 여기서 테스트 프로그램의 소스 코드는 UTF-8 인코딩이 아닌 것으로 밝혀졌으며, 따라서 OpenXLSX에 대한 입력 문자열도 NOTF-8이었다. 제정신을 유지하려면 소스 코드 파일이 항상 UTF-8 파일에있는 것이 좋습니다. 내가 알고있는 모든 IDE는 UTF-8 인코딩에서 소스 코드 파일을 처리 할 수 있습니다. Windows의 멋진 유니 코드 세계에 오신 것을 환영합니까?
Excel-File은 본질적으로 .zip 아카이브에 싸인 .xml 파일이 있습니다. OpenXLSX는 제 3 자 라이브러리를 사용하여 .zip 아카이브에서 .xml 파일을 추출합니다. OpenXLSX에서 사용하는 기본 라이브러리는 Zippy이며 Miniz 주변의 객체 지향 래퍼입니다. 미니즈 라이브러리는 빠르며 헤더 전용이며 OpenXLSX에 이상적입니다.
그러나 원하는 경우 다른 zip-library를 사용할 수 있습니다. 드문 경우, 미니 즈에서 안정성 문제가 발생할 수 있습니다. 이 경우 다른 지퍼 라이브러리를 시도하는 것이 유용 할 수 있습니다.
Zippy/Miniz 라이브러리를 사용하면 특별한 노력이 필요하지 않습니다. 상자에서 바로 작동합니다. 그러나 다른 zip-library를 사용하려면 약간의 작업이 필요합니다.
다른 zip-library를 사용하려면 iziparchive 클래스에서 지정된 인터페이스를 준수하는 래퍼 클래스를 만들어야합니다. 이것은 유형 삭제를 사용하여 구현되며, 이는 상속이 필요하지 않음을 의미합니다. 클래스는 단지 일치하는 인터페이스가 있어야합니다. 그 후 클래스의 객체를 제공하고 OpenXLSX 생성자에 제공하십시오.
이것이 어떻게 수행되는지에 대한 예를 보려면 예제 폴더에서 demo1a를 살펴보십시오. 이 예제는 예제/외부/customZip에서 찾을 수있는 customzip (libzip을 zip 라이브러리로 사용)라는 클래스를 사용합니다. 예제 프로그램을 구축하려면 Libzip (및 종속성)이 컴퓨터에 설치되어 있는지 확인하고 OpenXLSX 루트의 cmakelists.txt 파일에서 OpenXlsx_enable_libzip 옵션을 활성화하십시오.
언급했듯이 Demo1a 예제 프로그램은 libzip을 사용합니다. Libzip은 매우 안정적인 라이브러리이며 널리 사용됩니다. 그러나 내 경험은 큰 스프레드 시트와 같은 대형 지퍼 파일의 경우 상당히 느리다는 것입니다. 이러한 이유로 Libzip은 이상적인 솔루션이 아닐 수도 있지만 다른 Zip 라이브러리를 어떻게 사용하는지 보여주는 데 유용합니다.
'예제'폴더에서는 OpenXLSX를 사용하는 방법을 보여주는 몇 가지 예제 프로그램을 찾을 수 있습니다. 이러한 예제 프로그램을 연구하는 것은 OpenXLSX를 사용하는 방법을 배우는 가장 좋은 방법입니다. 예제 프로그램은 주석이 달리므로 무슨 일이 일어나고 있는지 이해하기가 상대적으로 쉽습니다.
OpenXLSX는 이제 기본 ZIPPY/MINIZ 라이브러리보다 다른 ZIP 라이브러리를 사용할 수 있습니다. demo1a를 어떻게 수행했는지에 대한 예로 참조하십시오
이 버전에는 행 범위와 반복자가 포함되어 있습니다. 또한 XLROW 객체에 셀 값의 컨테이너 할당을 지원합니다. 이것은 세포 범위를 사용하거나 세포 참조에 의해 세포에 접근하는 것보다 훨씬 더 빠릅니다 (최대 x2).
OpenXLSX의 내부 아키텍처는 이전 버전 이후 크게 다시 디자인되었습니다. 그 이유는 도서관이 큰 진흙 공로 바뀌고 있었기 때문에 기능을 추가하고 버그를 수정하는 것이 점점 어려워 졌기 때문입니다. 새로운 아키텍처를 사용하면 관리가 더 쉽게 관리하고 새로운 기능을 추가 할 수 있습니다.
아키텍처의 재 설계로 인해 공개 인터페이스에 몇 가지 변경 사항이 있습니다. 그러나 이러한 변경 사항은 중요하지 않으며 업데이트하기 쉽습니다.
이러한 변경으로 인해 일부 사용자에게 문제가 발생할 수 있습니다. 이 때문에 OpenXLSX의 이전 버전은이 저장소의 "레거시"브랜치에서 찾을 수 있습니다. 그러나 대신 새 버전으로 전환하는 것이 좋습니다.
MS Office는 <mergeCells> XML 노드 이전에 XML 노드를 형식화하지 않는 것으로 보입니다. 오류 메시지를 제거하기 위해 최신 커밋은 XLSheet::merges 기능을 수정하여 <sheetData> 노드 직후에 새로 작성된 <mergeCells> 노드를 삽입합니다.
이러한 누락 된 기본값은 나중에이 셀의 스타일 인덱스가 인덱스별로 상기 스타일에 액세스하는 데 유효한 것으로 가정 될 때 후속 오류로 이어질 수 있습니다 (인덱스가 유효한 범위에 있지 않은 경우 예외). 셀 형식으로 제공되는 모든 스타일 인덱스는 이제 제로 시작화되었습니다 (인덱스 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 기본 경로 xl/workbook.xml이있는 통합 문서가 아카이브에 존재하는 경우에만 _rels/.rels 에서 누락 된 통합 문서 관계를 만듭니다.XLDocument::create 및 XLDocument::saveAs 함수 인터페이스를 다시 만들지 만 [[deprecated]] 로 표시했습니다. 새로운 인터페이스에는 XLForceOverwrite 또는 XLDoNotOverwrite 의 명시 적 사양이 필요합니다. 감가 상각 된 기능 정의를 제거 할 수 있으면 XLDoNotOverwrite 새로운 기본값이 될 수 있습니다.OpenXLSX/external/nowide/nowideDemo0 제거 / 테스트 차량으로 makefile에 보관했습니다.Notes 폴더xml-format.sh 로 Scripts 폴더를 작성했습니다 (XML Linting, 텍스트 편집기에서 XLSX ZIP 컨텐츠를 분석하는 데 유용함)make-gnu.sh Scripts/make-gnu.sh 로 옮겼습니다Scripts/cmake-cleanup.sh 추가 된 명령.Scripts/demos-cleanup.sh 추가 된 데모에서 생성 된 모든 XLSX 파일을 제거합니다.class XLXmlSavingDeclaration ( XLXmlData.hpp 에서 정의)를 사용하여 void setSavingDeclaration(XLXmlSavingDeclaration const& savingDeclaration) 에 대한 지원 사용자 정의 XML 버전, 인코딩 및 독립 속성을 pugixml로 전달하는 데 사용할 수 있습니다.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) - rangereference에 의해 정의 된 셀 병합 셀void unmergeCells(XLCellRange const& rangeToUnmerge) - rangetounmerge에 의해 정의 된 Unmerge 셀void unmergeCells(const std::string& rangeReference) - rangereference에 의해 정의 된 Unmerge 셀 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) - 색인에서 merge 참조 문자열 가져 오기const char* operator[](int32_t index) - 연산자의 과부하 []int32_t appendMerge(const std::string& reference) - xlworksheet :: mergecells에 의해 호출 된 새로운 병합 정의void deleteMerge(int32_t index) - xlworksheet :: unmergecells에 의해 호출 된 워크 시트 (= unmerge 셀)에서 주어진 인덱스와의 병합 삭제 이 기능의 예제 사용을 Demo10.cpp 에 추가했습니다
XLDocument::open 이제 알 수없는 서브 폴더를 무시합니다 (메모리의 지퍼에서는 수정되지 않고 접근 할 수 없으며 저장시 보관소에 머물러 있습니다). 이렇게하면이 라이브러리에 알려지지 않은 항목을 추가 한 "Creative"응용 프로그램에서 작성한 XLSX 파일에 대한 예외가 발생하지 않습니다.const unsigned int pugi_parse_settings 에서 constexpr 만들어 XLDocument.hpp 로 옮겨서 const가 xlstyles 및 xlsharedstrings에 사용할 수 있도록XLStyles 클래스에서 워크 시트 스타일에 대한 구현 - 인터페이스는 OpenXLSX/headers/XLStyles.hpp 에서 찾을 수 있습니다.Examples/Demo10.cpp 새로운 xlstyles 및 셀 병합 기능의 사용을 보여줍니다.XLCellIterator 에 대한 지원 : 이제 범위를 반복하고 XLCellIterator::cellExists 에 액세스하기 전에 테스트 할 수 있습니다. 이를 통해 존재하지 않는 셀을 생성하지 않고 건너 뛸 수 있습니다.workbook##.xml , XML 네임 스페이스 및 임의의 64 비트 (관계) 식별자 지원xl/workbook.xml )이 _rels/.rels 에서 올바르게 참조되면 이제 허용됩니다.bool OpenXLSX::enable_xml_namespaces() 네임 스페이스 x (예 : <x:row r="1"> >를 사용하여 문서를 열기 전에 네임 스페이스 지원을 활성화하는 데 사용해야합니다.<y:sheetData> 노드의 insert_child_before("x:row", curRow ) 는 x: <y:row> 라는 행 요소를 삽입하여 상위 노드의 네임 스페이스를 사용합니다.OpenXLSX/headers/XLXmlParser.hpp 참조)는 마지막으로 마지막 인수를 사용하여 Node Creation/Access의 기능에 전달 된 네임 스페이스를 존중하는 bool force_ns 를 선택합니다. 도우미 const bool OpenXLSX::XLForceNamespace = true 코드 가독성에 사용할 수 있습니다.XMLNode::insert_child_before("x:row", curRow, XLForceNamespace) <y:sheetData> node 위와 같이 x:row 라는 행 요소를 삽입합니다.id="rId##" 양식에 저장되어 ## 이 시퀀스 번호 인 경우, 새로운 구성 요소가 통합 문서에 추가되면 통합 문서 내에서 가장 높은 기존 값을 가져 와서 +1을 추가하여 새로운 관계 ID를 결정합니다. [#254]를 조사하는 동안 통합 문서 r:id="Rxx" 형식에 저장된 무작위 64 비트 정수를 사용하는 것으로 밝혀졌으며 xx 는 64 비트 정수의 16 진수 표현입니다.OpenXLSX::UseRandomIDs() 호출하여 해당 문서를 열기 전에 ID 기능을 전환해야합니다.OpenXLSX::UseSequentialIDs() 사용하여 기본값 (순차적) 관계 ID 기능을 복원 할 수 있습니다. enable_xml_namespaces : 네임 스페이스 지원은 투명 하며 이러한 네임 스페이스를 사용하지 않는 문서와 함께 사용할 수 있습니다. 그러나 대규모 통합 문서에 적은 성능 (<5%) 성능에 영향을 줄 수 있으므로 활성화 할 수 있습니다.
UseRandomIDs 와의 주의 : 임의의 ID 지원을 통해 하나의 문서가 열리고 순차적 관계 ID가없는 혼합 모드가 당분간 지원되지 않습니다. 다른 유형의 문서를 사용해야하는 경우 다음 문서에 대해 원하는 관계 ID 동작을 항상 구성하고 다음 문서를 열기 전에 관계 ID 구성을 변경해야합니다.
예제/demo0.cpp 및 예제/demo9.cpp를 무시하십시오 (Demo0은 사소하고 비표준 통합 문서 지원을 테스트하는 데 사용되었으며 Demo9는 더 나은 의견을 가진 검토가 필요합니다). Demo9는 새로운 xlcellassignable에 복사 할당 셀 내용물 (Excel Copy & Paste)을 사용하는 방법을 보여줍니다.
XLCellIterator 더 이상 빈 셀을 반복하기 위해 빈 셀을 생성하지 않고 다음을 제공합니다 ::cellExists()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. In short: