v1.1.7
This commit is contained in:
parent
b9955b3b05
commit
80783ee8a4
|
|
@ -759,5 +759,20 @@ style.Protection.Lock := 1;
|
||||||
),
|
),
|
||||||
'Demo': '',
|
'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
|
End
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
||||||
// Version 1.1.6
|
// Version 1.1.7
|
||||||
|
|
||||||
Function TOfficeObj(n);
|
Function TOfficeObj(n);
|
||||||
Begin
|
Begin
|
||||||
|
|
@ -309,6 +309,8 @@ Begin
|
||||||
return new TBreak();
|
return new TBreak();
|
||||||
"tprotect":
|
"tprotect":
|
||||||
return new TProtect();
|
return new TProtect();
|
||||||
|
"tcalcpr":
|
||||||
|
return new TCalcPr();
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
|
@ -9461,6 +9463,58 @@ type TProtect=class(NodeInfo)
|
||||||
//Nodes
|
//Nodes
|
||||||
End;
|
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文档实现
|
///DOCX文档实现
|
||||||
|
|
||||||
|
|
@ -14302,3 +14356,4 @@ private
|
||||||
|
|
||||||
End
|
End
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Version 1.1.6
|
// Version 1.1.7
|
||||||
|
|
||||||
Type TSDocxFile = Class
|
Type TSDocxFile = Class
|
||||||
///Version: V1.0 2022-09-20
|
///Version: V1.0 2022-09-20
|
||||||
|
|
@ -73,6 +73,25 @@ Type TSDocxFile = Class
|
||||||
return zipfile_.Save(alias, fname);
|
return zipfile_.Save(alias, fname);
|
||||||
End;
|
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
|
///返回:string
|
||||||
Function FileName();
|
Function FileName();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Version 1.1.6
|
// Version 1.1.7
|
||||||
|
|
||||||
Type TSExcelFile = Class
|
Type TSExcelFile = Class
|
||||||
///Version: V1.0 2022-08-08
|
///Version: V1.0 2022-08-08
|
||||||
|
|
@ -69,6 +69,27 @@ Type TSExcelFile = Class
|
||||||
return zipfile_.Save();
|
return zipfile_.Save();
|
||||||
End;
|
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,文件目录别名
|
///alias: string,文件目录别名
|
||||||
///fname: string,文件名
|
///fname: string,文件名
|
||||||
|
|
@ -115,11 +136,19 @@ Type TSExcelFile = Class
|
||||||
|
|
||||||
///创建新sheet
|
///创建新sheet
|
||||||
///sheet: string,工作表名称
|
///sheet: string,工作表名称
|
||||||
Function NewSheet(sheet);
|
Function NewSheet(sheet);overload;
|
||||||
Begin
|
Begin
|
||||||
return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sheet));
|
return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sheet));
|
||||||
End;
|
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
|
||||||
///sheet: string,工作表名称
|
///sheet: string,工作表名称
|
||||||
Function DeleteSheet(sheet);
|
Function DeleteSheet(sheet);
|
||||||
|
|
@ -848,6 +877,13 @@ Type TSExcelFile = Class
|
||||||
return workbook_.GetDefaultFont();
|
return workbook_.GetDefaultFont();
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///设置工作簿计算选项
|
||||||
|
///calcPr: TCalcPr对象
|
||||||
|
Function SetCalcOptions(calcPr);
|
||||||
|
Begin
|
||||||
|
return workbook_.SetCalcOptions(calcPr);
|
||||||
|
End;
|
||||||
|
|
||||||
Function WorkBook();
|
Function WorkBook();
|
||||||
Begin
|
Begin
|
||||||
return workbook_;
|
return workbook_;
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ Type xlsxWorkBook = Class
|
||||||
|
|
||||||
///创建新sheet
|
///创建新sheet
|
||||||
///sheet: string,工作表名称
|
///sheet: string,工作表名称
|
||||||
Function NewSheet(sheet);
|
Function NewSheet(sheet);overload;
|
||||||
Begin
|
Begin
|
||||||
lname := LowerCase(sheet);
|
lname := LowerCase(sheet);
|
||||||
if ifint(sheetIndexMap_[ lname ]) then return 'The sheet already exists.';
|
if ifint(sheetIndexMap_[ lname ]) then return 'The sheet already exists.';
|
||||||
|
|
@ -201,6 +201,86 @@ Type xlsxWorkBook = Class
|
||||||
SetDefaultSheet(sheet);
|
SetDefaultSheet(sheet);
|
||||||
End;
|
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);
|
Function DeleteSheet(sheet);
|
||||||
Begin
|
Begin
|
||||||
if sheetsCount_ <= 1 then return 'Cant not delete the last sheet.';
|
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';
|
del_partname := '/' + sheetPrefix_ + inttostr(sheetsCount_ + 1) + '.xml';
|
||||||
DeleteContentType(del_partname);
|
DeleteContentType(del_partname);
|
||||||
|
|
||||||
|
//删除calcChain.xml
|
||||||
|
zipfile_.Remove('xl/calcChain.xml');
|
||||||
|
|
||||||
xmlFileObjMap_ := array();
|
xmlFileObjMap_ := array();
|
||||||
|
|
||||||
//设置默认工作表
|
//设置默认工作表
|
||||||
|
|
@ -1143,6 +1226,17 @@ Type xlsxWorkBook = Class
|
||||||
return tfont;
|
return tfont;
|
||||||
End;
|
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
|
private
|
||||||
Function generateRow(c1, c2, r);
|
Function generateRow(c1, c2, r);
|
||||||
Begin
|
Begin
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue