Files
DocumentServer-v-9.2.0/core/OOXML/XlsbFormat/WorkBookStream.cpp
Yajbir Singh f1b860b25c
Some checks failed
check / markdownlint (push) Has been cancelled
check / spellchecker (push) Has been cancelled
updated
2025-12-11 19:03:17 +05:30

618 lines
18 KiB
C++

/*
* (c) Copyright Ascensio System SIA 2010-2023
*
* This program is a free software product. You can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License (AGPL)
* version 3 as published by the Free Software Foundation. In accordance with
* Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect
* that Ascensio System SIA expressly excludes the warranty of non-infringement
* of any third-party rights.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For
* details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html
*
* You can contact Ascensio System SIA at 20A-6 Ernesta Birznieka-Upish
* street, Riga, Latvia, EU, LV-1050.
*
* The interactive user interfaces in modified source and object code versions
* of the Program must display Appropriate Legal Notices, as required under
* Section 5 of the GNU AGPL version 3.
*
* Pursuant to Section 7(b) of the License you must retain the original Product
* logo when distributing the program. Pursuant to Section 7(e) we decline to
* grant you any rights under trademark law for use of our trademarks.
*
* All the Product's GUI elements, including illustrations and icon sets, as
* well as technical writing content are licensed under the terms of the
* Creative Commons Attribution-ShareAlike 4.0 International. See the License
* terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
*
*/
#include "WorkBookStream.h"
#include "Biff12_records/CommonRecords.h"
#include "Biff12_records/BeginBook.h"
#include "Biff12_records/FileVersion.h"
#include "Biff12_records/FileSharingIso.h"
#include "Biff12_records/WbProp.h"
#include "Biff12_unions/ACABSPATH.h"
#include "Biff12_unions/BOOKVIEWS.h"
#include "Biff12_unions/BUNDLESHS.h"
#include "Biff12_unions/FNGROUP.h"
#include "Biff12_unions/EXTERNALS.h"
#include "Biff12_records/CalcProp.h"
#include "Biff12_unions/PIVOTCACHEIDS.h"
#include "Biff12_records/OleSize.h"
#include "Biff12_records/EndBook.h"
#include "Biff12_records/BookProtection.h"
#include "Biff12_records/BookProtectionIso.h"
#include "Biff12_records/SupBookSrc.h"
#include "Biff12_unions/SUP.h"
#include "Biff12_unions/FRT.h"
#include "Biff12_unions/FRTWORKBOOK.h"
using namespace XLS;
namespace XLSB
{
WorkBookStream::WorkBookStream()
{
}
WorkBookStream::~WorkBookStream()
{
}
BaseObjectPtr WorkBookStream::clone()
{
return BaseObjectPtr(new WorkBookStream(*this));
}
const bool WorkBookStream::loadContent(BinProcessor& proc)
{
int count = 0;
while (true)
{
CFRecordType::TypeId type = proc.getNextRecordType();
if (type == rt_NONE) break;
switch(type)
{
case rt_BeginBook:
{
if (proc.optional<BeginBook>())
{
m_bBeginBook = true;
elements_.pop_back();
}
else
m_bBeginBook = false;
}break;
case rt_FileVersion:
{
if (proc.optional<FileVersion>())
{
m_BrtFileVersion = elements_.back();
elements_.pop_back();
}
}break;
case rt_FileSharingIso:
{
if (proc.optional<FileSharingIso>())
{
m_BrtFileSharingIso = elements_.back();
elements_.pop_back();
}
}break;
case rt_FileSharing:
{
if (proc.optional<FileSharing>())
{
m_BrtFileSharing = elements_.back();
elements_.pop_back();
}
}break;
case rt_WbProp:
{
if (proc.optional<WbProp>())
{
m_BrtWbProp = elements_.back();
elements_.pop_back();
}
}break;
case rt_BookProtectionIso:
{
if (proc.optional<BookProtectionIso>())
{
m_BrtBookProtectionIso = elements_.back();
elements_.pop_back();
}
}break;
case rt_BookProtection:
{
if (proc.optional<BookProtection>())
{
m_BrtBookProtection = elements_.back();
elements_.pop_back();
}
}break;
case rt_ACBegin:
{
if (proc.optional<ACABSPATH>())
{
m_ACABSPATH = elements_.back();
elements_.pop_back();
}
}break;
case rt_BeginBookViews:
{
if (proc.optional<BOOKVIEWS>())
{
m_BOOKVIEWS = elements_.back();
elements_.pop_back();
}
}break;
case rt_BeginBundleShs:
{
if (proc.optional<BUNDLESHS>())
{
m_BUNDLESHS = elements_.back();
elements_.pop_back();
}
}break;
case rt_BeginFnGroup:
{
if (proc.optional<FNGROUP>())
{
m_FNGROUP = elements_.back();
elements_.pop_back();
}
}break;
case rt_BeginExternals:
{
if (proc.optional<EXTERNALS>())
{
m_EXTERNALS = elements_.back();
elements_.pop_back();
}
}break;
case rt_Name:
{
count = proc.repeated<Name>(0, 0);
int start_pos = m_arBrtName.size();
while(count > 0)
{
m_arBrtName.insert(m_arBrtName.begin() + start_pos, elements_.back());
elements_.pop_back();
count--;
}
}break;
case rt_CalcProp:
{
if (proc.optional<CalcProp>())
{
m_BrtCalcProp = elements_.back();
elements_.pop_back();
}
}break;
case rt_OleSize:
{
if (proc.optional<OleSize>())
{
m_BrtOleSize = elements_.back();
elements_.pop_back();
}
}break;
case rt_BeginPivotCacheIDs:
{
if (proc.optional<PIVOTCACHEIDS>())
{
m_PIVOTCACHEIDS = elements_.back();
elements_.pop_back();
}
}break;
case rt_UserBookView:
{
while (true)
{
if(proc.optional<UserBookView>())
{
m_arBrtUserBookView.push_back(elements_.back());
elements_.pop_back();
while (proc.optional<FRT>())
{
//m_arFRT.push_back(elements_.back());
elements_.pop_back();
}
}
else break;
}
}break;
case rt_WebOpt:
{
if (proc.optional<WebOpt>())
{
m_BrtWebOpt = elements_.back();
elements_.pop_back();
}
}break;
case rt_FileRecover:
{
count = proc.repeated<FileRecover>(0, 0);
while(count > 0)
{
m_arBrtFileRecover.insert(m_arBrtFileRecover.begin(), elements_.back());
elements_.pop_back();
count--;
}
}break;
case rt_FRTBegin:
{
FRTWORKBOOK oFRTWORKBOOK;
if (proc.optional(oFRTWORKBOOK))
{
if(m_FRTWORKBOOK != nullptr)
{
if(oFRTWORKBOOK.m_SLICERCACHEIDS != nullptr)
boost::dynamic_pointer_cast<FRTWORKBOOK>(m_FRTWORKBOOK)->m_SLICERCACHEIDS = oFRTWORKBOOK.m_SLICERCACHEIDS;
if(oFRTWORKBOOK.m_SLICERCACHESPIVOTCACHEIDS != nullptr)
boost::dynamic_pointer_cast<FRTWORKBOOK>(m_FRTWORKBOOK)->m_SLICERCACHESPIVOTCACHEIDS = oFRTWORKBOOK.m_SLICERCACHESPIVOTCACHEIDS;
if(oFRTWORKBOOK.m_TABLESLICERCACHEIDS != nullptr)
boost::dynamic_pointer_cast<FRTWORKBOOK>(m_FRTWORKBOOK)->m_TABLESLICERCACHEIDS = oFRTWORKBOOK.m_TABLESLICERCACHEIDS;
elements_.pop_back();
}
else
{
m_FRTWORKBOOK = elements_.back();
elements_.pop_back();
}
}
}break;
case rt_EndBook:
{
if (proc.optional<EndBook>())
{
m_bEndBook = true;
elements_.pop_back();
}
else
m_bEndBook = false;
}break;
default://skip
{
proc.SkipRecord();
}break;
}
}
return true;
}
const bool WorkBookStream::saveContent(XLS::BinProcessor & proc)
{
proc.mandatory<BeginBook>();
if (m_BrtFileVersion != nullptr)
proc.mandatory(*m_BrtFileVersion);
if (m_BrtFileSharingIso != nullptr)
proc.mandatory(*m_BrtFileSharingIso);
if (m_BrtFileSharing != nullptr)
proc.mandatory(*m_BrtFileSharing);
if (m_BrtWbProp != nullptr)
proc.mandatory(*m_BrtWbProp);
if (m_BrtBookProtectionIso != nullptr)
proc.mandatory(*m_BrtBookProtectionIso);
if (m_BrtBookProtection != nullptr)
proc.mandatory(*m_BrtBookProtection);
if (m_ACABSPATH != nullptr)
proc.mandatory(*m_ACABSPATH);
if (m_BOOKVIEWS != nullptr)
proc.mandatory(*m_BOOKVIEWS);
if (m_BUNDLESHS != nullptr)
proc.mandatory(*m_BUNDLESHS);
if (m_FNGROUP != nullptr)
proc.mandatory(*m_FNGROUP);
if (m_EXTERNALS != nullptr)
proc.mandatory(*m_EXTERNALS);
for(auto &item: m_arBrtName)
{
proc.mandatory(*item);
}
if (m_BrtCalcProp != nullptr)
proc.mandatory(*m_BrtCalcProp);
if (m_BrtOleSize != nullptr)
proc.mandatory(*m_BrtOleSize);
if (m_PIVOTCACHEIDS != nullptr)
proc.mandatory(*m_PIVOTCACHEIDS);
for (auto &item : m_arBrtUserBookView)
{
proc.mandatory(*item);
}
if (m_BrtWebOpt != nullptr)
proc.mandatory(*m_BrtWebOpt);
for (auto &item : m_arBrtFileRecover)
{
proc.mandatory(*item);
}
if (m_FRTWORKBOOK != nullptr)
proc.mandatory(*m_FRTWORKBOOK);
proc.mandatory<EndBook>();
return true;
}
void WorkBookStream::UpdateXtiWrite(XLS::GlobalWorkbookInfo* global_info_)
{
EXTERNALS* externals = dynamic_cast<EXTERNALS*>(m_EXTERNALS.get());
if (externals && !externals->m_arSUP.empty())
{
if(externals->m_BrtExternSheet == nullptr)
externals->m_BrtExternSheet = XLS::BaseObjectPtr(new XLSB::ExternSheet());
XLSB::ExternSheet* extern_sheet = dynamic_cast<XLSB::ExternSheet*>(externals->m_BrtExternSheet.get());
for (size_t i = 0; extern_sheet && i < externals->m_arSUP.size(); i++)
{
SUP* index_book = dynamic_cast<SUP*>(externals->m_arSUP[i].get());
if (!index_book) continue;
if (index_book->m_source->get_type() == XLS::typeSupSelf)
{
XTIPtr xti(new XTI);
xti->iSupBook = i;
xti->itabFirst = 0;
xti->itabLast = 0;
extern_sheet->rgXTI.push_back(xti);
}
}
for (size_t i = 0; extern_sheet && i < extern_sheet->rgXTI.size(); i++)
{
XTI* xti = dynamic_cast<XTI*>(extern_sheet->rgXTI[i].get());
if (!xti) continue;
SUP* index_book = dynamic_cast<SUP*>(externals->m_arSUP[xti->iSupBook].get());
if (!index_book) continue;
//if (index_book->arNames.empty()) continue;
GlobalWorkbookInfo::_xti val_1;
val_1.iSup = xti->iSupBook;
val_1.pNames = &index_book->arNames;
if (index_book->m_source->get_type() == XLS::typeSupBookSrc)
{
val_1.link = dynamic_cast<XLSB::SupBookSrc*>(index_book->m_source.get())->strRelID.value.value();
val_1.itabFirst = xti->itabFirst;
val_1.itabLast = xti->itabLast;
}
else if (xti->itabFirst >= 0 /*|| itabLast >= 0*/)
{
std::wstring strRange;
if (-1 == xti->itabFirst)
{
strRange = L"#REF";
}
else if (xti->itabFirst < global_info_->sheets_info.size())
{
strRange = XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabFirst].name, L"");
if (xti->itabFirst != xti->itabLast)
{
strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabLast].name, L"");
}
}
val_1.link = strRange;
}
else if (xti->itabFirst == -1)
{
//sheet not found
}
else if (xti->itabFirst == -2)
{
//Workbook-level
}
global_info_->arXti_External.push_back(val_1);
GlobalWorkbookInfo::arXti_External_static.push_back(val_1);
}
//global_info_->arXti.push_back(val);
//}
}
}
void WorkBookStream::UpdateXti(XLS::GlobalWorkbookInfo* global_info_)
{
EXTERNALS* externals = dynamic_cast<EXTERNALS*>(m_EXTERNALS.get());
if (externals)
{
//for (size_t s = 0; s < externals->m_arSUP.size(); s++)
//{
// SUP* SUPP = dynamic_cast<SUP*>(externals->m_arSUP[s].get());
// if (!SUPP) continue;
XLSB::ExternSheet* extern_sheet = dynamic_cast<XLSB::ExternSheet*>(externals->m_BrtExternSheet.get());
//GlobalWorkbookInfo::_xti val;
//val.iSup = s;
//val.pNames = &SUPP->arNames;
for (size_t i = 0; extern_sheet && i < extern_sheet->rgXTI.size(); i++)
{
XTI* xti = dynamic_cast<XTI*>(extern_sheet->rgXTI[i].get());
if (!xti) continue;
if(externals->m_arSUP.size() <= xti->iSupBook) continue;
SUP* index_book = dynamic_cast<SUP*>(externals->m_arSUP[xti->iSupBook].get());
if (!index_book) continue;
//if (index_book->arNames.empty()) continue;
GlobalWorkbookInfo::_xti val_1;
val_1.iSup = xti->iSupBook;
auto namesVector = new std::vector<std::wstring>();
*namesVector = index_book->arNames;
val_1.pNames = namesVector;
if(index_book->m_source->get_type() == XLS::typeSupBookSrc)
{
val_1.link = dynamic_cast<XLSB::SupBookSrc*>(index_book->m_source.get())->strRelID.value.value();
val_1.itabFirst = xti->itabFirst;
val_1.itabLast = xti->itabLast;
}
else if (xti->itabFirst >= 0 /*|| itabLast >= 0*/)
{
std::wstring strRange;
if(-1 == xti->itabFirst)
{
strRange = L"#REF";
}
else if (xti->itabFirst < global_info_->sheets_info.size())
{
strRange = XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabFirst].name, L"");
if (xti->itabFirst != xti->itabLast && xti->itabLast < global_info_->sheets_info.size())
{
strRange += std::wstring(L":") + XMLSTUFF::name2sheet_name(global_info_->sheets_info[xti->itabLast].name, L"");
}
}
val_1.link = strRange;
}
else if (xti->itabFirst == -1)
{
//sheet not found
}
else if (xti->itabFirst == -2)
{
//Workbook-level
}
global_info_->arXti_External.push_back(val_1);
}
//global_info_->arXti.push_back(val);
//}
}
}
void WorkBookStream::UpdateDefineNames(XLS::GlobalWorkbookInfo* global_info_)
{
for (size_t s = 0; s < m_arBrtName.size(); s++)
{
//LBL* LBL_ = dynamic_cast<LBL*>(m_arBrtName[s].get());
//if (!LBL_) continue;
Name *lbl = dynamic_cast<Name*>(m_arBrtName[s].get());
if (!lbl) continue;
std::wstring name;
std::wstring comment;
//if (lbl->fBuiltin)
name = lbl->name.value();
//if (name.empty()) name = lbl->Name_bin.value();
//NameCmt *namecmt = dynamic_cast<NameCmt*>(LBL_->m_NameCmt.get());
//if (namecmt)
// {
// if (name.empty())
//name = namecmt->name.value();
comment = lbl->comment.value();
//}
std::wstring value = lbl->rgce.getAssembledFormula(lbl->fWorkbookParam/*lbl->itab == 0 ? true : false*/);
if (!value.empty() && !name.empty() && lbl->itab != 0xFFFFFFFF)
{
int ind_sheet = lbl->itab;
std::map<std::wstring, std::vector<std::wstring>>::iterator it = global_info_->mapDefineNames.find(name);
if (it != global_info_->mapDefineNames.end())
{
while ( it->second.size() <= ind_sheet)
{
it->second.push_back(L"");
}
it->second[ind_sheet] = value;
//it->second.push_back(value);
}
else
{
std::vector<std::wstring> ar(ind_sheet + 1);
ar[ind_sheet] = value;
//ar.push_back(value);
global_info_->mapDefineNames.insert(std::make_pair(name, ar));
}
//LBL_->isSerialize = true;
}
else
{
if (lbl->fFunc)
{
if (name != L"CHISQDIST" &&
name != L"CHISQINV" &&
name != L"CURRENT" &&
name != L"EFFECTIVE" &&
name.substr(0, 6) != L"_xlfn.")
name = L"_xludf." + name;
}
}
global_info_->arDefineNames.push_back(name);// для имен функций - todooo ... не все функции корректны !! БДИ !!
}
}
} // namespace XLSB