This commit is contained in:
csh 2023-02-21 17:26:44 +08:00
parent b9955b3b05
commit 80783ee8a4
8 changed files with 239 additions and 5 deletions

View File

@ -759,5 +759,20 @@ style.Protection.Lock := 1;
),
'Demo': '',
),
('ObjName': 'TCalcPr',
'Desc': ('TCalcPr有以下属性: '),
'AttrInfo': (
('attrName': 'CalcMode', 'type': 'string', 'desc': '工作簿计算模式', 'value': array('nil(默认): 自动重算', '"autoNoTable": 除模拟运算表外自动重算', '"manual": 手动重算')),
('attrName': 'RefMode', 'type': 'string', 'desc': 'R1C1引用样式', 'value': array('nil(默认): 不启用', '"R1C1": 启用R1C1引用样式')),
('attrName': 'Iterate', 'type': 'bool', 'desc': '是否启用迭代计算', 'value': array()),
('attrName': 'IterateCount', 'type': 'int', 'desc': '最多迭代次数', 'value': array()),
('attrName': 'IterateDelta', 'type': 'double', 'desc': '最大误差需要使用科学计数法如0.002时为2E-3', 'value': array()),
('attrName': 'CalcOnSave', 'type': 'bool', 'desc': '保存工作簿之前重新计算,{CalcMode}为"manual"时有效', 'value': array()),
('attrName': 'ConCurrentCalc', 'type': 'bool', 'desc': '是否启用多线程计算', 'value': array()),
('attrName': 'ConCurrentManualCount', 'type': 'int', 'desc': '自定义计算线程数', 'value': array()),
('attrName': 'FullPrecision', 'type': 'bool', 'desc': '是否采用完整精度', 'value': array()),
),
'Demo': '',
),
);
End

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
// Version 1.1.6
// Version 1.1.7
Function TOfficeObj(n);
Begin
@ -309,6 +309,8 @@ Begin
return new TBreak();
"tprotect":
return new TProtect();
"tcalcpr":
return new TCalcPr();
End;
End;
@ -9461,6 +9463,58 @@ type TProtect=class(NodeInfo)
//Nodes
End;
///////////////////////////////////////////////////////////////
/// TCalcPr
///////////////////////////////////////////////////////////////
type TCalcPr=class(NodeInfo)
Function Create(); overload;
Begin
Create(nil, 'calcPr');
End;
Function Create(p, name); overload;
Begin
Class(NodeInfo).Create(p, name);
Init();
End;
Function Init();
Begin
//TODO...
End;
Function InitRootNode(node);
Begin
RootObj := node;
End;
Function GetAttrs(); override;
Begin
HandleAttrs();
return array(("CalCId", "calcId", CalCId, ""),("CalcMode", "calcMode", CalcMode, ""),("RefMode", "refMode", RefMode, ""),("Iterate", "iterate", Iterate, ""),("IterateCount", "iterateCount", IterateCount, ""),("IterateDelta", "iterateDelta", IterateDelta, ""),("CalcOnSave", "calcOnSave", CalcOnSave, ""),("FullPrecision", "fullPrecision", FullPrecision, ""),("ConCurrentCalc", "conCurrentCalc", ConCurrentCalc, ""),("ConCurrentManualCount", "conCurrentManualCount", ConCurrentManualCount, "")) union ExtAttr;
End;
Function GetChildren(); override;
Begin
HandleChildren();
return ExtNodes;
End;
//Attributes
CalCId;
CalcMode;
RefMode;
Iterate;
IterateCount;
IterateDelta;
CalcOnSave;
FullPrecision;
ConCurrentCalc;
ConCurrentManualCount;
//Nodes
End;
///////////////////////////////////////////////////////////////////////////////////////////
///DOCX文档实现
@ -14302,3 +14356,4 @@ private
End

View File

@ -1,4 +1,4 @@
// Version 1.1.6
// Version 1.1.7
Type TSDocxFile = Class
///Version: V1.0 2022-09-20
@ -73,6 +73,25 @@ Type TSDocxFile = Class
return zipfile_.Save(alias, fname);
End;
///另存为二进制流数据
///返回: [err, fileContent] fileContent 文件内容为Binary数据类型
Function SaveToMem();
Begin
return zipfile_.Save2Mem();
End;
///打开二进制内容
///data: 二进制数据
///返回: [err, errmsg]
Function LoadFromMem(data);
Begin
[err, errmsg] := zipfile_.LoadFromMem(data);
if err=0 then Begin
document_ := new docxDocument(zipfile_);
End;
return array(err, errmsg);
End;
///真实文件名
///返回string
Function FileName();

View File

@ -1,4 +1,4 @@
// Version 1.1.6
// Version 1.1.7
Type TSExcelFile = Class
///Version: V1.0 2022-08-08
@ -69,6 +69,27 @@ Type TSExcelFile = Class
return zipfile_.Save();
End;
///打开二进制内容
///data: 二进制数据
///返回: [err, errmsg]
Function LoadFromMem(data);
Begin
[err, errmsg] := zipfile_.LoadFromMem(data);
if err = 0 then
begin
workbook_ := new xlsxWorkBook(zipfile_);
workbook_.Load();
end
return array(err, errmsg);
End;
///保存为二进制内容
///返回: [err, fileContent] fileContent二进制文件内容
Function SaveToMem();
Begin
return zipfile_.Save2Mem();
End;
///另存为
///alias: string文件目录别名
///fname: string文件名
@ -115,11 +136,19 @@ Type TSExcelFile = Class
///创建新sheet
///sheet: string工作表名称
Function NewSheet(sheet);
Function NewSheet(sheet);overload;
Begin
return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sheet));
End;
///在指定sheet之前插入新sheet
///sourceSheet: string指定工作表名称
///destSheet: string目的工作表名称
Function NewSheet(sourceSheet, destSheet);overload;
Begin
return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet));
End;
///删除sheet
///sheet: string工作表名称
Function DeleteSheet(sheet);
@ -848,6 +877,13 @@ Type TSExcelFile = Class
return workbook_.GetDefaultFont();
End;
///设置工作簿计算选项
///calcPr: TCalcPr对象
Function SetCalcOptions(calcPr);
Begin
return workbook_.SetCalcOptions(calcPr);
End;
Function WorkBook();
Begin
return workbook_;

View File

@ -139,7 +139,7 @@ Type xlsxWorkBook = Class
///创建新sheet
///sheet: string工作表名称
Function NewSheet(sheet);
Function NewSheet(sheet);overload;
Begin
lname := LowerCase(sheet);
if ifint(sheetIndexMap_[ lname ]) then return 'The sheet already exists.';
@ -201,6 +201,86 @@ Type xlsxWorkBook = Class
SetDefaultSheet(sheet);
End;
Function NewSheet(sourceSheet, destSheet);overload;
Begin
lname := LowerCase(destSheet);
if ifint(sheetIndexMap_[ lname ]) then return 'destSheet already exists.';
sname := LowerCase(sourceSheet);
if not ifint(sheetIndexMap_[ sname ]) then return 'sourceSheet does not exists';
//添加文件xl/worksheets/sheetN.xml
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
sheetId := integer(sheetId) + 1;
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
//设置 workbook.xml.rels
rid := getWorkbookRelsRid();
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
rels := workbook_rels.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship');
rels.SetAttribute('Target', getTarget( sheetsCount_ + 1));
rels.SetAttribute('Type', class(TSXml).GetTemplate('RelationshipWorkSheet'));
rels.SetAttribute('Id', rid);
//workbook_rels.Print;
//设置 xl/workbook.xml
workbook := GetXmlFileObj('xl/workbook.xml');
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets');
sheet_node := node.FirstChildElement('sheet');
while ifObj(sheet_node) do
begin
if sheet_node.GetAttribute('name') = sourceSheet then
begin
sheet_node := node.InsertAfterChild(sheet_node, 'element', 'sheet');
sheet_node.SetAttribute('name', destSheet);
sheet_node.SetAttribute('sheetId', sheetId);
sheet_node.SetAttribute('r:id', rid);
break;
end
sheet_node := sheet_node.NextElement();
end
//workbook.Print();
//设置docProps/app.xml
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
//app.Print();
node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts');
vector := node.FirstChildElement('vt:vector');
vector.SetAttribute('size', length(sheetNames_) + 1);
lpstr := vector.FirstChildElement('vt:lpstr');
while ifObj(lpstr) do
begin
if LowerCase(lpstr.GetText()) = LowerCase(sourceSheet) then
begin
lpstr := vector.InsertAfterChild(lpstr, 'element', 'vt:lpstr');
lpstr.SetValue(destSheet);
break;
end
lpstr := lpstr.NextElement();
end
//设置[Content_Types].xml
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddOverrideContentType(content_xml, '/' + fname, class(TSXml).GetTemplate('sheetContentType'));
ind := sheetIndexMap_[sname];
for i:=sheetsCount_ downto ind+2 do
begin
sheetNames_[i]['name'] := sheetNames_[i-1]['name'];
sheetNames_[i]['sheetId'] := sheetNames_[i-1]['sheetId'];
sheetNames_[i]['rid'] := sheetNames_[i-1]['rid'];
sheetNames_[i]['file'] := sheetNames_[i-1]['file'];
sheetIndexMap_[ LowerCase(sheetNames_[i]['name']) ] := i;
end
sheetIndexMap_[lname] := ind + 1;
sheetNames_[ind+1]['name'] := destSheet;
sheetNames_[ind+1]['sheetId'] := sheetId;
sheetNames_[ind+1]['rid'] := rid;
sheetNames_[ind+1]['file'] := fname;
sheetsCount_ ++;
SetDefaultSheet(destSheet);
End;
Function DeleteSheet(sheet);
Begin
if sheetsCount_ <= 1 then return 'Cant not delete the last sheet.';
@ -299,6 +379,9 @@ Type xlsxWorkBook = Class
del_partname := '/' + sheetPrefix_ + inttostr(sheetsCount_ + 1) + '.xml';
DeleteContentType(del_partname);
//删除calcChain.xml
zipfile_.Remove('xl/calcChain.xml');
xmlFileObjMap_ := array();
//设置默认工作表
@ -1143,6 +1226,17 @@ Type xlsxWorkBook = Class
return tfont;
End;
Function SetCalcOptions(calcPr);
Begin
workbook_xml := GetXmlFileObj('xl/workbook.xml');
workbook_node := workbook_xml.FirstChildElement('workbook');
calc_node := workbook_node.FirstChildElement('calcPr');
sheet_node := workbook_node.FirstChildElement('sheets');
if ifObj(calc_node) then workbook_node.DeleteChild(calc_node);
calcPr.calcId := "191029";
workbook_node.InsertAfterChild(sheet_node, calcPr.Marshal());
End
private
Function generateRow(c1, c2, r);
Begin

View File

@ -1,5 +1,20 @@
# 更新日志
## 2023-2-21
### V1.1.7
#### word
1. 新增`LoadFromMem`, `SavaToMem`
#### excel
1. 新增`LoadFromMem`, `SavaToMem`
2. 新增重载方法`NewSheet`
3. 新增`SetCalcOptions`
4. 修复删除sheet报错问题
## 2023-2-13
### V1.1.6