From 474a500819d5f63f010d05f363b72baaa1c6ebb4 Mon Sep 17 00:00:00 2001 From: K1rillProkhorov <138659631+K1rillProkhorov@users.noreply.github.com> Date: Thu, 31 Aug 2023 18:15:27 +0300 Subject: [PATCH 001/318] Add compound file to checker --- Common/OfficeFileFormatChecker.h | 1 + Common/OfficeFileFormatChecker2.cpp | 14 ++++++++ Common/OfficeFileFormats.h | 1 + X2tConverter/src/ASCConverters.cpp | 36 ++++++++++++++++++++ X2tConverter/src/cextracttools.h | 51 +++++++++++++++-------------- 5 files changed, 79 insertions(+), 24 deletions(-) diff --git a/Common/OfficeFileFormatChecker.h b/Common/OfficeFileFormatChecker.h index ca923d8ba6..27f5517994 100644 --- a/Common/OfficeFileFormatChecker.h +++ b/Common/OfficeFileFormatChecker.h @@ -75,6 +75,7 @@ public: bool isDocFormatFile (POLE::Storage *storage); bool isXlsFormatFile (POLE::Storage *storage); bool isPptFormatFile (POLE::Storage *storage); + bool isCompoundFile (POLE::Storage* storage); bool isMS_OFFICECRYPTOFormatFile(POLE::Storage * storage, std::wstring & documentID); bool isMS_MITCRYPTOFormatFile(POLE::Storage * storage, std::wstring & documentID); bool isVbaProjectFile(POLE::Storage * storage); diff --git a/Common/OfficeFileFormatChecker2.cpp b/Common/OfficeFileFormatChecker2.cpp index 2049ad80e9..ccbca1d3d2 100644 --- a/Common/OfficeFileFormatChecker2.cpp +++ b/Common/OfficeFileFormatChecker2.cpp @@ -313,6 +313,15 @@ bool COfficeFileFormatChecker::isPptFormatFile (POLE::Storage * storage) return true; } +bool COfficeFileFormatChecker::isCompoundFile(POLE::Storage* storage) +{ + if (storage == NULL) return false; + + if (storage->GetAllStreams(L"/").size() == 1) return true; + + return false; +} + std::wstring COfficeFileFormatChecker::getDocumentID (const std::wstring & _fileName ) { #if defined(_WIN32) || defined(_WIN32_WCE) || defined(_WIN64) @@ -499,6 +508,11 @@ bool COfficeFileFormatChecker::isOfficeFile(const std::wstring & _fileName) nFileType = AVS_OFFICESTUDIO_FILE_OTHER_MS_VBAPROJECT; return true; } + else if (isCompoundFile(&storage)) + { + nFileType = AVS_OFFICESTUDIO_FILE_OTHER_COMPOUND; + return true; + } } COfficeUtils OfficeUtils(NULL); diff --git a/Common/OfficeFileFormats.h b/Common/OfficeFileFormats.h index c102a2a327..215d9b00b6 100644 --- a/Common/OfficeFileFormats.h +++ b/Common/OfficeFileFormats.h @@ -125,6 +125,7 @@ #define AVS_OFFICESTUDIO_FILE_OTHER_ODF AVS_OFFICESTUDIO_FILE_OTHER + 0x000a #define AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO AVS_OFFICESTUDIO_FILE_OTHER + 0x000b #define AVS_OFFICESTUDIO_FILE_OTHER_MS_VBAPROJECT AVS_OFFICESTUDIO_FILE_OTHER + 0x000c +#define AVS_OFFICESTUDIO_FILE_OTHER_COMPOUND AVS_OFFICESTUDIO_FILE_OTHER + 0x000d #define AVS_OFFICESTUDIO_FILE_TEAMLAB 0x1000 #define AVS_OFFICESTUDIO_FILE_TEAMLAB_DOCY AVS_OFFICESTUDIO_FILE_TEAMLAB + 0x0001 diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 7853694e89..65a4695c16 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -5223,6 +5223,38 @@ namespace NExtractTools return nRes; } + _UINT32 compound2docxdir(const std::wstring& sFrom, const std::wstring& sTo, const std::wstring& sTemp, InputParams& params) + { + POLE::Storage storage(sFrom.c_str()); + + if (storage.open()) + { + POLE::Stream stream(&storage, storage.GetAllStreams(L"/").front()); + + POLE::uint64 stream_size = stream.size(); + + unsigned char* buffer = new unsigned char[stream_size]; + if (buffer) + { + stream.read(buffer, stream_size); + std::wstring sTempDocxDir = sTemp + FILE_SEPARATOR_STR + L"tempdocx.docx"; + + NSFile::CFileBinary file; + + if (file.CreateFileW(sTempDocxDir)) + { + file.WriteFile(buffer, stream_size); + file.CloseFile(); + } + delete[]buffer; + + return 0; + } + } + + return AVS_FILEUTILS_ERROR_CONVERT; + } + //------------------------------------------------------------------------------------------------------------------ _UINT32 detectMacroInFile(InputParams& oInputParams) { @@ -5772,6 +5804,10 @@ namespace NExtractTools { result = msVbaProject2Xml(sFileFrom, sFileTo, sTempDir, oInputParams); }break; + case TCD_COMPOUND2DOCX: + { + result = compound2docxdir(sFileFrom, sFileTo, sTempDir, oInputParams); + } //TCD_FB22DOCT, //TCD_FB22DOCT_BIN, diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index 53ee3b951a..ab9dc2893a 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -139,6 +139,7 @@ namespace NExtractTools TCD_DOC2DOCT_BIN, TCD_DOC2DOCX, TCD_DOC2DOCM, + TCD_COMPOUND2DOCX, //xls 2 TCD_XLS2XLST, TCD_XLS2XLST_BIN, @@ -920,41 +921,43 @@ namespace NExtractTools if (TCD_AUTO != eRes) return eRes; - if (NULL != m_oMailMergeSend) - eRes = TCD_MAILMERGE; + if (NULL != m_oMailMergeSend) + eRes = TCD_MAILMERGE; else if ((AVS_OFFICESTUDIO_FILE_DOCUMENT_XML == nFormatFrom) && 0 != (AVS_OFFICESTUDIO_FILE_OTHER & nFormatTo)) eRes = TCD_NON_AUTO; // параметры требуют уточнений - else if ((AVS_OFFICESTUDIO_FILE_DOCUMENT_XML == nFormatFrom) && (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatTo) || - (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == nFormatTo))) + else if ((AVS_OFFICESTUDIO_FILE_DOCUMENT_XML == nFormatFrom) && (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatTo) || + (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == nFormatTo))) eRes = TCD_SPREADSHEET2; else if (0 != (AVS_OFFICESTUDIO_FILE_DOCUMENT & nFormatFrom)) - eRes = TCD_DOCUMENT2; - else if (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatFrom)) - eRes = TCD_SPREADSHEET2; - else if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatFrom)) - eRes = TCD_PRESENTATION2; - else if (0 != (AVS_OFFICESTUDIO_FILE_TEAMLAB & nFormatFrom)) - eRes = TCD_T2; - else if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == nFormatFrom) - eRes = TCD_DOCT_BIN2; - else if (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == nFormatFrom) - eRes = TCD_XLST_BIN2; - else if (AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION == nFormatFrom) - eRes = TCD_PPTT_BIN2; - else if (0 != (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM & nFormatFrom)) - eRes = TCD_CROSSPLATFORM2; - else if (AVS_OFFICESTUDIO_FILE_CANVAS_PDF == nFormatFrom) - eRes = TCD_CANVAS_PDF2; + eRes = TCD_DOCUMENT2; + else if (0 != (AVS_OFFICESTUDIO_FILE_SPREADSHEET & nFormatFrom)) + eRes = TCD_SPREADSHEET2; + else if (0 != (AVS_OFFICESTUDIO_FILE_PRESENTATION & nFormatFrom)) + eRes = TCD_PRESENTATION2; + else if (0 != (AVS_OFFICESTUDIO_FILE_TEAMLAB & nFormatFrom)) + eRes = TCD_T2; + else if (AVS_OFFICESTUDIO_FILE_CANVAS_WORD == nFormatFrom) + eRes = TCD_DOCT_BIN2; + else if (AVS_OFFICESTUDIO_FILE_CANVAS_SPREADSHEET == nFormatFrom) + eRes = TCD_XLST_BIN2; + else if (AVS_OFFICESTUDIO_FILE_CANVAS_PRESENTATION == nFormatFrom) + eRes = TCD_PPTT_BIN2; + else if (0 != (AVS_OFFICESTUDIO_FILE_CROSSPLATFORM & nFormatFrom)) + eRes = TCD_CROSSPLATFORM2; + else if (AVS_OFFICESTUDIO_FILE_CANVAS_PDF == nFormatFrom) + eRes = TCD_CANVAS_PDF2; else if (AVS_OFFICESTUDIO_FILE_OTHER_MS_OFFCRYPTO == nFormatFrom) eRes = TCD_MSCRYPT2; else if (AVS_OFFICESTUDIO_FILE_OTHER_MS_MITCRYPTO == nFormatFrom) eRes = TCD_MITCRYPT2; - else if (AVS_OFFICESTUDIO_FILE_OTHER_ZIP == nFormatFrom && AVS_OFFICESTUDIO_FILE_UNKNOWN == nFormatTo) - eRes = TCD_UNZIPDIR; + else if (AVS_OFFICESTUDIO_FILE_OTHER_ZIP == nFormatFrom && AVS_OFFICESTUDIO_FILE_UNKNOWN == nFormatTo) + eRes = TCD_UNZIPDIR; else if (AVS_OFFICESTUDIO_FILE_OTHER_MS_VBAPROJECT == nFormatFrom && AVS_OFFICESTUDIO_FILE_UNKNOWN == nFormatTo) eRes = TCD_VBAPROJECT2XML; else if (AVS_OFFICESTUDIO_FILE_UNKNOWN == nFormatFrom && AVS_OFFICESTUDIO_FILE_OTHER_ZIP == nFormatTo) - eRes = TCD_ZIPDIR; + eRes = TCD_ZIPDIR; + else if (AVS_OFFICESTUDIO_FILE_OTHER_COMPOUND == nFormatFrom) + eRes = TCD_COMPOUND2DOCX; } else eRes = TCD_ERROR; From 0fcf29eddc9676f67cf48bf77b37356d527cd4ea Mon Sep 17 00:00:00 2001 From: K1rillProkhorov <138659631+K1rillProkhorov@users.noreply.github.com> Date: Fri, 1 Sep 2023 18:01:58 +0300 Subject: [PATCH 002/318] fix compound converter --- X2tConverter/src/ASCConverters.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 65a4695c16..9ecdd7c426 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -5247,6 +5247,10 @@ namespace NExtractTools file.CloseFile(); } delete[]buffer; + + InputParams newparams = params; + newparams.m_sFileFrom = &sTempDocxDir; + fromInputParams(params); return 0; } From d6ed01e1dff1dfda72ef2bf9c6da9d5dc643efe7 Mon Sep 17 00:00:00 2001 From: K1rillProkhorov <138659631+K1rillProkhorov@users.noreply.github.com> Date: Mon, 4 Sep 2023 12:25:28 +0300 Subject: [PATCH 003/318] fix compound2 function --- X2tConverter/src/ASCConverters.cpp | 14 ++++++++------ X2tConverter/src/cextracttools.h | 4 ++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 9ecdd7c426..f0ff7ddc54 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -4310,7 +4310,10 @@ namespace NExtractTools { nRes = mht2docx_dir(sFrom, sDocxDir, sTemp, params); } - else + else if (AVS_OFFICESTUDIO_FILE_OTHER_COMPOUND == nFormatFrom) + { + nRes = compound2(sFrom, sDocxDir, sTemp, params); + } nRes = AVS_FILEUTILS_ERROR_CONVERT_PARAMS; if (SUCCEEDED_X2T(nRes)) { @@ -5223,7 +5226,7 @@ namespace NExtractTools return nRes; } - _UINT32 compound2docxdir(const std::wstring& sFrom, const std::wstring& sTo, const std::wstring& sTemp, InputParams& params) + _UINT32 compound2(const std::wstring& sFrom, const std::wstring& sTo, const std::wstring& sTemp, InputParams& params) { POLE::Storage storage(sFrom.c_str()); @@ -5250,9 +5253,8 @@ namespace NExtractTools InputParams newparams = params; newparams.m_sFileFrom = &sTempDocxDir; - fromInputParams(params); - return 0; + return fromInputParams(params) && file.Remove(sTempDocxDir); } } @@ -5808,9 +5810,9 @@ namespace NExtractTools { result = msVbaProject2Xml(sFileFrom, sFileTo, sTempDir, oInputParams); }break; - case TCD_COMPOUND2DOCX: + case TCD_COMPOUND2: { - result = compound2docxdir(sFileFrom, sFileTo, sTempDir, oInputParams); + result = compound2(sFileFrom, sFileTo, sTempDir, oInputParams); } //TCD_FB22DOCT, //TCD_FB22DOCT_BIN, diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index ab9dc2893a..efc109bc4f 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -139,7 +139,7 @@ namespace NExtractTools TCD_DOC2DOCT_BIN, TCD_DOC2DOCX, TCD_DOC2DOCM, - TCD_COMPOUND2DOCX, + TCD_COMPOUND2, //xls 2 TCD_XLS2XLST, TCD_XLS2XLST_BIN, @@ -957,7 +957,7 @@ namespace NExtractTools else if (AVS_OFFICESTUDIO_FILE_UNKNOWN == nFormatFrom && AVS_OFFICESTUDIO_FILE_OTHER_ZIP == nFormatTo) eRes = TCD_ZIPDIR; else if (AVS_OFFICESTUDIO_FILE_OTHER_COMPOUND == nFormatFrom) - eRes = TCD_COMPOUND2DOCX; + eRes = TCD_COMPOUND2; } else eRes = TCD_ERROR; From 86a2d66d834c4cf1a3748aa103f9bc64650a0622 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 16 Jul 2025 19:13:12 +0600 Subject: [PATCH 004/318] Add xlsx2xls conversion --- OOXML/XlsxFormat/Xlsx.cpp | 17 +++++++++++++++++ OOXML/XlsxFormat/Xlsx.h | 1 + X2tConverter/src/ASCConverters.cpp | 5 +++++ X2tConverter/src/cextracttools.cpp | 4 +++- X2tConverter/src/cextracttools.h | 1 + X2tConverter/src/lib/xlsx.h | 28 ++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Xlsx.cpp b/OOXML/XlsxFormat/Xlsx.cpp index dfaac70855..122d43a755 100644 --- a/OOXML/XlsxFormat/Xlsx.cpp +++ b/OOXML/XlsxFormat/Xlsx.cpp @@ -58,6 +58,9 @@ #include "ComplexTypes_Spreadsheet.h" #include "../../DesktopEditor/common/SystemUtils.h" +#include "../../MsBinaryFile/XlsFile/Converter/xls_writer.h" +#include "../../MsBinaryFile/XlsFile/Format/Logic/WorkbookStreamObject.h" + OOX::Spreadsheet::CXlsx::CXlsx() : OOX::IFileContainer(dynamic_cast(this)) { init(); @@ -187,6 +190,20 @@ bool OOX::Spreadsheet::CXlsx::Write(const CPath& oDirPath, OOX::CContentTypes &o oContentTypes.Write(oDirPath); return true; } +bool OOX::Spreadsheet::CXlsx::WriteXLS(const CPath& oFilePath) +{ + PrepareToWrite(); + if(NULL == m_pWorkbook || m_arWorksheets.empty ()) + return false; + auto workbookStream = new XLS::WorkbookStreamObject; + auto workbookPtr = XLS::BaseObjectPtr(workbookStream); + XlsWriter writer; + //todo substreams conversion + + writer.Open(oFilePath.GetPath()); + writer.WriteWorkbook(workbookPtr); + return true; +} bool OOX::Spreadsheet::CXlsx::WriteWorkbook(const CPath& oDirPath) { //Theme diff --git a/OOXML/XlsxFormat/Xlsx.h b/OOXML/XlsxFormat/Xlsx.h index c5a782eaf6..58f01ab5c5 100644 --- a/OOXML/XlsxFormat/Xlsx.h +++ b/OOXML/XlsxFormat/Xlsx.h @@ -62,6 +62,7 @@ namespace OOX bool Read(const CPath& oFilePath); bool Write(const CPath& oDirPath, OOX::CContentTypes &oContentTypes); bool WriteWorkbook(const CPath& oDirPath); + bool WriteXLS(const CPath& oFilePath); bool ReadNative(const CPath& oFilePath); bool WriteNative(const CPath& oDirPath, OOX::CContentTypes &oContentTypes); diff --git a/X2tConverter/src/ASCConverters.cpp b/X2tConverter/src/ASCConverters.cpp index 3a6d6a90d7..3a67fcbb2d 100644 --- a/X2tConverter/src/ASCConverters.cpp +++ b/X2tConverter/src/ASCConverters.cpp @@ -2076,6 +2076,11 @@ namespace NExtractTools result = xls2xlsx(sFileFrom, sFileTo, oInputParams, oConvertParams); } break; + case TCD_XLSX2XLS: + { + result = xlsx2xls(sFileFrom, sFileTo, oInputParams, oConvertParams); + } + break; case TCD_XLS2XLSM: { result = xls2xlsm(sFileFrom, sFileTo, oInputParams, oConvertParams); diff --git a/X2tConverter/src/cextracttools.cpp b/X2tConverter/src/cextracttools.cpp index 9c5c992841..ec18d4304e 100644 --- a/X2tConverter/src/cextracttools.cpp +++ b/X2tConverter/src/cextracttools.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -281,6 +281,8 @@ namespace NExtractTools res = TCD_XLTM2XLSM; else if (0 == sExt2.compare(L".xlsb")) res = TCD_XLSX2XLSB; + else if (0 == sExt2.compare(L".xls")) + res = TCD_XLSX2XLS; } break; case AVS_OFFICESTUDIO_FILE_SPREADSHEET_XLSB: diff --git a/X2tConverter/src/cextracttools.h b/X2tConverter/src/cextracttools.h index 4892e54f71..b0b1c523e7 100644 --- a/X2tConverter/src/cextracttools.h +++ b/X2tConverter/src/cextracttools.h @@ -96,6 +96,7 @@ namespace NExtractTools TCD_XLSB2XLST, TCD_XLSX2XLSB, TCD_XLST2XLSB, + TCD_XLSX2XLS, TCD_PPTX2PPTT, TCD_PPTT2PPTX, diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 72eb0fe4b2..58762aca33 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -171,6 +171,17 @@ namespace NExtractTools return nRes; } + _UINT32 xlsx_dir2xls_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + _UINT32 nRes = S_OK; + const OOX::CPath oox_path(sFrom); + { + OOX::Spreadsheet::CXlsx oXlsx; + oXlsx.Read(oox_path); + nRes = oXlsx.WriteXLS(sTo)? S_OK : AVS_FILEUTILS_ERROR_CONVERT;; + } + return nRes; + } _UINT32 xlst_bin2xlsb_dir(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { @@ -378,6 +389,23 @@ namespace NExtractTools } return nRes; } + _UINT32 xlsx_dir2xls(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xls", xlsx_dir2xls_dir); + } + _UINT32 xlsx2xls(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) + { + std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); + NSDirectory::CreateDirectory(sTempUnpackedXLSX); + + COfficeUtils oCOfficeUtils(NULL); + _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0); + if (SUCCEEDED_X2T(nRes)) + { + nRes = xlsx_dir2xls(sTempUnpackedXLSX, sTo, params, convertParams); + } + return nRes; + } _UINT32 xml2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { return NSCommon::format2ooxml(sFrom, sTo, params, convertParams, L"xlsx", xml2xlsx_dir); From aa2127b55f0c68d86806ed407b4716c1c086b8e0 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 16 Jul 2025 20:28:40 +0600 Subject: [PATCH 005/318] Add bundlesheet conversion --- OOXML/XlsxFormat/Workbook/Sheets.cpp | 35 +++++++++++++++++++++++++- OOXML/XlsxFormat/Workbook/Sheets.h | 1 + OOXML/XlsxFormat/Workbook/Workbook.cpp | 11 ++++++++ OOXML/XlsxFormat/Workbook/Workbook.h | 1 + OOXML/XlsxFormat/Xlsx.cpp | 1 + 5 files changed, 48 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Workbook/Sheets.cpp b/OOXML/XlsxFormat/Workbook/Sheets.cpp index 6ab6c8bebd..86b1f83427 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.cpp +++ b/OOXML/XlsxFormat/Workbook/Sheets.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -33,6 +33,12 @@ #include "Sheets.h" #include "../../XlsbFormat/Biff12_records/BundleSh.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/BUNDLESHEET.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoundSheet8.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/RRTabId.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SheetId.h" + #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" @@ -212,6 +218,33 @@ namespace OOX objectVector.push_back(i->toBin()); return objectVector; } + void CSheets::toXLS(XLS::BaseObjectPtr stream) + { + auto streamPtr = static_cast(stream.get()); + auto tabIdArray = new XLS::RRTabId; + streamPtr->m_RRTabId = XLS::BaseObjectPtr(tabIdArray); + auto SheetNum = 1; + for(auto i: m_arrItems) + { + auto tempSheet = new XLS::BoundSheet8; + auto tempSheetUnion = new XLS::BUNDLESHEET; + tempSheetUnion->bundleSheetRecord = XLS::BaseObjectPtr(tempSheet); + { + XLS::SheetIdPtr element(new XLS::SheetId); + if(i->m_oSheetId.IsInit()) + element->id = i->m_oSheetId->GetValue(); + else + element->id = SheetNum; + tabIdArray->sheet_ids.push_back(element); + } + if(i->m_oName.IsInit()) + tempSheet->name_ = i->m_oName.get(); + else + tempSheet->name_ = std::wstring(L"sheet" + std::to_wstring(SheetNum)); + streamPtr->m_arBUNDLESHEET.push_back(XLS::BaseObjectPtr(tempSheetUnion)); + SheetNum++; + } + } EElementType CSheets::getType () const { return et_x_Sheets; diff --git a/OOXML/XlsxFormat/Workbook/Sheets.h b/OOXML/XlsxFormat/Workbook/Sheets.h index e0978d5264..25ddb6cbb4 100644 --- a/OOXML/XlsxFormat/Workbook/Sheets.h +++ b/OOXML/XlsxFormat/Workbook/Sheets.h @@ -97,6 +97,7 @@ namespace OOX void fromBin(std::vector& obj); std::vector toBin(); + void toXLS(XLS::BaseObjectPtr stream); virtual EElementType getType () const; static void AddSheetRef(const std::wstring& link, const _INT32& sheetIndex); private: diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index e02ba8919d..4f6da0c7fd 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -55,6 +55,8 @@ #include "../../XlsbFormat/Biff12_unions/FRTWORKBOOK.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalWorkbookInfo.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/WorkbookStreamObject.h" #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" @@ -441,6 +443,15 @@ namespace OOX } return workBookStream; } + XLS::BaseObjectPtr CWorkbook::toXLS() const + { + auto globalsSubstream = new XLS::GlobalsSubstream(XLS::WorkbookStreamObject::DefaultCodePage); + auto objectPtr = XLS::BaseObjectPtr(globalsSubstream); + if(m_oSheets.IsInit()) + m_oSheets->toXLS(objectPtr); + + return objectPtr; + } void CWorkbook::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) diff --git a/OOXML/XlsxFormat/Workbook/Workbook.h b/OOXML/XlsxFormat/Workbook/Workbook.h index 7d21038013..e50abe340b 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.h +++ b/OOXML/XlsxFormat/Workbook/Workbook.h @@ -129,6 +129,7 @@ namespace OOX void readBin(const CPath& oPath); XLS::BaseObjectPtr WriteBin() const; + XLS::BaseObjectPtr toXLS() const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void fromXML(XmlUtils::CXmlNode& node); diff --git a/OOXML/XlsxFormat/Xlsx.cpp b/OOXML/XlsxFormat/Xlsx.cpp index 122d43a755..aa3cee3a94 100644 --- a/OOXML/XlsxFormat/Xlsx.cpp +++ b/OOXML/XlsxFormat/Xlsx.cpp @@ -198,6 +198,7 @@ bool OOX::Spreadsheet::CXlsx::WriteXLS(const CPath& oFilePath) auto workbookStream = new XLS::WorkbookStreamObject; auto workbookPtr = XLS::BaseObjectPtr(workbookStream); XlsWriter writer; + workbookStream->m_GlobalsSubstream = m_pWorkbook->toXLS(); //todo substreams conversion writer.Open(oFilePath.GetPath()); From 7a2944ce58e6bfbc7b6dd0520124f2b206aeb21a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 17 Jul 2025 15:26:34 +0600 Subject: [PATCH 006/318] Add defined names conversion --- OOXML/XlsxFormat/Workbook/DefinedNames.cpp | 41 ++++++++++++++++++++++ OOXML/XlsxFormat/Workbook/DefinedNames.h | 2 ++ OOXML/XlsxFormat/Workbook/Workbook.cpp | 2 ++ 3 files changed, 45 insertions(+) diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp index f65841d17f..a5c5b88868 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.cpp +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.cpp @@ -33,6 +33,9 @@ #include "DefinedNames.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Lbl.h" + #include "../../Common/SimpleTypes_Shared.h" namespace OOX @@ -150,6 +153,37 @@ namespace OOX ptr->fBuiltin = false; return objectPtr; } + XLS::BaseObjectPtr CDefinedName::toXLS() + { + auto name = new XLS::Lbl; + auto namePtr = XLS::BaseObjectPtr(name); + if(m_oHidden.IsInit()) + name->fHidden = m_oHidden->GetValue(); + if(m_oFunction.IsInit()) + name->fFunc = m_oFunction->GetValue(); + if(m_oVbProcedure.IsInit()) + { + name->fOB = m_oVbProcedure->GetValue(); + name->fProc = m_oVbProcedure->GetValue(); + } + if (m_oName.IsInit()) + name->Name_bin = m_oName.get(); + else + name->Name_bin = L""; + if(m_oLocalSheetId.IsInit()) + name->itab = m_oLocalSheetId->GetValue(); + if(m_oPublishToServer.IsInit()) + name->fPublished = m_oPublishToServer->GetValue(); + if(m_oFunctionGroupId.IsInit()) + name->fGrp = m_oFunctionGroupId->GetValue(); + if(m_oWorkbookParameter.IsInit()) + name->fWorkbookParam = m_oWorkbookParameter->GetValue(); + + if(m_oRef.IsInit()) + name->rgce.parseStringFormula(m_oRef.get(), L""); + + return namePtr; + } void CDefinedName::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); @@ -275,6 +309,13 @@ namespace OOX return objectVector; } + void CDefinedNames::toXLS(XLS::BaseObjectPtr substream) + { + auto globalsSubstream = static_cast(substream.get()); + for(auto i:m_arrItems) + if(i->m_oName.IsInit() || i->m_oRef.IsInit()) + globalsSubstream->m_arLBL.push_back(i->toBin()); + } void CDefinedNames::fromBin(std::vector& obj) { //ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Workbook/DefinedNames.h b/OOXML/XlsxFormat/Workbook/DefinedNames.h index d612f0c67d..5ec66e87bc 100644 --- a/OOXML/XlsxFormat/Workbook/DefinedNames.h +++ b/OOXML/XlsxFormat/Workbook/DefinedNames.h @@ -61,6 +61,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); virtual EElementType getType () const; private: @@ -104,6 +105,7 @@ namespace OOX void fromBin(std::vector& obj); std::vector toBin(); + void toXLS(XLS::BaseObjectPtr substream); std::vector AddFutureFunctions(const _UINT32 namesStart); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 4f6da0c7fd..9911b3244d 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -449,6 +449,8 @@ namespace OOX auto objectPtr = XLS::BaseObjectPtr(globalsSubstream); if(m_oSheets.IsInit()) m_oSheets->toXLS(objectPtr); + if(m_oDefinedNames.IsInit()) + m_oDefinedNames->toXLS(objectPtr); return objectPtr; } From cfd1dcc3ee7d40b259e40678a775bb3d28a81ddf Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 17 Jul 2025 17:14:12 +0600 Subject: [PATCH 007/318] Add worksheets conversion --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 8 ++++++++ OOXML/XlsxFormat/Worksheets/Worksheet.h | 1 + OOXML/XlsxFormat/Xlsx.cpp | 3 ++- X2tConverter/src/lib/xlsx.h | 15 +-------------- 4 files changed, 12 insertions(+), 15 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 1685943a56..2c2dc13bd8 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -51,6 +51,7 @@ #include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" #include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/WorksheetSubstream.h" namespace OOX { @@ -359,6 +360,13 @@ namespace OOX } } + XLS::BaseObjectPtr CWorksheet::toXLS() const + { + auto worksheetPtr = new XLS::WorksheetSubstream(0); + auto sheetPtr = XLS::BaseObjectPtr(worksheetPtr); + + return sheetPtr; + } void CWorksheet::WriteBin(XLS::StreamCacheWriterPtr& writer) const { { diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.h b/OOXML/XlsxFormat/Worksheets/Worksheet.h index ffb0e556df..073b598814 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.h +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.h @@ -77,6 +77,7 @@ namespace OOX void readBin(const CPath& oPath); XLS::BaseObjectPtr WriteBin() const; + XLS::BaseObjectPtr toXLS() const; void WriteBin(XLS::StreamCacheWriterPtr& writer) const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); diff --git a/OOXML/XlsxFormat/Xlsx.cpp b/OOXML/XlsxFormat/Xlsx.cpp index aa3cee3a94..0d167c313f 100644 --- a/OOXML/XlsxFormat/Xlsx.cpp +++ b/OOXML/XlsxFormat/Xlsx.cpp @@ -200,7 +200,8 @@ bool OOX::Spreadsheet::CXlsx::WriteXLS(const CPath& oFilePath) XlsWriter writer; workbookStream->m_GlobalsSubstream = m_pWorkbook->toXLS(); //todo substreams conversion - + for(auto i : m_arWorksheets) + workbookStream->m_arWorksheetSubstream.push_back(i->toXLS()); writer.Open(oFilePath.GetPath()); writer.WriteWorkbook(workbookPtr); return true; diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 58762aca33..5d9d834edd 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -389,22 +389,9 @@ namespace NExtractTools } return nRes; } - _UINT32 xlsx_dir2xls(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) - { - return NSCommon::ooxml2ooxml(sFrom, sTo, params, convertParams, L"xls", xlsx_dir2xls_dir); - } _UINT32 xlsx2xls(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { - std::wstring sTempUnpackedXLSX = combinePath(convertParams.m_sTempDir, L"xlsx_unpacked"); - NSDirectory::CreateDirectory(sTempUnpackedXLSX); - - COfficeUtils oCOfficeUtils(NULL); - _UINT32 nRes = oCOfficeUtils.ExtractToDirectory(sFrom, sTempUnpackedXLSX, NULL, 0); - if (SUCCEEDED_X2T(nRes)) - { - nRes = xlsx_dir2xls(sTempUnpackedXLSX, sTo, params, convertParams); - } - return nRes; + return NSCommon::ooxml2format(sFrom, sTo, params, convertParams, L"xls", xlsx_dir2xls_dir); } _UINT32 xml2xlsx(const std::wstring& sFrom, const std::wstring& sTo, InputParams& params, ConvertParams& convertParams) { From e6158043b93f8f7436aed78ff49966f265b2a686 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 17 Jul 2025 18:42:22 +0600 Subject: [PATCH 008/318] add sheet data conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 75 +++++++++++++++++++++++ OOXML/XlsxFormat/Worksheets/SheetData.h | 3 + OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 3 + 3 files changed, 81 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 161352ad3a..0d4b812793 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -63,6 +63,9 @@ #include "../../XlsbFormat/Biff12_records/Cell.h" #include "../../XlsbFormat/Biff12_records/Fmla.h" #include "../../XlsbFormat/Biff12_structures/GrbitFmla.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h" @@ -2692,6 +2695,32 @@ namespace OOX oCell->iStyleRef = 0; return objectPtr; } + void CCell::toXLS(XLS::BaseObjectPtr cellPtr) + { + auto castedPtr = static_cast(cellPtr.get()); + XLS::CellRef CellReference; + if((!m_oRow.IsInit() || !m_oCol.IsInit())) + { + if(m_oRef.IsInit()) + { + std::wstring wstringRef(m_oRef.get().begin(), m_oRef.get().end()); + CellReference = XLS::CellRef(wstringRef); + m_oCol = CellReference.column; + } + else + { + CellReference.row = 0; + CellReference.column = 0; + } + } + else + { + CellReference.row = m_oRow.get() -1; + CellReference.column = m_oCol.get(); + } + castedPtr->RowNumber = CellReference.row; + castedPtr->ColumnNumber = CellReference.column; + } void CCell::toBin(XLS::StreamCacheWriterPtr& writer) { XLS::CellRef CellReference; @@ -4024,6 +4053,32 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CRow::toXLS() + { + auto rowPtr = new XLS::Row; + auto basePtr = XLS::BaseObjectPtr(rowPtr); + if(m_oR.IsInit()) + rowPtr->rw = m_oR->GetValue(); + if(m_oOutlineLevel.IsInit()) + rowPtr->iOutLevel = m_oOutlineLevel->GetValue(); + if(m_oHidden.IsInit()) + rowPtr->fDyZero = m_oHidden->GetValue(); + if(m_oCustomFormat.IsInit()) + rowPtr->fGhostDirty = m_oCustomFormat->GetValue(); + if(m_oS.IsInit()) + rowPtr->ixfe_val = m_oS->GetValue(); + if(m_oCustomHeight.IsInit()) + rowPtr->fUnsynced = m_oCustomHeight->GetValue(); + if(m_oHt.IsInit()) + rowPtr->miyRw = m_oHt->GetValue() * 20.; + if(m_oPh.IsInit()) + rowPtr->fPhonetic = m_oPh->GetValue(); + if(m_oThickBot.IsInit()) + rowPtr->fExDes = m_oThickBot->GetValue(); + if(m_oThickTop.IsInit()) + rowPtr->fExAsc = m_oThickTop->GetValue(); + return basePtr; + } void CRow::toBin(XLS::StreamCacheWriterPtr& writer) { WriteAttributes(writer); @@ -4799,6 +4854,26 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CSheetData::toXLS() + { + std::vector shared_formulas_locations_ref; + auto cellTable = new XLS::CELLTABLE(shared_formulas_locations_ref); + auto tablePtr = XLS::BaseObjectPtr(cellTable); + auto cellGroup = new XLS::CELL_GROUP(shared_formulas_locations_ref); + cellTable->m_arCellGroups.push_back(XLS::BaseObjectPtr(cellGroup)); + for(auto row : m_arrItems) + { + cellGroup->m_arRows.push_back(row->toXLS()); + for(auto cell : row->m_arrItems) + { + auto Cellptr = XLS::BaseObjectPtr(new XLS::CELL(shared_formulas_locations_ref)); + cell->toXLS(Cellptr); + cellGroup->m_arCells.push_back(Cellptr); + } + } + + return tablePtr; + } void CSheetData::toBin(XLS::StreamCacheWriterPtr& writer) { { diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index 2bea57af73..f6be4d1145 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -230,6 +230,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); bool fromBin(XLS::StreamCacheReaderPtr& reader); XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); + void toXLS(XLS::BaseObjectPtr cellPtr); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; @@ -309,6 +310,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); void fromBin(XLS::StreamCacheReaderPtr& reader); XLS::BaseObjectPtr toBin(sharedFormula &sharedFormulas); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); void WriteAttributes(XLS::StreamCacheWriterPtr& writer); //удалить хранимые ячейки и кэшировать данные для экономии памяти @@ -363,6 +365,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); void fromBin(XLS::StreamCacheReaderPtr& reader); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 2c2dc13bd8..ef0acdbec1 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -365,6 +365,9 @@ namespace OOX auto worksheetPtr = new XLS::WorksheetSubstream(0); auto sheetPtr = XLS::BaseObjectPtr(worksheetPtr); + if(m_oSheetData.IsInit()) + worksheetPtr->m_CELLTABLE = m_oSheetData->toXLS(); + return sheetPtr; } void CWorksheet::WriteBin(XLS::StreamCacheWriterPtr& writer) const From 05dd636a1cbee4f0716c4ae00fa896a6cbdd8d96 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 17 Jul 2025 21:36:00 +0600 Subject: [PATCH 009/318] Add cellType processing function --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 206 ++++++++-------------- 1 file changed, 75 insertions(+), 131 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 0d4b812793..eae16490ad 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -2108,6 +2108,74 @@ namespace OOX } oStream.Seek(nEnd); } + const SimpleTypes::Spreadsheet::ECellTypeType processCellType(const std::wstring &value,bool &isReal, double &realCache) + { + SimpleTypes::Spreadsheet::ECellTypeType cellType; + cellType = SimpleTypes::Spreadsheet::celltypeStr; + if(value != L"") + { + if(value == L"TRUE" || value == L"FALSE") + cellType = SimpleTypes::Spreadsheet::celltypeBool; + else if(std::all_of(value.begin(), value.end(), [](const char c) { return std::isdigit(c); }) && value.size() <= 10 && value.size() > 0) + { + if(value.size() < 10 ) + { + realCache = std::stoi(value); + cellType = SimpleTypes::Spreadsheet::celltypeNumber; + } + else if(value.size() == 10) + { + _INT64 tempVal = std::stoll(value); + if(tempVal < MAXINT32 && tempVal > MININT32) + { + realCache = tempVal; + cellType = SimpleTypes::Spreadsheet::celltypeNumber; + } + } + } + + if((value.find(L".") == std::string::npos || value.find(L".") == value.rfind(L".")) + && value.size() <=17 && value.size() > 0) + { + if(value.size() < 17) + { + wchar_t *tail; + double tempVal = std::wcstod(value.c_str(), &tail); + if(*tail == L'\0') + { + cellType = SimpleTypes::Spreadsheet::celltypeNumber; + isReal = true; + realCache = tempVal; + } + } + else + { + wchar_t *tail; + long double tempVal = std::wcstold(value.c_str(), &tail); + if(*tail == L'\0') + if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) + { + cellType = SimpleTypes::Spreadsheet::celltypeNumber; + realCache = tempVal; + isReal = true; + } + } + } + else if((value.find(L"E") == std::string::npos || value.find(L"E") == value.rfind(L"E"))) + { + wchar_t *tail; + long double tempVal = std::wcstold(value.c_str(), &tail); + if(*tail == L'\0') + if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) + { + cellType = SimpleTypes::Spreadsheet::celltypeNumber; + realCache = tempVal; + isReal = true; + } + } + } + return cellType; + } XLS::BaseObjectPtr CCell::toBin(sharedFormula &sharedFormulas) { std::vector shared_formulas_locations_ref; @@ -2143,7 +2211,6 @@ namespace OOX BiffRecord* pSource = nullptr; XLSB::Cell* oCell; bool isReal = false; - _INT32 intCache = 0; double realCache = 0; XLS::CellRef cellref; @@ -2174,69 +2241,8 @@ namespace OOX { m_oType.Init(); m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); - if(m_oValue.IsInit()) - { - if(m_oValue->m_sText == L"TRUE" || m_oValue->m_sText == L"FALSE") - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); - else if(std::all_of(m_oValue->m_sText.begin(), m_oValue->m_sText.end(), [](const char c) { return std::isdigit(c); }) && m_oValue->m_sText.size() <= 10 && m_oValue->m_sText.size() > 0) - { - if(m_oValue->m_sText.size() < 10 ) - { - intCache = std::stoi(m_oValue->m_sText); - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - } - else if(m_oValue->m_sText.size() == 10) - { - _INT64 tempVal = std::stoll(m_oValue->m_sText); - if(tempVal < MAXINT32 && tempVal > MININT32) - { - intCache = tempVal; - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - } - } - } - - if((m_oValue->m_sText.find(L".") == std::string::npos || m_oValue->m_sText.find(L".") == m_oValue->m_sText.rfind(L".")) - && m_oValue->m_sText.size() <=17 && m_oValue->m_sText.size() > 0) - { - if(m_oValue->m_sText.size() < 17) - { - wchar_t *tail; - double tempVal = std::wcstod(m_oValue->m_sText.c_str(), &tail); - if(*tail == L'\0') - { - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - isReal = true; - realCache = tempVal; - } - } - else - { - wchar_t *tail; - long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); - if(*tail == L'\0') - if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) - { - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - realCache = tempVal; - isReal = true; - } - } - } - else if((m_oValue->m_sText.find(L"E") == std::string::npos || m_oValue->m_sText.find(L"E") == m_oValue->m_sText.rfind(L"E"))) - { - wchar_t *tail; - long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); - if(*tail == L'\0') - if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) - { - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - realCache = tempVal; - isReal = true; - } - } - - } + if(m_oValue.IsInit()) + m_oType->SetValue(processCellType(m_oValue.get().m_sText, isReal, realCache)); } switch (m_oType->GetValue()) { @@ -2249,7 +2255,7 @@ namespace OOX auto pCellRk = new(XLSB::CellRk); pCellRk->value.fInt = 1; pCellRk->value.fX100 = 0; - pCellRk->value.num = intCache; + pCellRk->value.num = realCache; oCell = &pCellRk->cell; pSource = pCellRk; } @@ -2260,7 +2266,7 @@ namespace OOX pCellRk->grbitFlags.fAlwaysCalc = m_oFormula->m_oAca->GetValue(); else pCellRk->grbitFlags.fAlwaysCalc = false; - pCellRk->value.data.value = intCache; + pCellRk->value.data.value = realCache; oCell = &pCellRk->cell; pSource = pCellRk; } @@ -2758,75 +2764,13 @@ namespace OOX } } bool isReal = false; - _INT32 intCache = 0; double realCache = 0; if(!m_oType.IsInit()) { m_oType.Init(); m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); - if(m_oValue.IsInit()) - { - if(m_oValue->m_sText == L"TRUE" || m_oValue->m_sText == L"FALSE") - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeBool); - else if(std::all_of(m_oValue->m_sText.begin(), m_oValue->m_sText.end(), [](const char c) { return std::isdigit(c); }) && m_oValue->m_sText.size() <= 10 && m_oValue->m_sText.size() > 0) - { - if(m_oValue->m_sText.size() < 10 ) - { - intCache = std::stoi(m_oValue->m_sText); - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - } - else if(m_oValue->m_sText.size() == 10) - { - _INT64 tempVal = std::stoll(m_oValue->m_sText); - if(tempVal < MAXINT32 && tempVal > MININT32) - { - intCache = tempVal; - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - } - } - } - - if((m_oValue->m_sText.find(L".") == std::string::npos || m_oValue->m_sText.find(L".") == m_oValue->m_sText.rfind(L".")) - && m_oValue->m_sText.size() <=17 && m_oValue->m_sText.size() > 0) - { - if(m_oValue->m_sText.size() < 17) - { - wchar_t *tail; - double tempVal = std::wcstod(m_oValue->m_sText.c_str(), &tail); - if(*tail == L'\0') - { - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - isReal = true; - realCache = tempVal; - } - } - else - { - wchar_t *tail; - long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); - if(*tail == L'\0') - if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) - { - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - realCache = tempVal; - isReal = true; - } - } - } - else if((m_oValue->m_sText.find(L"E") == std::string::npos || m_oValue->m_sText.find(L"E") == m_oValue->m_sText.rfind(L"E"))) - { - wchar_t *tail; - long double tempVal = std::wcstold(m_oValue->m_sText.c_str(), &tail); - if(*tail == L'\0') - if(tempVal <= DBL_MAX && tempVal >= -DBL_MAX) - { - m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeNumber); - realCache = tempVal; - isReal = true; - } - } - - } + if(m_oValue.IsInit()) + m_oType->SetValue(processCellType(m_oValue.get().m_sText, isReal, realCache)); } auto cellType = m_oType->GetValue(); //основная запись ячейки @@ -2880,7 +2824,7 @@ namespace OOX XLS::RkNumber cellRk; cellRk.fInt = 1; cellRk.fX100 = 0; - cellRk.num = intCache; + cellRk.num = realCache; *CellRecord << cellRk; } break; From 07afc6e4c3438cb9cad8cafc28e676a632203e3f Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 18 Jul 2025 16:16:03 +0600 Subject: [PATCH 010/318] add simple cells conversion --- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 117 +++++++++++++++++++++- 1 file changed, 115 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index eae16490ad..338c6df0b8 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -66,6 +66,10 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h" @@ -2724,8 +2728,117 @@ namespace OOX CellReference.row = m_oRow.get() -1; CellReference.column = m_oCol.get(); } - castedPtr->RowNumber = CellReference.row; - castedPtr->ColumnNumber = CellReference.column; + bool isReal = false; + double realCache = 0; + if(!m_oType.IsInit()) + { + m_oType.Init(); + m_oType->SetValue(SimpleTypes::Spreadsheet::celltypeStr); + if(m_oValue.IsInit()) + m_oType->SetValue(processCellType(m_oValue.get().m_sText, isReal, realCache)); + } + auto cellType = m_oType->GetValue(); + + switch(cellType) + { + case SimpleTypes::Spreadsheet::celltypeNumber: + { + if(isReal || m_oFormula.IsInit()) + { + + auto cellNumber = new XLS::Number; + XLS::Xnum number; + number.data.value = realCache; + cellNumber->num = number; + cellNumber->cell.rw = CellReference.row; + cellNumber->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + cellNumber->cell.ixfe = m_oStyle.get(); + castedPtr->cellContent = XLS::BaseObjectPtr(cellNumber); + } + else + { + auto RkCell = new XLS::RK; + XLS::RkNumber cellRk; + cellRk.fInt = 1; + cellRk.fX100 = 0; + cellRk.num = realCache; + RkCell->rkrec.RK_ = cellRk; + RkCell->cell.rw = CellReference.row; + RkCell->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + RkCell->rkrec.ixfe = m_oStyle.get(); + castedPtr->cellContent = XLS::BaseObjectPtr(RkCell); + } + break; + } + case SimpleTypes::Spreadsheet::celltypeBool: + { + + auto BoolErrCell = new XLS::BoolErr; + BoolErrCell->cell.rw = CellReference.row; + BoolErrCell->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + BoolErrCell->cell.ixfe = m_oStyle.get(); + BYTE cellval = 0; + if(m_oValue.IsInit()) + cellval = m_oValue->m_sText == L"1" ? true : false; + BoolErrCell->bes.bBoolErr = cellval; + castedPtr->cellContent = XLS::BaseObjectPtr(BoolErrCell); + break; + } + case SimpleTypes::Spreadsheet::celltypeError: + { + + auto BoolErrCell = new XLS::BoolErr; + BoolErrCell->cell.rw = CellReference.row; + BoolErrCell->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + BoolErrCell->cell.ixfe = m_oStyle.get(); + BoolErrCell->bes.fError = true; + BYTE cellval = 0; + if(m_oValue.IsInit()) + { + if(m_oValue->m_sText == L"#NULL!") + cellval = 0x00; + else if (m_oValue->m_sText == L"#DIV/0!") + cellval = 0x07; + else if (m_oValue->m_sText == L"#VALUE!") + cellval = 0x0F; + else if (m_oValue->m_sText == L"#REF!") + cellval = 0x17; + else if (m_oValue->m_sText == L"#NAME?") + cellval = 0x1D; + else if (m_oValue->m_sText == L"#NUM!") + cellval = 0x24; + else if (m_oValue->m_sText == L"#N/A") + cellval = 0x2A; + else if (m_oValue->m_sText == L"#GETTING_DATA") + cellval = 0x2B; + } + BoolErrCell->bes.bBoolErr = cellval; + castedPtr->cellContent = XLS::BaseObjectPtr(BoolErrCell); + break; + } + case SimpleTypes::Spreadsheet::celltypeSharedString: + { + if(m_oValue.IsInit()) + { + auto CellSst = new XLS::LabelSst; + CellSst->cell.rw = CellReference.row; + CellSst->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + CellSst->cell.ixfe = m_oStyle.get(); + _UINT32 isst = 0; + isst = std::stoi(m_oValue->m_sText); + CellSst->isst = isst; + castedPtr->cellContent = XLS::BaseObjectPtr(CellSst); + } + break; + } + + } + } void CCell::toBin(XLS::StreamCacheWriterPtr& writer) { From 89473c5ba06e75e08604b529fd8bf9df78f61ae6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 18 Jul 2025 20:03:37 +0600 Subject: [PATCH 011/318] Add simple shared strings conversion --- .../SharedStrings/SharedStrings.cpp | 22 ++++++++++++++++++- .../XlsxFormat/SharedStrings/SharedStrings.h | 1 + OOXML/XlsxFormat/SharedStrings/Si.cpp | 21 ++++++++++++++++++ OOXML/XlsxFormat/SharedStrings/Si.h | 1 + OOXML/XlsxFormat/Xlsx.cpp | 3 +++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp index 136a189d72..659022d8f3 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -38,6 +38,12 @@ #include "../../XlsbFormat/Biff12_unions/SHAREDSTRINGS.h" #include "../../XlsbFormat/Biff12_records/SSTItem.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/WorkbookStreamObject.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/SST.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/SHAREDSTRINGS.h" + + #include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" namespace OOX @@ -123,6 +129,20 @@ namespace OOX } return objectPtr; } + void CSharedStrings::toXLS(XLS::BaseObjectPtr globalsSubstreamPtr) const + { + auto castedPtr = static_cast(globalsSubstreamPtr.get()); + auto SharedStringsObj = new XLS::SHAREDSTRINGS(XLS::WorkbookStreamObject::DefaultCodePage); + auto Sst = new XLS::SST(XLS::WorkbookStreamObject::DefaultCodePage); + SharedStringsObj->sstPtr = XLS::BaseObjectPtr(Sst); + + for(auto i:m_arrItems) + { + Sst->rgb.push_back(i->toXLS()); + } + + castedPtr->m_SHAREDSTRINGS = XLS::BaseObjectPtr(SharedStringsObj); + } void CSharedStrings::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) diff --git a/OOXML/XlsxFormat/SharedStrings/SharedStrings.h b/OOXML/XlsxFormat/SharedStrings/SharedStrings.h index e8c7b7d513..2d656b9ff6 100644 --- a/OOXML/XlsxFormat/SharedStrings/SharedStrings.h +++ b/OOXML/XlsxFormat/SharedStrings/SharedStrings.h @@ -55,6 +55,7 @@ namespace OOX void readBin(const CPath& oPath); XLS::BaseObjectPtr WriteBin() const; + void toXLS(XLS::BaseObjectPtr globalsSubstreamPtr) const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); virtual void write(const CPath& oPath, const CPath& oDirectory, CContentTypes& oContent) const; diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index c27e54d38b..64fa485fa0 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -32,6 +32,8 @@ #include "Si.h" #include "../../XlsbFormat/Biff12_records/SSTItem.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XLUnicodeRichExtendedString.h" + #include "../../Binary/Presentation/BinaryFileReaderWriter.h" namespace OOX @@ -186,6 +188,25 @@ namespace OOX return objectPtr; } + XLS::BiffStructurePtr CSi::toXLS() const + { + XLS::XLUnicodeRichExtendedString* StringPtr; + { + std::list cfRecordPtr;// just for construction + StringPtr = new XLS::XLUnicodeRichExtendedString(cfRecordPtr); + } + for(auto i = 0; i < m_arrItems.size(); i++) + { + if(m_arrItems[i]->getType() == OOX::et_x_t) + { + auto text = static_cast(m_arrItems[i]); + StringPtr->str_ = text->ToString(); + continue; + } + } + auto StructPtr = XLS::BiffStructurePtr(StringPtr); + return StructPtr; + } void CSi::fromBin(XLS::BiffStructure& obj, bool flagIsComment) { auto ptr = static_cast(&obj); diff --git a/OOXML/XlsxFormat/SharedStrings/Si.h b/OOXML/XlsxFormat/SharedStrings/Si.h index efdc78f6ce..d8680db278 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.h +++ b/OOXML/XlsxFormat/SharedStrings/Si.h @@ -64,6 +64,7 @@ namespace OOX void fromBin(XLS::BiffStructure& obj, bool flagIsComment = false); XLS::BaseObjectPtr toBin() const; + XLS::BiffStructurePtr toXLS() const; void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream); void toXLSBExt (NSBinPptxRW::CXlsbBinaryWriter& oStream); diff --git a/OOXML/XlsxFormat/Xlsx.cpp b/OOXML/XlsxFormat/Xlsx.cpp index 0d167c313f..63ae7df026 100644 --- a/OOXML/XlsxFormat/Xlsx.cpp +++ b/OOXML/XlsxFormat/Xlsx.cpp @@ -202,6 +202,9 @@ bool OOX::Spreadsheet::CXlsx::WriteXLS(const CPath& oFilePath) //todo substreams conversion for(auto i : m_arWorksheets) workbookStream->m_arWorksheetSubstream.push_back(i->toXLS()); + if(m_pSharedStrings != nullptr) + m_pSharedStrings->toXLS(workbookStream->m_GlobalsSubstream); + writer.Open(oFilePath.GetPath()); writer.WriteWorkbook(workbookPtr); return true; From c37f96da2d6efb26da8d00d223888b3257e83134 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 21 Jul 2025 19:20:37 +0600 Subject: [PATCH 012/318] Add formula conversion --- .../Format/Logic/Biff_unions/FORMULA.h | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 202 ++++++++++++------ OOXML/XlsxFormat/Worksheets/SheetData.h | 1 + 3 files changed, 138 insertions(+), 67 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h index 7974186e95..bb52d7885f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h @@ -35,7 +35,7 @@ #include "../Biff_structures/CellRef.h" #include "../Biff_structures/CellRangeRef.h" #include "../Biff_structures/BiffString.h" -#include "../Base/Nullable.h" +#include "../../../../OOXML/Base/Nullable.h" namespace XLS { diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 338c6df0b8..14379e51ad 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -65,11 +65,13 @@ #include "../../XlsbFormat/Biff12_structures/GrbitFmla.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELLTABLE.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/CELL.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMULA.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Row.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Number.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/RK.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/BoolErr.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/LabelSst.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Formula.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BIFF12/CellRef.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgArea.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgRef.h" @@ -1230,6 +1232,16 @@ namespace OOX } } + void CFormula::toXls(XLS::BaseObjectPtr& obj) + { + auto xlsFmla = static_cast(obj.get()); + if(m_oT.IsInit() && m_oT->GetValue() == SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared) + xlsFmla->fShrFmla = true; + if(m_oAca.IsInit()) + xlsFmla->fAlwaysCalc = m_oAca->GetValue(); + if(!m_sText.empty()) + xlsFmla->formula = m_sText; + } void CFormula::toBin(XLS::BaseObjectPtr& obj) { switch(m_oT->GetValue()) @@ -2738,64 +2750,139 @@ namespace OOX m_oType->SetValue(processCellType(m_oValue.get().m_sText, isReal, realCache)); } auto cellType = m_oType->GetValue(); - - switch(cellType) + if(!m_oFormula.IsInit()) { - case SimpleTypes::Spreadsheet::celltypeNumber: + switch(cellType) { - if(isReal || m_oFormula.IsInit()) + case SimpleTypes::Spreadsheet::celltypeNumber: + { + if(isReal) + { + + auto cellNumber = new XLS::Number; + XLS::Xnum number; + number.data.value = realCache; + cellNumber->num = number; + cellNumber->cell.rw = CellReference.row; + cellNumber->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + cellNumber->cell.ixfe = m_oStyle.get(); + castedPtr->cellContent = XLS::BaseObjectPtr(cellNumber); + } + else + { + auto RkCell = new XLS::RK; + XLS::RkNumber cellRk; + cellRk.fInt = 1; + cellRk.fX100 = 0; + cellRk.num = realCache; + RkCell->rkrec.RK_ = cellRk; + RkCell->cell.rw = CellReference.row; + RkCell->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + RkCell->rkrec.ixfe = m_oStyle.get(); + castedPtr->cellContent = XLS::BaseObjectPtr(RkCell); + } + break; + } + case SimpleTypes::Spreadsheet::celltypeBool: { - auto cellNumber = new XLS::Number; - XLS::Xnum number; - number.data.value = realCache; - cellNumber->num = number; - cellNumber->cell.rw = CellReference.row; - cellNumber->cell.col = CellReference.column; + auto BoolErrCell = new XLS::BoolErr; + BoolErrCell->cell.rw = CellReference.row; + BoolErrCell->cell.col = CellReference.column; if(m_oStyle.IsInit()) - cellNumber->cell.ixfe = m_oStyle.get(); - castedPtr->cellContent = XLS::BaseObjectPtr(cellNumber); + BoolErrCell->cell.ixfe = m_oStyle.get(); + BYTE cellval = 0; + if(m_oValue.IsInit()) + cellval = m_oValue->m_sText == L"1" ? true : false; + BoolErrCell->bes.bBoolErr = cellval; + castedPtr->cellContent = XLS::BaseObjectPtr(BoolErrCell); + break; } + case SimpleTypes::Spreadsheet::celltypeError: + { + + auto BoolErrCell = new XLS::BoolErr; + BoolErrCell->cell.rw = CellReference.row; + BoolErrCell->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + BoolErrCell->cell.ixfe = m_oStyle.get(); + BoolErrCell->bes.fError = true; + BYTE cellval = 0; + if(m_oValue.IsInit()) + { + if(m_oValue->m_sText == L"#NULL!") + cellval = 0x00; + else if (m_oValue->m_sText == L"#DIV/0!") + cellval = 0x07; + else if (m_oValue->m_sText == L"#VALUE!") + cellval = 0x0F; + else if (m_oValue->m_sText == L"#REF!") + cellval = 0x17; + else if (m_oValue->m_sText == L"#NAME?") + cellval = 0x1D; + else if (m_oValue->m_sText == L"#NUM!") + cellval = 0x24; + else if (m_oValue->m_sText == L"#N/A") + cellval = 0x2A; + else if (m_oValue->m_sText == L"#GETTING_DATA") + cellval = 0x2B; + } + BoolErrCell->bes.bBoolErr = cellval; + castedPtr->cellContent = XLS::BaseObjectPtr(BoolErrCell); + break; + } + case SimpleTypes::Spreadsheet::celltypeSharedString: + { + if(m_oValue.IsInit()) + { + auto CellSst = new XLS::LabelSst; + CellSst->cell.rw = CellReference.row; + CellSst->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + CellSst->cell.ixfe = m_oStyle.get(); + _UINT32 isst = 0; + isst = std::stoi(m_oValue->m_sText); + CellSst->isst = isst; + castedPtr->cellContent = XLS::BaseObjectPtr(CellSst); + } + break; + } + + } + } + else + { + auto fmlaUnion = new XLS::FORMULA(castedPtr->shared_formulas_locations_ref_); + castedPtr->cellContent = XLS::BaseObjectPtr(fmlaUnion); + auto FmlaCell = new XLS::Formula; + fmlaUnion->m_Formula = XLS::BaseObjectPtr(FmlaCell); + FmlaCell->cell.rw = CellReference.row; + FmlaCell->cell.col = CellReference.column; + if(m_oStyle.IsInit()) + FmlaCell->cell.ixfe = m_oStyle.get(); + auto cellType = m_oType->GetValue(); + if(cellType == SimpleTypes::Spreadsheet::celltypeNumber) + FmlaCell->val.data.xnum = realCache; + else if(cellType == SimpleTypes::Spreadsheet::celltypeStr) + { + if(m_oValue.IsInit() && !m_oValue.get().m_sText.empty()) + FmlaCell->val.data.Byte1 = 0x00; else - { - auto RkCell = new XLS::RK; - XLS::RkNumber cellRk; - cellRk.fInt = 1; - cellRk.fX100 = 0; - cellRk.num = realCache; - RkCell->rkrec.RK_ = cellRk; - RkCell->cell.rw = CellReference.row; - RkCell->cell.col = CellReference.column; - if(m_oStyle.IsInit()) - RkCell->rkrec.ixfe = m_oStyle.get(); - castedPtr->cellContent = XLS::BaseObjectPtr(RkCell); - } - break; + FmlaCell->val.data.Byte1 = 0x03; } - case SimpleTypes::Spreadsheet::celltypeBool: + else if(cellType == SimpleTypes::Spreadsheet::celltypeBool) { - - auto BoolErrCell = new XLS::BoolErr; - BoolErrCell->cell.rw = CellReference.row; - BoolErrCell->cell.col = CellReference.column; - if(m_oStyle.IsInit()) - BoolErrCell->cell.ixfe = m_oStyle.get(); + FmlaCell->val.data.Byte1 = 0x01; BYTE cellval = 0; - if(m_oValue.IsInit()) - cellval = m_oValue->m_sText == L"1" ? true : false; - BoolErrCell->bes.bBoolErr = cellval; - castedPtr->cellContent = XLS::BaseObjectPtr(BoolErrCell); - break; + if(m_oValue.IsInit()) + cellval = m_oValue->m_sText == L"1" ? true : false; + FmlaCell->val.data.Byte3 = cellval; } - case SimpleTypes::Spreadsheet::celltypeError: + else if(cellType == SimpleTypes::Spreadsheet::celltypeError) { - - auto BoolErrCell = new XLS::BoolErr; - BoolErrCell->cell.rw = CellReference.row; - BoolErrCell->cell.col = CellReference.column; - if(m_oStyle.IsInit()) - BoolErrCell->cell.ixfe = m_oStyle.get(); - BoolErrCell->bes.fError = true; + FmlaCell->val.data.Byte1 = 0x02; BYTE cellval = 0; if(m_oValue.IsInit()) { @@ -2816,27 +2903,10 @@ namespace OOX else if (m_oValue->m_sText == L"#GETTING_DATA") cellval = 0x2B; } - BoolErrCell->bes.bBoolErr = cellval; - castedPtr->cellContent = XLS::BaseObjectPtr(BoolErrCell); - break; + FmlaCell->val.data.Byte3 = cellval; } - case SimpleTypes::Spreadsheet::celltypeSharedString: - { - if(m_oValue.IsInit()) - { - auto CellSst = new XLS::LabelSst; - CellSst->cell.rw = CellReference.row; - CellSst->cell.col = CellReference.column; - if(m_oStyle.IsInit()) - CellSst->cell.ixfe = m_oStyle.get(); - _UINT32 isst = 0; - isst = std::stoi(m_oValue->m_sText); - CellSst->isst = isst; - castedPtr->cellContent = XLS::BaseObjectPtr(CellSst); - } - break; - } - + if(m_oFormula.IsInit()) + m_oFormula->toXls(fmlaUnion->m_Formula); } } diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.h b/OOXML/XlsxFormat/Worksheets/SheetData.h index f6be4d1145..cd4ba8dd7b 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.h +++ b/OOXML/XlsxFormat/Worksheets/SheetData.h @@ -152,6 +152,7 @@ namespace OOX void fromXLSBExt (NSBinPptxRW::CBinaryFileReader& oStream, _UINT16 nFlags); void fromBin(XLS::StreamCacheReaderPtr& reader, XLS::CFRecordPtr& record); void fromBin(XLS::BaseObjectPtr& obj, SimpleTypes::Spreadsheet::ECellFormulaType eType); + void toXls(XLS::BaseObjectPtr& obj); void toBin(XLS::BaseObjectPtr& obj); void toBin(XLS::CFRecordPtr& record, const XLS::CellRef& cellBaseRef); From f1fa861c8a66275687376370b25f3d5be8b9f07c Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 22 Jul 2025 17:35:57 +0600 Subject: [PATCH 013/318] Add shared formula conversion --- .../Format/Logic/Biff_records/ShrFmla.h | 2 +- .../Format/Logic/Biff_structures/PtgExp.h | 6 ++-- .../Biff_structures/SharedParsedFormula.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 35 ++++++++++++++++--- 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ShrFmla.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ShrFmla.h index eff4150f1b..ccda7dc787 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ShrFmla.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ShrFmla.h @@ -57,7 +57,7 @@ public: //----------------------------- RefU ref_; - BYTE cUse; + BYTE cUse = 1; SharedParsedFormula formula; XLSB::UncheckedRfX rfx; //in biff12 diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h index affb820df7..387a7f4aed 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/PtgExp.h @@ -53,10 +53,10 @@ public: static const unsigned short fixed_id = 0x01; - unsigned short row; - unsigned short col; + unsigned short row = 0; + unsigned short col = 0; - _INT32 rowXlsb;//biff12 + _INT32 rowXlsb = 0;//biff12 }; typedef boost::shared_ptr PtgExpPtr; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp index 14d90b2532..40a9f7cec0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/SharedParsedFormula.cpp @@ -95,7 +95,7 @@ void SharedParsedFormula::save(CFRecord& record) size = record.getRdPtr() - rdPtr; - record.RollRdPtrBack(size + 4); + record.RollRdPtrBack(size + 2); record << size; record.skipNunBytes(size); }; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index 14379e51ad..bc2caccb26 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1234,13 +1234,38 @@ namespace OOX } void CFormula::toXls(XLS::BaseObjectPtr& obj) { - auto xlsFmla = static_cast(obj.get()); - if(m_oT.IsInit() && m_oT->GetValue() == SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared) + auto FmlaUnion = static_cast(obj.get()); + auto xlsFmla = static_cast(FmlaUnion->m_Formula.get()); + if(!m_oT.IsInit()) + m_oT = SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeNormal; + if(m_oT->GetValue() == SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeNormal && !m_sText.empty()) + xlsFmla->formula = m_sText; + else if(m_oT->GetValue() == SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeShared) + { xlsFmla->fShrFmla = true; + if(!m_sText.empty() && m_oRef.IsInit()) + { + CellRef cell_base_ref; + cell_base_ref.column = xlsFmla->cell.col; + cell_base_ref.row = xlsFmla->cell.rw; + auto shrFmla = new XLS::ShrFmla(cell_base_ref); + FmlaUnion->m_SharedFormula = XLS::BaseObjectPtr(shrFmla); + shrFmla->ref_.fromString(m_oRef.get()); + shrFmla->formula = m_sText; + FmlaUnion->shared_formulas_locations_ref_.push_back(shrFmla->ref_); + } + if(m_oSi.IsInit() && FmlaUnion->shared_formulas_locations_ref_.size() > m_oSi->GetValue()) + { + auto SharedFmlaRef = FmlaUnion->shared_formulas_locations_ref_.at(m_oSi->GetValue()).getTopLeftCell(); + auto rowPos = new XLS::PtgExp; + rowPos->row = SharedFmlaRef.row; + rowPos->col = SharedFmlaRef.column; + xlsFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + + } + } if(m_oAca.IsInit()) xlsFmla->fAlwaysCalc = m_oAca->GetValue(); - if(!m_sText.empty()) - xlsFmla->formula = m_sText; } void CFormula::toBin(XLS::BaseObjectPtr& obj) { @@ -2906,7 +2931,7 @@ namespace OOX FmlaCell->val.data.Byte3 = cellval; } if(m_oFormula.IsInit()) - m_oFormula->toXls(fmlaUnion->m_Formula); + m_oFormula->toXls(castedPtr->cellContent); } } From c012662402b1f4e5673f1307032dca83865a1da8 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 23 Jul 2025 17:21:30 +0600 Subject: [PATCH 014/318] Add array formula writing --- .../XlsFile/Format/Logic/Biff_records/Array.h | 2 +- .../Format/Logic/Biff_records/Dimensions.h | 4 +- .../Biff_structures/ArrayParsedFormula.cpp | 2 +- OOXML/XlsxFormat/Worksheets/SheetData.cpp | 62 ++++++++++++++++--- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Array.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Array.h index 27972b7e73..ec3c75668f 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Array.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Array.h @@ -56,7 +56,7 @@ public: Ref ref_; ArrayParsedFormula formula; - bool fAlwaysCalc; + bool fAlwaysCalc = false; RFX rfx; //biff12 }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h index 9c0f251a78..33489b6eb5 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h @@ -56,9 +56,9 @@ public: std::wstring ref_ = L""; //----------------------------- _UINT32 rwMic = 0; - _UINT32 rwMac = 0; + _UINT32 rwMac = 0x00010000; _UINT16 colMic = 0; - _UINT16 colMac = 0; + _UINT16 colMac = 0x0100; }; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ArrayParsedFormula.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ArrayParsedFormula.cpp index c9585ca766..7eddcb63ee 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ArrayParsedFormula.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ArrayParsedFormula.cpp @@ -95,7 +95,7 @@ void ArrayParsedFormula::save(CFRecord& record) size = record.getRdPtr() - rdPtr; - record.RollRdPtrBack(size + 4); + record.RollRdPtrBack(size + 2); record << size; record.skipNunBytes(size); }; diff --git a/OOXML/XlsxFormat/Worksheets/SheetData.cpp b/OOXML/XlsxFormat/Worksheets/SheetData.cpp index bc2caccb26..6f1518bc43 100644 --- a/OOXML/XlsxFormat/Worksheets/SheetData.cpp +++ b/OOXML/XlsxFormat/Worksheets/SheetData.cpp @@ -1245,10 +1245,10 @@ namespace OOX xlsFmla->fShrFmla = true; if(!m_sText.empty() && m_oRef.IsInit()) { - CellRef cell_base_ref; - cell_base_ref.column = xlsFmla->cell.col; - cell_base_ref.row = xlsFmla->cell.rw; - auto shrFmla = new XLS::ShrFmla(cell_base_ref); + CellRef cellBaseRef; + cellBaseRef.column = xlsFmla->cell.col; + cellBaseRef.row = xlsFmla->cell.rw; + auto shrFmla = new XLS::ShrFmla(cellBaseRef); FmlaUnion->m_SharedFormula = XLS::BaseObjectPtr(shrFmla); shrFmla->ref_.fromString(m_oRef.get()); shrFmla->formula = m_sText; @@ -1257,13 +1257,46 @@ namespace OOX if(m_oSi.IsInit() && FmlaUnion->shared_formulas_locations_ref_.size() > m_oSi->GetValue()) { auto SharedFmlaRef = FmlaUnion->shared_formulas_locations_ref_.at(m_oSi->GetValue()).getTopLeftCell(); - auto rowPos = new XLS::PtgExp; - rowPos->row = SharedFmlaRef.row; - rowPos->col = SharedFmlaRef.column; - xlsFmla->formula.rgce.addPtg(PtgPtr{rowPos}); + auto cellPos = new XLS::PtgExp; + cellPos->row = SharedFmlaRef.row; + cellPos->col = SharedFmlaRef.column; + xlsFmla->formula.rgce.addPtg(PtgPtr{cellPos}); } } + else if(m_oT->GetValue() == SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray) + { + if(!m_sText.empty() && m_oRef.IsInit()) + { + if(!SharedFormulasRef::ArrayRefsLocations) + SharedFormulasRef::ArrayRefsLocations = std::unique_ptr>>(new std::vector>); + auto rangeRef = XLS::CellRangeRef(m_oRef.get()); + CellRef cellBaseRef; + cellBaseRef.column = xlsFmla->cell.col; + cellBaseRef.row = xlsFmla->cell.rw; + SharedFormulasRef::ArrayRefsLocations->push_back(std::pair(rangeRef, cellBaseRef)); + + auto ArrayFmla = new XLS::Array(cellBaseRef); + FmlaUnion->m_ArrayFormula = XLS::BaseObjectPtr(ArrayFmla); + ArrayFmla->ref_.fromString(m_oRef.get()); + ArrayFmla->formula = m_sText; + + auto cellPos = new XLS::PtgExp; + cellPos->row = cellBaseRef.row; + cellPos->col = cellBaseRef.column; + xlsFmla->formula.rgce.addPtg(PtgPtr{cellPos}); + } + else if(!m_sText.empty()) + { + CellRef cellBaseRef; + cellBaseRef.fromString(m_sText); + auto cellPos = new XLS::PtgExp; + cellPos->row = cellBaseRef.row; + cellPos->col = cellBaseRef.column; + xlsFmla->formula.rgce.addPtg(PtgPtr{cellPos}); + } + + } if(m_oAca.IsInit()) xlsFmla->fAlwaysCalc = m_oAca->GetValue(); } @@ -2775,6 +2808,19 @@ namespace OOX m_oType->SetValue(processCellType(m_oValue.get().m_sText, isReal, realCache)); } auto cellType = m_oType->GetValue(); + if(SharedFormulasRef::ArrayRefsLocations && SharedFormulasRef::ArrayRefsLocations->size()) + { + for(auto i: *SharedFormulasRef::ArrayRefsLocations) + { + if(i.first.inRange(CellReference)) + { + m_oFormula.Init(); + m_oFormula->m_oT = SimpleTypes::Spreadsheet::ECellFormulaType::cellformulatypeArray; + m_oFormula->m_sText = i.second.toString(); + break; + } + } + } if(!m_oFormula.IsInit()) { switch(cellType) From 010371724176b86e6b7011a0f8130ecf1bd72095 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 23 Jul 2025 20:44:54 +0600 Subject: [PATCH 015/318] add dimensions conversion --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 3 ++- OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp | 10 ++++++++++ OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index ef0acdbec1..bd868cdcb8 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -364,7 +364,8 @@ namespace OOX { auto worksheetPtr = new XLS::WorksheetSubstream(0); auto sheetPtr = XLS::BaseObjectPtr(worksheetPtr); - + if(m_oDimension.IsInit()) + worksheetPtr->m_Dimensions = m_oDimension->toXLS(); if(m_oSheetData.IsInit()) worksheetPtr->m_CELLTABLE = m_oSheetData->toXLS(); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index fdc4e9371c..f9e2c3a104 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -72,6 +72,8 @@ #include "../../Common/SimpleTypes_Word.h" #include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h" + namespace OOX { namespace Spreadsheet @@ -1157,6 +1159,14 @@ namespace OOX castedPtr->rfx = m_oRef.get(); return ptr; } + XLS::BaseObjectPtr CDimension::toXLS() + { + auto dimensions = new XLS::Dimensions; + XLS::BaseObjectPtr ptr(dimensions); + if (m_oRef.IsInit()) + dimensions->ref_ = m_oRef.get(); + return ptr; + } void CDimension::toBin(XLS::StreamCacheWriterPtr& writer) { auto record = writer->getNextRecord(XLSB::rt_WsDim); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index c3d7a8c24d..ba33ef4331 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -283,6 +283,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; From 89172a9047061cd3f7988b45681b7d9c708f70a6 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 23 Jul 2025 20:45:04 +0600 Subject: [PATCH 016/318] add relsSorting --- OOXML/DocxFormat/Rels.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OOXML/DocxFormat/Rels.cpp b/OOXML/DocxFormat/Rels.cpp index 27182849c1..43dd4edfbb 100644 --- a/OOXML/DocxFormat/Rels.cpp +++ b/OOXML/DocxFormat/Rels.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -190,6 +190,9 @@ namespace OOX } } } + std::sort(m_arRelations.begin(), m_arRelations.end(),[](const OOX::Rels::CRelationShip* a, const OOX::Rels::CRelationShip* b) { + return a->rId().getNumber() < b->rId().getNumber(); + }); } void CRels::Write(const CPath& oFilePath) const { From 7e51dd143af0a7de70016d88dd71ba65022b4462 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 24 Jul 2025 15:02:36 +0600 Subject: [PATCH 017/318] Add colls & merged cells conversion --- .../Format/Logic/Biff_records/ColInfo.h | 2 +- .../Format/Logic/Biff_records/MergeCells.cpp | 1 + .../Format/Logic/Biff_unions/COLUMNS.cpp | 25 ++++------ .../Format/Logic/Biff_unions/COLUMNS.h | 1 + OOXML/XlsxFormat/Worksheets/Cols.cpp | 47 +++++++++++++++++++ OOXML/XlsxFormat/Worksheets/Cols.h | 2 + OOXML/XlsxFormat/Worksheets/MergeCells.cpp | 30 ++++++++++++ OOXML/XlsxFormat/Worksheets/MergeCells.h | 3 ++ OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 4 ++ 9 files changed, 98 insertions(+), 17 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h index 6afc80ecfd..d8490a005c 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h @@ -54,7 +54,7 @@ public: _UINT32 colFirst = 0; _UINT32 colLast = 0; _UINT32 coldx = 0; - IXFCell ixfe = 0xffff; + IXFCell ixfe = 0; _UINT32 ixfeXLSB = 0xffffffff; bool fHidden = false; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MergeCells.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MergeCells.cpp index 82612c1936..c5c2c0b19d 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MergeCells.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/MergeCells.cpp @@ -65,6 +65,7 @@ void MergeCells::readFields(CFRecord& record) void MergeCells::writeFields(CFRecord& record) { cmcs = rgref.size(); + record << cmcs; for(auto i : rgref) record << *i; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp index 8400e5e813..290da063d9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.cpp @@ -94,22 +94,15 @@ const bool COLUMNS::loadContent(BinProcessor& proc) } const bool COLUMNS::saveContent(BinProcessor& proc) { - if(m_DefColWidth != nullptr) - proc.mandatory(*m_DefColWidth); - else - proc.mandatory(); - /*if(global_info_ && global_info_->sheets_info.size() > global_info_->current_sheet) - { - for(auto i:global_info_->sheets_info[global_info_->current_sheet - 1].customColumnsWidth) - { - ColInfo column_info; - column_info.colFirst = i.first; - column_info.colLast = i.first; - column_info.coldx = i.second * 256; - proc.mandatory(column_info); - } - }*/ - return true; + if(m_DefColWidth != nullptr) + proc.mandatory(*m_DefColWidth); + else + proc.mandatory(); + for(auto i : m_colInfos) + { + proc.mandatory(*i); + } + return true; } int COLUMNS::serialize(std::wostream & stream) { diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h index b64620d6f1..356499b706 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h @@ -53,6 +53,7 @@ public: static const ElementType type = typeCOLUMNS; BaseObjectPtr m_DefColWidth; + std::vector m_colInfos; GlobalWorkbookInfoPtr global_info_; }; diff --git a/OOXML/XlsxFormat/Worksheets/Cols.cpp b/OOXML/XlsxFormat/Worksheets/Cols.cpp index f588235f2e..3f3d0cc3a5 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.cpp +++ b/OOXML/XlsxFormat/Worksheets/Cols.cpp @@ -38,6 +38,9 @@ #include "../../Common/SimpleTypes_Shared.h" #include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/COLUMNS.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/DefColWidth.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/ColInfo.h" namespace OOX { @@ -132,6 +135,40 @@ namespace OOX castedPtr->coldx = 2304; ///standart col width(9) * 256 return ptr; } + XLS::BaseObjectPtr CCol::toXLS() + { + auto colInfo = new XLS::ColInfo; + if(m_oMax.IsInit()) + colInfo->colLast = m_oMax->m_eValue - 1; + else + colInfo->colLast = 255; + if(m_oMin.IsInit()) + colInfo->colFirst = m_oMin->m_eValue - 1; + else + colInfo->colFirst = 0; + if (m_oWidth.IsInit()) + { + if(m_oWidth->GetValue() > 0) + colInfo->coldx = m_oWidth->GetValue() * 256; + } + else + colInfo->coldx = 2304; + if(m_oStyle.IsInit()) + colInfo->ixfe = m_oStyle->m_eValue; + if(m_oHidden.IsInit()) + colInfo->fHidden = m_oHidden->ToBool(); + if(m_oCustomWidth.IsInit()) + colInfo->fUserSet = m_oCustomWidth->ToBool(); + if(m_oBestFit.IsInit()) + colInfo->fBestFit = m_oBestFit->ToBool(); + if(m_oPhonetic.IsInit()) + colInfo->fPhonetic = m_oPhonetic->ToBool(); + if(m_oOutlineLevel.IsInit()) + colInfo->iOutLevel = m_oOutlineLevel->m_eValue; + if(m_oCollapsed.IsInit()) + colInfo->fCollapsed = m_oCollapsed->ToBool(); + return XLS::BaseObjectPtr(colInfo); + } void CCol::toBin(XLS::StreamCacheWriterPtr& writer) { auto record = writer->getNextRecord(XLSB::rt_ColInfo); @@ -350,6 +387,16 @@ namespace OOX writer->storeNextRecord(end); } } + XLS::BaseObjectPtr CCols::toXLS() + { + auto cols = new XLS::COLUMNS; + for(auto i:m_arrItems) + { + cols->m_colInfos.push_back(i->toXLS()); + } + + return XLS::BaseObjectPtr(cols); + } EElementType CCols::getType () const { return et_x_Cols; diff --git a/OOXML/XlsxFormat/Worksheets/Cols.h b/OOXML/XlsxFormat/Worksheets/Cols.h index 9a4ce8bcd3..f2c2cdc3de 100644 --- a/OOXML/XlsxFormat/Worksheets/Cols.h +++ b/OOXML/XlsxFormat/Worksheets/Cols.h @@ -62,6 +62,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType() const; @@ -98,6 +99,7 @@ namespace OOX void fromBin(std::vector& obj); std::vector toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp index 13518cd6b8..372abed61a 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.cpp +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.cpp @@ -37,6 +37,8 @@ #include "../../XlsbFormat/Biff12_records/BeginMergeCells.h" #include "../../XlsbFormat/Biff12_unions/MERGECELLS.h" #include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h" + +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/MergeCells.h" namespace OOX { namespace Spreadsheet @@ -78,6 +80,13 @@ namespace OOX castedPtr->rfx = m_oRef.get(); return ptr; } + XLS::BiffStructurePtr CMergeCell::toXLS() + { + auto mergedCell = new XLS::Ref8; + if(m_oRef.IsInit()) + mergedCell->fromString(m_oRef.get()); + return XLS::BiffStructurePtr(mergedCell); + } void CMergeCell::toBin(XLS::StreamCacheWriterPtr& writer) { auto record = writer->getNextRecord(XLSB::rt_MergeCell); @@ -183,6 +192,27 @@ namespace OOX beginCells->cmcs = castedPtr->m_arBrtMergeCell.size(); return ptr; } + std::vector CMergeCells::toXLS() + { + std::vector mergeCellsArray; + auto cellsRecord = new XLS::MergeCells; + auto i = 0; + while(i < m_arrItems.size()) + { + cellsRecord->rgref.push_back(m_arrItems.at(i)->toXLS()); + cellsRecord->cmcs++; + if(cellsRecord->cmcs == 1026) + { + mergeCellsArray.push_back(XLS::BaseObjectPtr(cellsRecord)); + cellsRecord = new XLS::MergeCells; + } + } + if(cellsRecord->cmcs) + mergeCellsArray.push_back(XLS::BaseObjectPtr(cellsRecord)); + else + delete cellsRecord; + return mergeCellsArray; + } void CMergeCells::toBin(XLS::StreamCacheWriterPtr& writer) { { diff --git a/OOXML/XlsxFormat/Worksheets/MergeCells.h b/OOXML/XlsxFormat/Worksheets/MergeCells.h index 5e34970748..cf3f70b98f 100644 --- a/OOXML/XlsxFormat/Worksheets/MergeCells.h +++ b/OOXML/XlsxFormat/Worksheets/MergeCells.h @@ -33,6 +33,7 @@ #include "../WritingElement.h" #include "../../Base/Nullable.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/BiffStructure.h" namespace SimpleTypes { @@ -60,6 +61,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BiffStructurePtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; @@ -87,6 +89,7 @@ namespace OOX XLS::BaseObjectPtr toBin(); void toBin(XLS::StreamCacheWriterPtr& writer); + std::vector toXLS(); void fromBin(std::vector& obj); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index bd868cdcb8..2e5a032820 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -366,6 +366,10 @@ namespace OOX auto sheetPtr = XLS::BaseObjectPtr(worksheetPtr); if(m_oDimension.IsInit()) worksheetPtr->m_Dimensions = m_oDimension->toXLS(); + if(m_oCols.IsInit()) + worksheetPtr->m_COLUMNS = m_oCols->toXLS(); + if (m_oMergeCells.IsInit()) + worksheetPtr->m_arMergeCells = m_oMergeCells->toXLS(); if(m_oSheetData.IsInit()) worksheetPtr->m_CELLTABLE = m_oSheetData->toXLS(); From 609e3bc1586ff141c42e3c13c81e08aeb5c07704 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 24 Jul 2025 20:50:37 +0600 Subject: [PATCH 018/318] Add worksheet view conversion --- .../XlsFile/Format/Logic/Biff_records/Pane.h | 14 +-- .../Format/Logic/Biff_records/Window2.h | 2 +- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 3 + .../Worksheets/WorksheetChildOther.cpp | 95 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 3 + 5 files changed, 109 insertions(+), 8 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.h index a2c5692cad..9b23e56117 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Pane.h @@ -55,12 +55,12 @@ public: static const ElementType type = typePane; - _UINT16 x; - _UINT16 y; + _UINT16 x = 0; + _UINT16 y = 0; //_UINT16 rwTop; - UncheckedRw rwTop; + UncheckedRw rwTop = 0; //_UINT16 colLeft; - UncheckedCol colLeft; + UncheckedCol colLeft = 0; PaneType pnnAcct; //4 byte in biff12 std::wstring topLeftCell; @@ -68,9 +68,9 @@ public: //biff12 Xnum xnumXSplit; Xnum xnumYSplit; - bool fFrozen; - bool fFrozenNoSplit; - _UINT32 pnnAcct_xlsb; + bool fFrozen = false; + bool fFrozenNoSplit = false; + _UINT32 pnnAcct_xlsb = 0; }; } // namespace XLS diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h index e79db2949e..a09b326310 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h @@ -63,7 +63,7 @@ public: bool fDspGuts = true; // * bool fFrozenNoSplit = false; bool fSelected = false; // * - bool fPaged = true; + bool fPaged = false; bool fSLV = false; bool is_contained_in_chart_substream = false; diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index 2e5a032820..cfe542248d 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -370,6 +370,9 @@ namespace OOX worksheetPtr->m_COLUMNS = m_oCols->toXLS(); if (m_oMergeCells.IsInit()) worksheetPtr->m_arMergeCells = m_oMergeCells->toXLS(); + if(m_oSheetViews.IsInit()) + worksheetPtr->m_arWINDOW = m_oSheetViews->toXLS(); + if(m_oSheetData.IsInit()) worksheetPtr->m_CELLTABLE = m_oSheetData->toXLS(); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index f9e2c3a104..9208e34e1f 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -72,6 +72,8 @@ #include "../../Common/SimpleTypes_Word.h" #include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h" namespace OOX @@ -1597,6 +1599,28 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CSelection::toXLS() + { + auto sel = new XLS::Selection; + if(m_oActiveCell.IsInit()) + sel->activeCell = m_oActiveCell.get(); + if(m_oPane.IsInit()) + { + if(m_oPane->GetValue() == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomRight) + sel->pnn.value() = XLS::PaneType::REVTPNNBOTRIGHT; + else if(m_oPane->GetValue() == SimpleTypes::Spreadsheet::EActivePane::activepaneTopRight) + sel->pnn.value() = XLS::PaneType::REVTPNNTOPRIGHT; + else if(m_oPane->GetValue() == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomLeft) + sel->pnn.value() = XLS::PaneType::REVTPNNBOTLEFT; + else if(m_oPane->GetValue() == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) + sel->pnn.value() = XLS::PaneType::REVTPNNTOPLEFT; + } + else + sel->pnn.value() = XLS::PaneType::REVTPNNTOPLEFT; + if(m_oSqref.IsInit()) + sel->sqref = m_oSqref.get(); + return XLS::BaseObjectPtr(sel); + } void CSelection::toBin(XLS::StreamCacheWriterPtr& writer) { auto record = writer->getNextRecord(XLSB::rt_Sel); @@ -1860,6 +1884,70 @@ namespace OOX return castedPtr; } + XLS::BaseObjectPtr CSheetView::toXLS() + { + auto windowUnion = new XLS::WINDOW; + auto window = new XLS::Window2; + windowUnion->m_Window2 = XLS::BaseObjectPtr(window); + if(m_oShowFormulas.IsInit()) + window->fDspFmlaRt = m_oShowFormulas->GetValue(); + if(m_oShowGridLines.IsInit()) + window->fDspGridRt = m_oShowGridLines->GetValue(); + if(m_oShowRowColHeaders.IsInit()) + window->fDspRwColRt = m_oShowRowColHeaders->GetValue(); + if(m_oShowZeros.IsInit()) + window->fDspZerosRt = m_oShowZeros->GetValue(); + if(m_oTabSelected.IsInit()) + { + window->fSelected = m_oTabSelected->GetValue(); + window->fPaged = true; + } + if(m_oDefaultGridColor.IsInit()) + window->fDefaultHdr = m_oDefaultGridColor->GetValue(); + if(m_oTopLeftCell.IsInit()) + window->topLeftCell = m_oTopLeftCell.get(); + if(m_oZoomScale.IsInit()) + window->wScale = m_oZoomScale->GetValue(); + if(m_oZoomScaleNormal.IsInit()) + window->wScaleNormal = m_oZoomScale->GetValue(); + if(m_oColorId.IsInit()) + window->icvHdr = m_oColorId->m_eValue; + if(m_oPane.IsInit()) + { + if(m_oPane->m_oState.IsInit()) + { + if(m_oPane->m_oState->GetValue() != SimpleTypes::Spreadsheet::EPaneState::panestateSplit) + { + window->fFrozenRt = true; + if(m_oPane->m_oState->GetValue() == SimpleTypes::Spreadsheet::EPaneState::panestateFrozen) + window->fFrozenNoSplit = true; + } + } + auto pane = new XLS::Pane; + windowUnion->m_Pane = XLS::BaseObjectPtr(pane); + if(m_oPane->m_oTopLeftCell.IsInit()) + pane->topLeftCell = m_oPane->m_oTopLeftCell.get(); + if(m_oPane->m_oXSplit.IsInit()) + pane->x = m_oPane->m_oXSplit->GetValue(); + if(m_oPane->m_oYSplit.IsInit()) + pane->y = m_oPane->m_oYSplit->GetValue(); + if(m_oPane->m_oActivePane.IsInit()) + { + if(m_oPane->m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomRight) + pane->pnnAcct.value() = XLS::PaneType::REVTPNNBOTRIGHT; + else if(m_oPane->m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopRight) + pane->pnnAcct.value() = XLS::PaneType::REVTPNNTOPRIGHT; + else if(m_oPane->m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneBottomLeft) + pane->pnnAcct.value() = XLS::PaneType::REVTPNNBOTLEFT; + else if(m_oPane->m_oActivePane == SimpleTypes::Spreadsheet::EActivePane::activepaneTopLeft) + pane->pnnAcct.value() = XLS::PaneType::REVTPNNTOPLEFT; + } + + } + for(auto i : m_arrItems) + windowUnion->m_arSelection.push_back(i->toXLS()); + return XLS::BaseObjectPtr(windowUnion); + } void CSheetView::toBin(XLS::StreamCacheWriterPtr& writer) { { @@ -2124,6 +2212,13 @@ namespace OOX castedPtr->m_arWSVIEW2.push_back(i->toBin()); return ptr; } + std::vector CSheetViews::toXLS() + { + std::vector ptrVector; + for(auto i:m_arrItems) + ptrVector.push_back(i->toXLS()); + return ptrVector; + } void CSheetViews::toBin(XLS::StreamCacheWriterPtr& writer) { { diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index ba33ef4331..3f7e316d32 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -378,6 +378,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; @@ -411,6 +412,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; @@ -460,6 +462,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + std::vector toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); XLS::BaseObjectPtr toBinCs(); virtual EElementType getType () const; From e8ad643a0eda75a2c13db22dcf44edcb5618deea Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 24 Jul 2025 21:24:07 +0600 Subject: [PATCH 019/318] Add bookviewsConversion --- OOXML/XlsxFormat/Workbook/BookViews.cpp | 79 ++++++++++++++++++++++++- OOXML/XlsxFormat/Workbook/BookViews.h | 2 + OOXML/XlsxFormat/Workbook/Workbook.cpp | 2 + 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Workbook/BookViews.cpp b/OOXML/XlsxFormat/Workbook/BookViews.cpp index 8ce08ea6a5..b6418ebc59 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.cpp +++ b/OOXML/XlsxFormat/Workbook/BookViews.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -33,6 +33,9 @@ #include "BookViews.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window1.h" + #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" @@ -153,6 +156,74 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CWorkbookView::toXLS() + { + auto ptr = new XLS::Window1; + if (m_oActiveTab.IsInit()) + { + ptr->itabCur = m_oActiveTab->GetValue(); + } + else + { + ptr->itabCur = 0; + } + + if (m_oAutoFilterDateGrouping.IsInit()) + ptr->fNoAFDateGroup = m_oAutoFilterDateGrouping->GetValue(); + else + ptr->fNoAFDateGroup = false; + if (m_oFirstSheet.IsInit()) + ptr->itabFirst = m_oFirstSheet->GetValue(); + else + ptr->itabFirst = 0; + if (m_oMinimized.IsInit()) + ptr->fIconic = m_oMinimized->GetValue(); + else + ptr->fIconic = false; + if (m_oShowHorizontalScroll.IsInit()) + ptr->fDspHScroll = m_oShowHorizontalScroll->GetValue(); + if (m_oShowSheetTabs.IsInit()) + ptr->fBotAdornment = m_oShowSheetTabs->GetValue(); + if (m_oShowVerticalScroll.IsInit()) + ptr->fDspVScroll = m_oShowVerticalScroll->GetValue(); + if (m_oTabRatio.IsInit()) + ptr->wTabRatio = m_oTabRatio->GetValue(); + else + ptr->wTabRatio = 600; + if (m_oWindowHeight.IsInit()) + ptr->dyWn = m_oWindowHeight->GetValue(); + else + ptr->dyWn = 12750; + if (m_oWindowWidth.IsInit()) + ptr->dxWn = m_oWindowWidth->GetValue(); + else + ptr->dxWn = 21240; + if (m_oXWindow.IsInit()) + ptr->xWn = m_oXWindow->GetValue() * 6; + else + ptr->xWn = 2280; + if (m_oYWindow.IsInit()) + ptr->yWn = m_oYWindow->GetValue() * 110; + else + ptr->yWn = 1650; + + if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleHidden) + { + ptr->fHidden = true; + ptr->fVeryHidden = false; + } + else if (m_oVisibility == SimpleTypes::Spreadsheet::EVisibleType::visibleVeryHidden) + { + ptr->fHidden = false; + ptr->fVeryHidden = true; + } + else + { + ptr->fHidden = false; + ptr->fVeryHidden = false; + } + return XLS::BaseObjectPtr(ptr); + } EElementType CWorkbookView::getType () const { return et_x_WorkbookView; @@ -267,6 +338,12 @@ namespace OOX return ptrVector; } + void CBookViews::toXLS(XLS::BaseObjectPtr substreamPtr) + { + auto Substream = static_cast(substreamPtr.get()); + for(auto i:m_arrItems) + Substream->m_arWindow1.push_back(i->toXLS()); + } EElementType CBookViews::getType () const { return et_x_BookViews; diff --git a/OOXML/XlsxFormat/Workbook/BookViews.h b/OOXML/XlsxFormat/Workbook/BookViews.h index bd5c418df5..5570c88849 100644 --- a/OOXML/XlsxFormat/Workbook/BookViews.h +++ b/OOXML/XlsxFormat/Workbook/BookViews.h @@ -68,6 +68,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); virtual EElementType getType () const; private: @@ -106,6 +107,7 @@ namespace OOX void fromBin(std::vector& obj); std::vector toBin(); + void toXLS(XLS::BaseObjectPtr substreamPtr); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index 9911b3244d..ce968f4d16 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -451,6 +451,8 @@ namespace OOX m_oSheets->toXLS(objectPtr); if(m_oDefinedNames.IsInit()) m_oDefinedNames->toXLS(objectPtr); + if(m_oBookViews.IsInit()) + m_oBookViews->toXLS(objectPtr); return objectPtr; } From 680c83853a7e86380cfb8279f7866948d9260970 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 25 Jul 2025 14:44:08 +0600 Subject: [PATCH 020/318] Add fonts conversion --- .../Format/Logic/Biff_unions/FORMATTING.cpp | 18 ++--- .../Format/Logic/Biff_unions/FORMATTING.h | 4 +- OOXML/XlsxFormat/Styles/Fonts.cpp | 73 ++++++++++++++++++- OOXML/XlsxFormat/Styles/Fonts.h | 2 + OOXML/XlsxFormat/Styles/Styles.h | 1 + OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 18 +++++ OOXML/XlsxFormat/Xlsx.cpp | 2 + 7 files changed, 106 insertions(+), 12 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp index 0d66d53ab3..dd4a8b43d0 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.cpp @@ -156,17 +156,17 @@ const bool FORMATTING::loadContent(BinProcessor& proc) } const bool FORMATTING::saveContent(BinProcessor& proc) { - global_info = proc.getGlobalWorkbookInfo(); - for(auto i:global_info->m_arFonts) - proc.mandatory(*i); - if(global_info->m_arFonts.empty()) + + if(m_arFonts.empty()) proc.mandatory(); - for(auto i:global_info->m_mapNumFormats) - proc.mandatory(*i.second); - if(global_info->m_mapNumFormats.empty()) - { + for(auto i : m_arFonts) + if(i != nullptr) + proc.mandatory(*i); + if(m_arFormats.empty()) proc.mandatory(); - } + for(auto i:m_arFormats) + if(i != nullptr) + proc.mandatory(*i); if(m_XFS != nullptr) proc.mandatory(*m_XFS); else diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h index c31bdc740d..5640317055 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h @@ -59,8 +59,8 @@ public: BaseObjectPtr m_Styles; BaseObjectPtr m_XFS; - //std::vector m_arFormats; in global - //std::vector m_arFonts; in global + std::vector m_arFormats; + std::vector m_arFonts; BaseObjectPtr m_Palette; BaseObjectPtr m_ClrtClient; std::vector m_arDXF; diff --git a/OOXML/XlsxFormat/Styles/Fonts.cpp b/OOXML/XlsxFormat/Styles/Fonts.cpp index 47d0dbb12c..786150fe39 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.cpp +++ b/OOXML/XlsxFormat/Styles/Fonts.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -38,6 +38,8 @@ #include "../../XlsbFormat/Biff12_unions/FONTS.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Font.h" + namespace OOX { namespace Spreadsheet @@ -292,6 +294,66 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CFont::toXLS() + { + auto ptr = new XLS::Font; + if(m_oSz.IsInit()) + ptr->dyHeight = m_oSz->m_oVal->GetValue() * 20; + if(m_oItalic.IsInit()) + ptr->fItalic = m_oItalic->ToBool(); + if(m_oStrike.IsInit()) + ptr->fStrikeOut = m_oStrike->ToBool(); + if(m_oOutline.IsInit()) + ptr->fOutline = m_oOutline->ToBool(); + if(m_oShadow.IsInit()) + ptr->fShadow = m_oShadow->ToBool(); + if(m_oCondense.IsInit()) + ptr->fCondense = m_oCondense->ToBool(); + if(m_oExtend.IsInit()) + ptr->fExtend = m_oExtend->ToBool(); + + if(m_oColor.IsInit()) + { + //todo add icv color conversion + } + + if(m_oBold.IsInit() && m_oBold->ToBool()) + ptr->bls = 0x02BC; + else + ptr->bls = 0x0190; + if(m_oUnderline.IsInit() && m_oUnderline->m_oUnderline.IsInit()) + { + if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineNone) + ptr->uls = 0; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineSingle) + ptr->uls = 1; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineDouble) + ptr->uls = 2; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineSingleAccounting) + ptr->uls = 33; + else if(m_oUnderline->m_oUnderline == SimpleTypes::Spreadsheet::EUnderline::underlineDoubleAccounting) + ptr->uls = 34; + } + else + ptr->uls = 0; + if(m_oVertAlign.IsInit() && m_oVertAlign->m_oVerticalAlign.IsInit()) + { + if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunBaseline) + ptr->sss = 0; + else if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunSuperscript) + ptr->sss = 1; + else if(m_oVertAlign->m_oVerticalAlign->GetValue() == SimpleTypes::EVerticalAlignRun::verticalalignrunSubscript) + ptr->sss = 2; + } + if(m_oFamily.IsInit()) + ptr->bFamily = m_oFamily->m_oFontFamily->GetValue(); + + if(m_oCharset.IsInit()) + ptr->bCharSet = m_oCharset->m_oCharset->GetValue(); + if(m_oRFont.IsInit()) + ptr->fontName = m_oRFont->m_sVal.get(); + return XLS::BaseObjectPtr(ptr); + } EElementType CFont::getType () const { return et_x_Font; @@ -533,6 +595,15 @@ namespace OOX ptr1->cfonts = ptr->m_arBrtFont.size(); return objectPtr; } + std::vector CFonts::toXLS() + { + std::vector fontVector; + for(auto i:m_arrItems) + { + fontVector.push_back(i->toXLS()); + } + return fontVector; + } EElementType CFonts::getType () const { return et_x_Fonts; diff --git a/OOXML/XlsxFormat/Styles/Fonts.h b/OOXML/XlsxFormat/Styles/Fonts.h index 1f8050fcb8..fc9a062c1f 100644 --- a/OOXML/XlsxFormat/Styles/Fonts.h +++ b/OOXML/XlsxFormat/Styles/Fonts.h @@ -56,6 +56,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); virtual EElementType getType () const; @@ -97,6 +98,7 @@ namespace OOX void fromBin(std::vector& obj); XLS::BaseObjectPtr toBin(); + std::vector toXLS(); virtual EElementType getType () const; void AddFont (CFont* pFont); diff --git a/OOXML/XlsxFormat/Styles/Styles.h b/OOXML/XlsxFormat/Styles/Styles.h index 83ec20520f..91c555665c 100644 --- a/OOXML/XlsxFormat/Styles/Styles.h +++ b/OOXML/XlsxFormat/Styles/Styles.h @@ -106,6 +106,7 @@ namespace OOX void readBin(const CPath& oPath); XLS::BaseObjectPtr WriteBin() const; + void toXLS(XLS::BaseObjectPtr globalsStreamPtr) const; virtual void read(const CPath& oPath); virtual void read(const CPath& oRootPath, const CPath& oPath); diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index f0a974d7b0..8fad3b99c8 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -63,6 +63,15 @@ #include "../../Binary/XlsbFormat/FileTypes_SpreadsheetBin.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/STYLES.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Format.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/DXF.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Style.h" + namespace OOX { namespace Spreadsheet @@ -250,6 +259,15 @@ namespace OOX stylesStream->m_FRTSTYLESHEET = m_oExtLst->toBinStyles(); return objectPtr; } + void CStyles::toXLS(XLS::BaseObjectPtr globalsStreamPtr) const + { + auto workbookPtr = static_cast(globalsStreamPtr.get()); + auto FormatPtr = new XLS::FORMATTING; + workbookPtr->m_Formating = XLS::BaseObjectPtr(FormatPtr); + if (m_oFonts.IsInit()) + FormatPtr->m_arFonts = m_oFonts->toXLS(); + + } void CStyles::read(const CPath& oPath) { //don't use this. use read(const CPath& oRootPath, const CPath& oFilePath) diff --git a/OOXML/XlsxFormat/Xlsx.cpp b/OOXML/XlsxFormat/Xlsx.cpp index 63ae7df026..aea34ba332 100644 --- a/OOXML/XlsxFormat/Xlsx.cpp +++ b/OOXML/XlsxFormat/Xlsx.cpp @@ -204,6 +204,8 @@ bool OOX::Spreadsheet::CXlsx::WriteXLS(const CPath& oFilePath) workbookStream->m_arWorksheetSubstream.push_back(i->toXLS()); if(m_pSharedStrings != nullptr) m_pSharedStrings->toXLS(workbookStream->m_GlobalsSubstream); + if(m_pStyles != nullptr) + m_pStyles->toXLS(workbookStream->m_GlobalsSubstream); writer.Open(oFilePath.GetPath()); writer.WriteWorkbook(workbookPtr); From ffc94bf455461779d8e3d9cd6fcf1c09be8bd6fd Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 25 Jul 2025 15:27:53 +0600 Subject: [PATCH 021/318] Add numFmts conversion --- OOXML/XlsxFormat/Styles/NumFmts.cpp | 22 +++++++++++++++++++++- OOXML/XlsxFormat/Styles/NumFmts.h | 2 ++ OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 3 ++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/NumFmts.cpp b/OOXML/XlsxFormat/Styles/NumFmts.cpp index f141813c4b..d51a094279 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.cpp +++ b/OOXML/XlsxFormat/Styles/NumFmts.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -39,6 +39,8 @@ #include "../../XlsbFormat/Biff12_unions/FMTS.h" #include "../../XlsbFormat/Biff12_records/BeginFmts.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Format.h" + namespace OOX { namespace Spreadsheet @@ -100,6 +102,15 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CNumFmt::toXLS() + { + auto fmt = new XLS::Format; + if(m_oNumFmtId.IsInit()) + fmt->ifmt = m_oNumFmtId->GetValue(); + if(m_oFormatCode.IsInit()) + fmt->stFormat = m_oFormatCode.get(); + return XLS::BaseObjectPtr(fmt); + } EElementType CNumFmt::getType () const { return et_x_NumFmt; @@ -218,6 +229,15 @@ namespace OOX beginfmt->cfmts = fmts->m_arBrtFmt.size(); return objectPtr; } + std::vector CNumFmts::toXLS() + { + std::vector fmtVector; + for(auto i:m_arrItems) + { + fmtVector.push_back(i->toXLS()); + } + return fmtVector; + } EElementType CNumFmts::getType () const { return et_x_NumFmts; diff --git a/OOXML/XlsxFormat/Styles/NumFmts.h b/OOXML/XlsxFormat/Styles/NumFmts.h index fa3bc7371b..c74864515c 100644 --- a/OOXML/XlsxFormat/Styles/NumFmts.h +++ b/OOXML/XlsxFormat/Styles/NumFmts.h @@ -62,6 +62,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); virtual EElementType getType () const; @@ -92,6 +93,7 @@ namespace OOX void fromBin(std::vector& obj); XLS::BaseObjectPtr toBin(); + std::vector toXLS(); virtual EElementType getType () const; private: diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index 8fad3b99c8..73c0e0940a 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -67,7 +67,6 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/STYLES.h" -#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Format.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/DXF.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Style.h" @@ -266,6 +265,8 @@ namespace OOX workbookPtr->m_Formating = XLS::BaseObjectPtr(FormatPtr); if (m_oFonts.IsInit()) FormatPtr->m_arFonts = m_oFonts->toXLS(); + if (m_oNumFmts.IsInit()) + FormatPtr->m_arFormats = m_oNumFmts->toXLS(); } void CStyles::read(const CPath& oPath) From d1c99891c6ad3221f0ab8d57591af2afb1343237 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 25 Jul 2025 18:12:27 +0600 Subject: [PATCH 022/318] Add xfs conversion --- .../XlsFile/Format/Logic/Biff_unions/XFS.cpp | 19 ++--- OOXML/XlsxFormat/Styles/Xfs.cpp | 76 ++++++++++++++++++- OOXML/XlsxFormat/Styles/Xfs.h | 3 + OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 12 ++- 4 files changed, 93 insertions(+), 17 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp index d4e46c8937..4f07a36921 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp @@ -112,20 +112,11 @@ const bool XFS::loadContent(BinProcessor& proc) } const bool XFS::saveContent(BinProcessor& proc) -{ for (auto i: m_arCellXFs) - if(i!= nullptr) - proc.mandatory(*i); - if(m_arCellXFs.empty()) - { - size_t cellId = 0; - size_t StyleId = 0; - XF styleXf(cellId, StyleId); - proc.mandatory(styleXf); - XF cellXf(cellId, StyleId); - cellXf.fStyle = false; - proc.mandatory(cellXf); - } - for (auto i: m_arCellStyles) +{ + for (auto i: m_arCellStyles) + if(i!= nullptr) + proc.mandatory(*i); + for (auto i: m_arCellXFs) if(i!= nullptr) proc.mandatory(*i); if(m_XFCRC != nullptr ) diff --git a/OOXML/XlsxFormat/Styles/Xfs.cpp b/OOXML/XlsxFormat/Styles/Xfs.cpp index 960e5db3dd..4ac57af127 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.cpp +++ b/OOXML/XlsxFormat/Styles/Xfs.cpp @@ -1,4 +1,4 @@ -/* +/* * (c) Copyright Ascensio System SIA 2010-2023 * * This program is a free software product. You can redistribute it and/or @@ -42,6 +42,9 @@ #include "../../XlsbFormat/Biff12_unions/CELLSTYLEXFS.h" #include "../../XlsbFormat/Biff12_unions/CELLXFS.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h" + namespace OOX { namespace Spreadsheet @@ -450,6 +453,55 @@ namespace OOX return objectPtr; } + XLS::BaseObjectPtr CXfs::toXLS() + { + size_t id = 0; + auto ptr = new XLS::XF(id, id); + XLS::BaseObjectPtr objectPtr(ptr); + if(m_oBorderId.IsInit()) + ptr->ixBorder = m_oBorderId->GetValue(); + if(m_oFillId.IsInit()) + ptr->iFill = m_oFillId->GetValue(); + if(m_oFontId.IsInit()) + ptr->font_index = m_oFontId->GetValue(); + if(m_oNumFmtId.IsInit()) + ptr->ifmt = m_oNumFmtId->GetValue(); + if(m_oPivotButton.IsInit()) + ptr->fsxButton = m_oPivotButton->GetValue(); + if(m_oQuotePrefix.IsInit()) + ptr->f123Prefix = m_oQuotePrefix->GetValue(); + + if (m_oXfId.IsInit()) + ptr->ixfParent = m_oXfId->GetValue(); + + if(m_oAligment.IsInit()) + { + m_oAligment->toBin(objectPtr); + } + else + { + ptr->alc = 0; + ptr->alcV = 2; + } + if(!m_oProtection.IsInit()) + m_oProtection.Init(); + m_oProtection->toBin(objectPtr); + + if(m_oApplyAlignment.IsInit()) + ptr->fAtrAlc = m_oApplyAlignment->GetValue(); + + if(m_oApplyBorder.IsInit()) + ptr->fAtrBdr = m_oApplyBorder->GetValue(); + if(m_oApplyFill.IsInit()) + ptr->fAtrPat = m_oApplyFill->GetValue(); + if(m_oApplyFont.IsInit()) + ptr->fAtrFnt = m_oApplyFont->GetValue(); + if(m_oApplyNumberFormat.IsInit()) + ptr->fAtrNum = m_oApplyNumberFormat->GetValue(); + if(m_oApplyProtection.IsInit()) + ptr->fAtrProt = m_oApplyProtection->GetValue(); + return objectPtr; + } void CXfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) @@ -561,6 +613,17 @@ namespace OOX ptr1->cxfs = ptr->m_arBrtXF.size(); return objectPtr; } + void CCellXfs::toXLS(XLS::BaseObjectPtr Xfs) + { + auto ptr = static_cast(Xfs.get()); + for(auto i:m_arrItems) + { + auto CellXf = i->toXLS(); + auto castedXF = static_cast(CellXf.get()); + castedXF->fStyle = false; + ptr->m_arCellXFs.push_back(CellXf); + } + } EElementType CCellXfs::getType () const { return et_x_CellXfs; @@ -654,6 +717,17 @@ namespace OOX ptr1->cxfs = ptr->m_arBrtXF.size(); return objectPtr; } + void CCellStyleXfs::toXLS(XLS::BaseObjectPtr Xfs) + { + auto ptr = static_cast(Xfs.get()); + for(auto i:m_arrItems) + { + auto styleXf = i->toXLS(); + auto castedXF = static_cast(styleXf.get()); + castedXF->fStyle = true; + ptr->m_arCellStyles.push_back(styleXf); + } + } void CCellStyleXfs::ReadAttributes(XmlUtils::CXmlLiteReader& oReader) { WritingElement_ReadAttributes_Start( oReader ) diff --git a/OOXML/XlsxFormat/Styles/Xfs.h b/OOXML/XlsxFormat/Styles/Xfs.h index 480f460ca7..49429f03b0 100644 --- a/OOXML/XlsxFormat/Styles/Xfs.h +++ b/OOXML/XlsxFormat/Styles/Xfs.h @@ -137,6 +137,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); @@ -178,6 +179,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); void fromBin(std::vector& obj); XLS::BaseObjectPtr toBin(); + void toXLS(XLS::BaseObjectPtr Xfs); virtual EElementType getType () const; @@ -207,6 +209,7 @@ namespace OOX void fromBin(std::vector& obj); XLS::BaseObjectPtr toBin(); + void toXLS(XLS::BaseObjectPtr Xfs); private: void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index 73c0e0940a..ee7245f681 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -65,10 +65,9 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h" -#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/STYLES.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/DXF.h" -#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Style.h" namespace OOX @@ -267,6 +266,15 @@ namespace OOX FormatPtr->m_arFonts = m_oFonts->toXLS(); if (m_oNumFmts.IsInit()) FormatPtr->m_arFormats = m_oNumFmts->toXLS(); + if(m_oCellStyleXfs.IsInit() || m_oCellXfs.IsInit()) + { + auto xfs = new XLS::XFS; + FormatPtr->m_XFS = XLS::BaseObjectPtr(xfs); + if(m_oCellStyleXfs.IsInit()) + m_oCellStyleXfs->toXLS(FormatPtr->m_XFS); + if(m_oCellXfs.IsInit()) + m_oCellXfs->toXLS(FormatPtr->m_XFS); + } } void CStyles::read(const CPath& oPath) From c779654a58f1cf656dbf2d90e0392bb8df782c39 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 25 Jul 2025 21:04:32 +0600 Subject: [PATCH 023/318] Add cell styles conversion --- OOXML/XlsxFormat/Styles/CellStyles.cpp | 31 ++++++++++++++++++++++++++ OOXML/XlsxFormat/Styles/CellStyles.h | 2 ++ OOXML/XlsxFormat/Styles/XlsxStyles.cpp | 4 ++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/Styles/CellStyles.cpp b/OOXML/XlsxFormat/Styles/CellStyles.cpp index 39d6a4fbbb..7eb8af486b 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.cpp +++ b/OOXML/XlsxFormat/Styles/CellStyles.cpp @@ -38,6 +38,9 @@ #include "../../XlsbFormat/Biff12_unions/STYLES.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/STYLES.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Style.h" + namespace OOX { namespace Spreadsheet @@ -107,6 +110,25 @@ namespace OOX ptr->ixf = 0; return objectPtr; } + XLS::BaseObjectPtr CCellStyle::toXLS() + { + auto ptr = new XLS::Style; + if (m_oXfId.IsInit()) + ptr->ixfe = m_oXfId->GetValue(); + if(m_oBuiltinId.IsInit()) + { + ptr->fBuiltIn = true; + ptr->builtInData.istyBuiltIn = m_oBuiltinId->GetValue(); + if(m_oILevel.IsInit()) + ptr->builtInData.iLevel = m_oILevel->GetValue(); + } + else if (m_oName.IsInit()) + { + ptr->fBuiltIn = false; + ptr->user = m_oName.get(); + } + return XLS::BaseObjectPtr(ptr); + } EElementType CCellStyle::getType () const { return et_x_CellStyle; @@ -207,6 +229,15 @@ namespace OOX ptr1->cstyles = ptr->m_arBrtStyle.size(); return objectPtr; } + XLS::BaseObjectPtr CCellStyles::toXLS() + { + auto ptr = new XLS::STYLES; + for(auto i:m_arrItems) + { + ptr->m_arStyles.push_back(std::make_pair(i->toXLS(), nullptr)); + } + return XLS::BaseObjectPtr(ptr); + } EElementType CCellStyles::getType () const { return et_x_CellStyles; diff --git a/OOXML/XlsxFormat/Styles/CellStyles.h b/OOXML/XlsxFormat/Styles/CellStyles.h index d69e44c085..1dfa493ce7 100644 --- a/OOXML/XlsxFormat/Styles/CellStyles.h +++ b/OOXML/XlsxFormat/Styles/CellStyles.h @@ -61,6 +61,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void fromBin(XLS::BaseObjectPtr& obj); virtual EElementType getType () const; @@ -92,6 +93,7 @@ namespace OOX virtual void fromXML(XmlUtils::CXmlLiteReader& oReader); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void fromBin(std::vector& obj); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp index ee7245f681..47a40d8c92 100644 --- a/OOXML/XlsxFormat/Styles/XlsxStyles.cpp +++ b/OOXML/XlsxFormat/Styles/XlsxStyles.cpp @@ -65,10 +65,8 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/GlobalsSubstream.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/FORMATTING.h" -#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/STYLES.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/DXF.h" -#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Style.h" namespace OOX { @@ -275,6 +273,8 @@ namespace OOX if(m_oCellXfs.IsInit()) m_oCellXfs->toXLS(FormatPtr->m_XFS); } + if (m_oCellStyles.IsInit()) + FormatPtr->m_Styles = m_oCellStyles->toXLS(); } void CStyles::read(const CPath& oPath) From af20b1f63d8cfd4b80438c7182483b09dcecbab1 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 28 Jul 2025 18:34:52 +0600 Subject: [PATCH 024/318] fix cell xf index writiong --- MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp | 2 +- .../XlsFile/Format/Logic/Biff_structures/Cell.cpp | 5 +++++ .../XlsFile/Format/Logic/Biff_structures/RkRec.cpp | 5 +++++ MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp | 10 ++++++++++ 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp index 14411c2e79..967361fc23 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp @@ -418,7 +418,7 @@ void XF::writeFields(CFRecord& record) if(font_index == 0xffff) font_index = 0; if(ifmt == 0xffff) - ifmt = 0; + ifmt = 164; if(ixfParent == 0) ixfParent = 0xfff; FontIndex ifnt; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp index 024c301d11..a543451e27 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/Cell.cpp @@ -87,6 +87,11 @@ void Cell::load(CFRecord& record) } void Cell::save(CFRecord& record) { + auto globInfo = record.getGlobalWorkbookInfo(); + if(ixfe != 0) + { + ixfe+= globInfo->cellStyleXfs_count; + } record << rw << col << ixfe; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp index 08b30a5b72..40eaa6ee12 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/RkRec.cpp @@ -49,6 +49,11 @@ void RkRec::load(CFRecord& record) } void RkRec::save(CFRecord& record) { + auto globInfo = record.getGlobalWorkbookInfo(); + if(ixfe != 0) + { + ixfe+= globInfo->cellStyleXfs_count; + } record << ixfe << RK_; } diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp index 4f07a36921..35e54caea9 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/XFS.cpp @@ -113,12 +113,22 @@ const bool XFS::loadContent(BinProcessor& proc) const bool XFS::saveContent(BinProcessor& proc) { + auto globInfo = proc.getGlobalWorkbookInfo(); + for(auto i = 0; i < 16; i++) + { + size_t index = 0; + XF cellStyleMandatory(index, index); + cellStyleMandatory.fStyle = true; + proc.mandatory(cellStyleMandatory); + } for (auto i: m_arCellStyles) if(i!= nullptr) proc.mandatory(*i); + globInfo->cellStyleXfs_count = m_arCellStyles.size() + 16; // styles + 16 mandatory styles for (auto i: m_arCellXFs) if(i!= nullptr) proc.mandatory(*i); + globInfo->cellXfs_count = m_arCellXFs.size(); if(m_XFCRC != nullptr ) { proc.mandatory(*m_XFCRC); From afb0f44af27cb9270353a4cf3a9b27e6e7fb03d2 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 28 Jul 2025 20:49:38 +0600 Subject: [PATCH 025/318] Add crun shared string conversion --- OOXML/XlsxFormat/SharedStrings/Si.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index 64fa485fa0..959ba8fd76 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -203,6 +203,19 @@ namespace OOX StringPtr->str_ = text->ToString(); continue; } + if(m_arrItems[i]->getType() == OOX::et_x_r) + { + auto crunPtr = static_cast(m_arrItems[i]); + StringPtr->fRichSt = true; + USHORT ind = 0; + XLS::FormatRun run; + run.ich = StringPtr->str_.size(); + StringPtr->str_ = StringPtr->str_ + crunPtr->toBin(ind); + run.ifnt.value() = ind; + if(run.ich != 0 || run.ifnt != 0) + StringPtr->rgRun.push_back(run); + continue; + } } auto StructPtr = XLS::BiffStructurePtr(StringPtr); return StructPtr; From 92fae52a6df8ac385accb6c7d84ed1f855acd68e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Mon, 28 Jul 2025 21:52:30 +0600 Subject: [PATCH 026/318] Fix rich string xls conversion --- OOXML/XlsxFormat/SharedStrings/Si.cpp | 3 ++- X2tConverter/src/lib/xlsx.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index 959ba8fd76..f07744a7a6 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -211,7 +211,8 @@ namespace OOX XLS::FormatRun run; run.ich = StringPtr->str_.size(); StringPtr->str_ = StringPtr->str_ + crunPtr->toBin(ind); - run.ifnt.value() = ind; + if(ind != 0) + run.ifnt.value() = ind+1; if(run.ich != 0 || run.ifnt != 0) StringPtr->rgRun.push_back(run); continue; diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index 5d9d834edd..e06299189c 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -176,8 +176,9 @@ namespace NExtractTools _UINT32 nRes = S_OK; const OOX::CPath oox_path(sFrom); { - OOX::Spreadsheet::CXlsx oXlsx; + OOX::Spreadsheet::CXlsb oXlsx; oXlsx.Read(oox_path); + oXlsx.PrepareRichStr(); nRes = oXlsx.WriteXLS(sTo)? S_OK : AVS_FILEUTILS_ERROR_CONVERT;; } return nRes; From f95014f46ff55aa0999f7473d0a491a6a5afa961 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Tue, 29 Jul 2025 17:25:33 +0600 Subject: [PATCH 027/318] Add phonetic string conversion --- .../Format/Logic/Biff_structures/ExtRst.cpp | 1 + OOXML/XlsxFormat/SharedStrings/Si.cpp | 34 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtRst.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtRst.cpp index 0919161561..6f82a61286 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtRst.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/ExtRst.cpp @@ -84,6 +84,7 @@ void ExtRst::save(CFRecord& record) record.reserveNunBytes(2); record << phs; auto rphssubStart = record.getRdPtr(); + rphssub.crun = rgphruns.size(); record << rphssub; cb = record.getRdPtr() - rphssubStart; record.RollRdPtrBack(record.getRdPtr() - cbPose); diff --git a/OOXML/XlsxFormat/SharedStrings/Si.cpp b/OOXML/XlsxFormat/SharedStrings/Si.cpp index f07744a7a6..96abd48d89 100644 --- a/OOXML/XlsxFormat/SharedStrings/Si.cpp +++ b/OOXML/XlsxFormat/SharedStrings/Si.cpp @@ -35,7 +35,7 @@ #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_structures/XLUnicodeRichExtendedString.h" #include "../../Binary/Presentation/BinaryFileReaderWriter.h" - +#include "../../Common/SimpleTypes_Shared.h" namespace OOX { namespace Spreadsheet @@ -217,6 +217,38 @@ namespace OOX StringPtr->rgRun.push_back(run); continue; } + auto phonPtr = static_cast(m_arrItems[i]); + if(phonPtr) + { + StringPtr->fExtSt = true; + StringPtr->extRst.rphssub.st = L""; + if(phonPtr->m_oFontId.IsInit()) + StringPtr->extRst.phs.ifnt = phonPtr->m_oFontId->GetValue(); + if(phonPtr->m_oAlignment.IsInit()) + StringPtr->extRst.phs.data.alcH = phonPtr->m_oAlignment->GetValue(); + if(phonPtr->m_oType.IsInit()) + StringPtr->extRst.phs.data.phType = phonPtr->m_oType->GetValue(); + + if(i < m_arrItems.size() - 1) + { + auto ph = static_cast(m_arrItems[i+1]); + if(ph) + { + XLS::PhRuns runs; + if(ph->m_oEb.IsInit()) + runs.ichMom = ph->m_oEb->GetValue(); + if(ph->m_oSb.IsInit()) + runs.ichFirst = ph->m_oSb->GetValue(); + if(!ph->m_arrItems.empty()) + { + StringPtr->extRst.rphssub.st.value() += ph->m_arrItems.back()->ToString(); + runs.ichMom = ph->m_arrItems.back()->ToString().size(); + } + StringPtr->extRst.rgphruns.push_back(runs); + } + i++; + } + } } auto StructPtr = XLS::BiffStructurePtr(StringPtr); return StructPtr; From 897ea781b74be14c096ceb6255ba49cfaa274a72 Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 30 Jul 2025 15:45:59 +0600 Subject: [PATCH 028/318] Fix font conversion --- MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp index 967361fc23..5e6637cae2 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/XF.cpp @@ -422,7 +422,7 @@ void XF::writeFields(CFRecord& record) if(ixfParent == 0) ixfParent = 0xfff; FontIndex ifnt; - ifnt.setValue(font_index); + ifnt.setValue(font_index + 1); record < Date: Wed, 30 Jul 2025 16:54:57 +0600 Subject: [PATCH 029/318] add workbook protection conversion --- OOXML/XlsxFormat/Workbook/Workbook.cpp | 3 +- OOXML/XlsxFormat/Workbook/WorkbookPr.cpp | 39 ++++++++++++++++++++++++ OOXML/XlsxFormat/Workbook/WorkbookPr.h | 1 + 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/OOXML/XlsxFormat/Workbook/Workbook.cpp b/OOXML/XlsxFormat/Workbook/Workbook.cpp index ce968f4d16..2c46c3b10b 100644 --- a/OOXML/XlsxFormat/Workbook/Workbook.cpp +++ b/OOXML/XlsxFormat/Workbook/Workbook.cpp @@ -453,7 +453,8 @@ namespace OOX m_oDefinedNames->toXLS(objectPtr); if(m_oBookViews.IsInit()) m_oBookViews->toXLS(objectPtr); - + if (m_oWorkbookProtection.IsInit()) + globalsSubstream->m_PROTECTION = m_oWorkbookProtection->toXLS(); return objectPtr; } void CWorkbook::read(const CPath& oPath) diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp index 729b85fdad..faf254bd2c 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.cpp @@ -38,6 +38,13 @@ #include "../../XlsbFormat/Biff12_records/FileSharingIso.h" #include "../../XlsbFormat/Biff12_records/CommonRecords.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PROTECTION.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/WinProtect.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Protect.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Password.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Prot4Rev.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Prot4RevPass.h" + #include "../../Common/SimpleTypes_Word.h" #include "../../Common/SimpleTypes_Shared.h" #include "../../Common/SimpleTypes_Spreadsheet.h" @@ -342,6 +349,38 @@ namespace OOX } return objectPtr; } + XLS::BaseObjectPtr CWorkbookProtection::toXLS() + { + auto ptr = new XLS::PROTECTION; + if(m_oLockWindows.IsInit()) + { + auto winPtr = new XLS::WinProtect; + winPtr->fLockWn = m_oLockWindows->GetValue(); + ptr->m_WinProtect = XLS::BaseObjectPtr(winPtr); + } + if(m_oLockStructure.IsInit()) + { + auto protPtr = new XLS::Protect; + protPtr->fLock = m_oLockStructure->GetValue(); + ptr->m_Protect = XLS::BaseObjectPtr(protPtr); + } + if(m_oPassword.IsInit()) + { + auto pass = new XLS::Password; + pass->wPassword = m_oPassword.get(); + ptr->m_Password = XLS::BaseObjectPtr(pass); + } + if(m_oLockRevision.IsInit() && m_oPassword.IsInit()) + { + auto rev = new XLS::Prot4Rev; + rev->fRevLock = m_oLockRevision->GetValue(); + ptr->m_Prot4Rev = XLS::BaseObjectPtr(rev); + auto revPass = new XLS::Prot4RevPass; + revPass->protPwdRev = m_oPassword.get(); + ptr->m_Prot4RevPass = XLS::BaseObjectPtr(revPass); + } + return XLS::BaseObjectPtr(ptr); + } void CWorkbookProtection::fromBin(XLS::BaseObjectPtr& obj) { ReadAttributes(obj); diff --git a/OOXML/XlsxFormat/Workbook/WorkbookPr.h b/OOXML/XlsxFormat/Workbook/WorkbookPr.h index 77de4016ec..9de89a5894 100644 --- a/OOXML/XlsxFormat/Workbook/WorkbookPr.h +++ b/OOXML/XlsxFormat/Workbook/WorkbookPr.h @@ -111,6 +111,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); virtual EElementType getType() const; void ReadAttributes(XmlUtils::CXmlLiteReader& oReader); From 0a7ad2f560dcd7ffef1451e36be99cd50a6eaf7e Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Wed, 30 Jul 2025 17:25:53 +0600 Subject: [PATCH 030/318] Add worksheet protection conversion --- OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 2 ++ .../Worksheets/WorksheetChildOther.cpp | 34 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 1 + 3 files changed, 37 insertions(+) diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index cfe542248d..fa37616542 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -372,6 +372,8 @@ namespace OOX worksheetPtr->m_arMergeCells = m_oMergeCells->toXLS(); if(m_oSheetViews.IsInit()) worksheetPtr->m_arWINDOW = m_oSheetViews->toXLS(); + if(m_oSheetProtection.IsInit()) + worksheetPtr->m_PROTECTION = m_oSheetProtection->toXLS(); if(m_oSheetData.IsInit()) worksheetPtr->m_CELLTABLE = m_oSheetData->toXLS(); diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp index 9208e34e1f..66accffcf8 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.cpp @@ -73,8 +73,13 @@ #include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/WINDOW.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PROTECTION_COMMON.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Window2.h" #include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Dimensions.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Protect.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/ObjProtect.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/ScenarioProtect.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/Password.h" namespace OOX { @@ -3871,6 +3876,35 @@ namespace OOX writer->storeNextRecord(record); } } + XLS::BaseObjectPtr CSheetProtection::toXLS() + { + auto ptr = new XLS::PROTECTION_COMMON; + if(m_oSheet.IsInit()) + { + auto protPtr = new XLS::Protect; + protPtr->fLock = m_oSheet->GetValue(); + ptr->m_Protect = XLS::BaseObjectPtr(protPtr); + } + if(m_oObjects.IsInit()) + { + auto objPtr = new XLS::ObjProtect; + objPtr->fLockObj = m_oObjects->GetValue(); + ptr->m_ObjProtect = XLS::BaseObjectPtr(objPtr); + } + if(m_oScenarios.IsInit()) + { + auto scenPtr = new XLS::ScenarioProtect; + scenPtr->fScenProtect = m_oScenarios->GetValue(); + ptr->m_ScenarioProtect = XLS::BaseObjectPtr(scenPtr); + } + if(m_oPassword.IsInit()) + { + auto passPtr = new XLS::Password; + passPtr->wPassword = m_oPassword.get(); + ptr->m_Password = XLS::BaseObjectPtr(passPtr); + } + return XLS::BaseObjectPtr(ptr); + } XLS::BaseObjectPtr CSheetProtection::toBinCS() { XLS::BaseObjectPtr objectPtr; diff --git a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h index 3f7e316d32..849373f49d 100644 --- a/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h +++ b/OOXML/XlsxFormat/Worksheets/WorksheetChildOther.h @@ -776,6 +776,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); XLS::BaseObjectPtr toBinCS(); void toBinCS(XLS::StreamCacheWriterPtr& writer); From cf5208d6a5cad6d2d8ffe7668599c2f86583ad4a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 31 Jul 2025 13:53:14 +0600 Subject: [PATCH 031/318] Add hyperlinks conversion --- .../Format/Logic/Biff_records/HLink.cpp | 3 +- OOXML/XlsxFormat/Worksheets/Hyperlinks.h | 2 + OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 2 + .../XlsxFormat/Worksheets/XlsxHyperlinks.cpp | 37 +++++++++++++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp index 4670d2ad29..856d4ea7b1 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp @@ -62,7 +62,8 @@ void HLink::writeFields(CFRecord& record) { record << ref8; _GUID_ guid_num(0, 0, 0, 0); - STR::bstr2guid(hlinkClsid, guid_num); + if(!hlinkClsid.empty()) + STR::bstr2guid(hlinkClsid, guid_num); record << guid_num << hyperlink; } diff --git a/OOXML/XlsxFormat/Worksheets/Hyperlinks.h b/OOXML/XlsxFormat/Worksheets/Hyperlinks.h index 4270abb16d..435d2796e4 100644 --- a/OOXML/XlsxFormat/Worksheets/Hyperlinks.h +++ b/OOXML/XlsxFormat/Worksheets/Hyperlinks.h @@ -60,6 +60,7 @@ namespace OOX void fromBin(XLS::BaseObjectPtr& obj); XLS::BaseObjectPtr toBin(); + XLS::BaseObjectPtr toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; @@ -93,6 +94,7 @@ namespace OOX void fromBin(std::vector& obj); XLS::BaseObjectPtr toBin(); + std::vector toXLS(); void toBin(XLS::StreamCacheWriterPtr& writer); virtual EElementType getType () const; diff --git a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp index fa37616542..cb68ae831e 100644 --- a/OOXML/XlsxFormat/Worksheets/Worksheet.cpp +++ b/OOXML/XlsxFormat/Worksheets/Worksheet.cpp @@ -374,6 +374,8 @@ namespace OOX worksheetPtr->m_arWINDOW = m_oSheetViews->toXLS(); if(m_oSheetProtection.IsInit()) worksheetPtr->m_PROTECTION = m_oSheetProtection->toXLS(); + if(m_oHyperlinks.IsInit()) + worksheetPtr->m_arHLINK = m_oHyperlinks->toXLS(); if(m_oSheetData.IsInit()) worksheetPtr->m_CELLTABLE = m_oSheetData->toXLS(); diff --git a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp index 795baf501e..474f3db64f 100644 --- a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp +++ b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp @@ -38,6 +38,9 @@ #include "../../XlsbFormat/Biff12_unions/HLINKS.h" #include "../../../MsBinaryFile/XlsFile/Format/Binary/CFStreamCacheWriter.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_unions/HLINK.h" +#include "../../../MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h" + namespace OOX { namespace Spreadsheet @@ -102,6 +105,31 @@ namespace OOX return ptr; } + XLS::BaseObjectPtr CHyperlink::toXLS() + { + auto unionPtr = new XLS::HLINK; + auto ptr = new XLS::HLink; + unionPtr->m_HLink = XLS::BaseObjectPtr(ptr); + if(m_oRef.IsInit()) + ptr->ref8.fromString(m_oRef.get()); + if(m_oDisplay.IsInit()) + { + ptr->hyperlink.hlstmfHasDisplayName = true; + ptr->hyperlink.displayName = m_oDisplay.get(); + } + if(m_oLocation.IsInit()) + { + ptr->hyperlink.hlstmfHasLocationStr = true; + ptr->hyperlink.location = m_oLocation.get(); + } + if(m_oRef.IsInit()) + { + ptr->hyperlink.hlstmfHasMoniker = true; + ptr->hyperlink.hlstmfMonikerSavedAsStr = true; + ptr->hyperlink.moniker = m_oRef.get(); + } + return XLS::BaseObjectPtr(unionPtr); + } void CHyperlink::toBin(XLS::StreamCacheWriterPtr& writer) { auto record = writer->getNextRecord(XLSB::rt_HLink); @@ -245,6 +273,15 @@ namespace OOX } return ptr; } + std::vector CHyperlinks::toXLS() + { + std::vector objectVector; + for(auto i:m_arrItems) + { + objectVector.push_back(i->toXLS()); + } + return objectVector; + } void CHyperlinks::toBin(XLS::StreamCacheWriterPtr& writer) { for(auto i : m_arrItems) From c3ce1d2756bcdef97673f752c11ca53c8d94606a Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Thu, 31 Jul 2025 19:14:09 +0600 Subject: [PATCH 032/318] Fix hlink conversion --- .../Format/Logic/Biff_records/HLink.cpp | 2 +- .../XlsFile/Format/Logic/Biff_records/HLink.h | 2 +- .../Logic/Biff_structures/HyperlinkObject.cpp | 3 ++- OOXML/XlsbFormat/Xlsb.cpp | 19 +++++++++++++++++++ OOXML/XlsbFormat/Xlsb.h | 1 + .../XlsxFormat/Worksheets/XlsxHyperlinks.cpp | 6 +++--- X2tConverter/src/lib/xlsx.h | 1 + 7 files changed, 28 insertions(+), 6 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp index 856d4ea7b1..a1832a0f91 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.cpp @@ -61,7 +61,7 @@ void HLink::readFields(CFRecord& record) void HLink::writeFields(CFRecord& record) { record << ref8; - _GUID_ guid_num(0, 0, 0, 0); + _GUID_ guid_num; if(!hlinkClsid.empty()) STR::bstr2guid(hlinkClsid, guid_num); record << guid_num << hyperlink; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h index d79b2e0bca..6de7163dbd 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/HLink.h @@ -58,7 +58,7 @@ public: //----------------------------- Ref8U ref8; - std::wstring hlinkClsid; + std::wstring hlinkClsid = L"{79EAC9D0-BAF9-11CE-8C82-00AA004BA90B}"; OSHARED::HyperlinkObject hyperlink; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp index 9fed5ce6af..a1ab168ffb 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_structures/HyperlinkObject.cpp @@ -162,7 +162,8 @@ std::wstring HyperlinkObject::loadHyperlinkString(XLS::CFRecord& record) } void HyperlinkObject::saveHyperlinkString(XLS::CFRecord& record, std::wstring hlinkString) { - _INT32 size = hlinkString.size(); + hlinkString += L'\0'; + _INT32 size = hlinkString.size(); record << size; for(auto i : hlinkString) { diff --git a/OOXML/XlsbFormat/Xlsb.cpp b/OOXML/XlsbFormat/Xlsb.cpp index 53dcb44adb..a3a5c2a5ef 100644 --- a/OOXML/XlsbFormat/Xlsb.cpp +++ b/OOXML/XlsbFormat/Xlsb.cpp @@ -228,6 +228,25 @@ void OOX::Spreadsheet::CXlsb::PrepareSi() } } +// подготовка гиперссылок для записи в xls +void OOX::Spreadsheet::CXlsb::PrepareHlinks() +{ + for(auto i : m_arWorksheets) + { + if(i->m_oHyperlinks.IsInit()) + { + for(auto hlink : i->m_oHyperlinks->m_arrItems) + { + if(!hlink->m_oLink.IsInit() && hlink->m_oRid.IsInit()) + { + auto rel = static_cast(i->Find(hlink->m_oRid->GetValue()).GetPointer()); + if(rel != nullptr) + hlink->m_oLink = rel->Uri().GetFilename(); + } + } + } + } +} //подготовка шрифтов в richString для конвертации в xlsb void OOX::Spreadsheet::CXlsb::PrepareRichStr() { diff --git a/OOXML/XlsbFormat/Xlsb.h b/OOXML/XlsbFormat/Xlsb.h index fa1ea30b5e..d78dbfe783 100644 --- a/OOXML/XlsbFormat/Xlsb.h +++ b/OOXML/XlsbFormat/Xlsb.h @@ -68,6 +68,7 @@ namespace OOX XLS::GlobalWorkbookInfo* GetGlobalinfo(); void PrepareSi(); + void PrepareHlinks(); void PrepareTableFormula(); void LinkTables(); void ReadSheetData(); diff --git a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp index 474f3db64f..69e5b630e3 100644 --- a/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp +++ b/OOXML/XlsxFormat/Worksheets/XlsxHyperlinks.cpp @@ -120,13 +120,13 @@ namespace OOX if(m_oLocation.IsInit()) { ptr->hyperlink.hlstmfHasLocationStr = true; - ptr->hyperlink.location = m_oLocation.get(); + ptr->hyperlink.location = m_oRef.get(); } - if(m_oRef.IsInit()) + if(m_oLink.IsInit()) { ptr->hyperlink.hlstmfHasMoniker = true; ptr->hyperlink.hlstmfMonikerSavedAsStr = true; - ptr->hyperlink.moniker = m_oRef.get(); + ptr->hyperlink.moniker = m_oLink.get(); } return XLS::BaseObjectPtr(unionPtr); } diff --git a/X2tConverter/src/lib/xlsx.h b/X2tConverter/src/lib/xlsx.h index e06299189c..6d9836d8d3 100644 --- a/X2tConverter/src/lib/xlsx.h +++ b/X2tConverter/src/lib/xlsx.h @@ -178,6 +178,7 @@ namespace NExtractTools { OOX::Spreadsheet::CXlsb oXlsx; oXlsx.Read(oox_path); + oXlsx.PrepareHlinks(); oXlsx.PrepareRichStr(); nRes = oXlsx.WriteXLS(sTo)? S_OK : AVS_FILEUTILS_ERROR_CONVERT;; } From 2a6e76a2bc7c395e746fc4f794db1b4735ca9acb Mon Sep 17 00:00:00 2001 From: Viktor Andreev Date: Fri, 1 Aug 2025 15:42:05 +0600 Subject: [PATCH 033/318] Add pagesetup conversion --- .../XlsFile/Format/Logic/Biff_records/Setup.h | 2 +- .../Format/Logic/Biff_unions/PAGESETUP.cpp | 52 ++++++---- .../Format/Logic/Biff_unions/PAGESETUP.h | 5 + OOXML/XlsxFormat/Worksheets/Worksheet.cpp | 10 ++ .../Worksheets/WorksheetChildOther.cpp | 96 +++++++++++++++++++ .../Worksheets/WorksheetChildOther.h | 2 + .../XlsxFormat/Worksheets/XlsxHyperlinks.cpp | 2 +- 7 files changed, 146 insertions(+), 23 deletions(-) diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.h b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.h index 9f50d033c1..6a019c520a 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.h +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_records/Setup.h @@ -60,7 +60,7 @@ public: bool fLeftToRight = false; bool fPortrait = true; - bool fNoPls = false; + bool fNoPls = true; bool fNoColor = false; bool fDraft = false; bool fNotes = false; diff --git a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp index 7828353afe..89256f1b27 100644 --- a/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp +++ b/MsBinaryFile/XlsFile/Format/Logic/Biff_unions/PAGESETUP.cpp @@ -170,27 +170,37 @@ namespace XLS const bool PAGESETUP::saveContent(BinProcessor& proc) { - if(m_Header != nullptr) - proc.mandatory(*m_Header); - else - proc.mandatory
(); - if(m_Footer != nullptr) - proc.mandatory(*m_Footer); - else - proc.mandatory