Compare commits
92
Commits
8f6bdd212b
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
19b8614c93 | ||
|
|
3df8ce2be0 | ||
|
|
6b0f11cebb | ||
|
|
bbe0821f68 | ||
|
|
ea528f3094 | ||
|
|
95a00e7002 | ||
|
|
2b62e4e1a5 | ||
|
|
a2c3905cd0 | ||
|
|
ca03e53285 | ||
|
|
d57631a19a | ||
|
|
c05b646104 | ||
|
|
39b7549665 | ||
|
|
93533c41a0 | ||
|
|
0f07603d73 | ||
|
|
3c16ce510a | ||
|
|
3243db0e2d | ||
|
|
fdd2bd0fef | ||
|
|
2d423ca1fb | ||
|
|
0e35cc0463 | ||
|
|
c7b7971d9a | ||
|
|
066a8f6562 | ||
|
|
9e04cc2cff | ||
|
|
bb8d3591ac | ||
|
|
037cb41560 | ||
|
|
5469ca318d | ||
|
|
c3432d1812 | ||
|
|
53d83f91ae | ||
|
|
893a3a928b | ||
|
|
72554969bb | ||
|
|
fa8800e20d | ||
|
|
92257c380f | ||
|
|
fb22cf9b0a | ||
|
|
a3df0d5df9 | ||
|
|
b4ef4a531c | ||
|
|
f499526f04 | ||
|
|
c1a93bb16e | ||
|
|
03e101fa46 | ||
|
|
1231868aa7 | ||
|
|
6d6281229c | ||
|
|
522e52ed46 | ||
|
|
a774f57335 | ||
|
|
800f91870d | ||
|
|
e5d011e59b | ||
|
|
d588ac67d4 | ||
|
|
dc7d48c318 | ||
|
|
fcb2a8e7b3 | ||
|
|
91f3c5af49 | ||
|
|
c16566d2f1 | ||
|
|
3607dab833 | ||
|
|
15e2cbe661 | ||
|
|
9f660c09f6 | ||
|
|
1e9b8f3a12 | ||
|
|
b617f235fa | ||
|
|
ee7b7164ce | ||
|
|
aab0a498c6 | ||
|
|
5172a78e3e | ||
|
|
de0af521bc | ||
|
|
8cd87118d5 | ||
|
|
9c917cfb70 | ||
|
|
d72d88d68a | ||
|
|
5f1064794d | ||
|
|
493691b930 | ||
|
|
f3094c148c | ||
|
|
addc41144e | ||
|
|
8aa050461c | ||
|
|
3643be6231 | ||
|
|
e2e68efc30 | ||
|
|
ef0dcde062 | ||
|
|
ba5f255573 | ||
|
|
79ba3254a0 | ||
|
|
81b806c93c | ||
|
|
60847b0636 | ||
|
|
819efc1ee1 | ||
|
|
9037124c01 | ||
|
|
b59c869ae2 | ||
|
|
8d63ecd7b3 | ||
|
|
f781cd0c0a | ||
|
|
522142b712 | ||
|
|
6eec96d84d | ||
|
|
1abc2028fe | ||
|
|
1d0b5684cc | ||
|
|
0c73a4c0d1 | ||
|
|
ced0d6b04c | ||
|
|
880e03c41a | ||
|
|
2384ca42b5 | ||
|
|
845c6bb554 | ||
|
|
f34d03a50f | ||
|
|
ff6d23090e | ||
|
|
f46240850e | ||
|
|
ce331f4417 | ||
|
|
c706d2d8d0 | ||
|
|
0e21645b2a |
@@ -0,0 +1,4 @@
|
|||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*.cmd
|
||||||
|
script.ps1
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "funcext/TSOffice/Extensions/OfficeVba"]
|
||||||
|
path = funcext/TSOffice/Extensions/OfficeVba
|
||||||
|
url = https://git.mytsl.cn/tinysoft/OfficeVba.git
|
||||||
@@ -69,9 +69,11 @@ _Annotation(docx);
|
|||||||
_Faq(docx);
|
_Faq(docx);
|
||||||
|
|
||||||
///目录
|
///目录
|
||||||
docx.AddTableContent(paragraphTitle, 1, 3);
|
content := docx.AddTableContent(paragraphTitle, 1, 3);
|
||||||
|
docx.AddPageBreak(content.node_);
|
||||||
|
|
||||||
v := docx.SaveAs('', TOfficeApi().CurCodePageToGBK('DocxFile使用帮助.docx'));
|
|
||||||
|
v := docx.SaveAs('', 'DocxFile使用帮助.docx');
|
||||||
println('Test Over!\n Save {}: {},time={}秒', file, v, mtoc);
|
println('Test Over!\n Save {}: {},time={}秒', file, v, mtoc);
|
||||||
|
|
||||||
//info := GetProfilerInfo(true);
|
//info := GetProfilerInfo(true);
|
||||||
@@ -84,7 +86,7 @@ Function _0_AddTitle(docx);
|
|||||||
Begin
|
Begin
|
||||||
_PrintMsg('AddTitle');
|
_PrintMsg('AddTitle');
|
||||||
p := _AddTitle(docx, '天软DOCX文档操作接口帮助文档', 0);//添加文档标题
|
p := _AddTitle(docx, '天软DOCX文档操作接口帮助文档', 0);//添加文档标题
|
||||||
p.Font.Size := 48;
|
p.Font.Size := 24;
|
||||||
p.Apply();
|
p.Apply();
|
||||||
for i:=0 to 16 do
|
for i:=0 to 16 do
|
||||||
docx.AddLineBreak(-1);//换行符
|
docx.AddLineBreak(-1);//换行符
|
||||||
@@ -132,7 +134,7 @@ Begin
|
|||||||
preface.Font.Name := '宋体';
|
preface.Font.Name := '宋体';
|
||||||
preface.Font.Color := 'FF0000';
|
preface.Font.Color := 'FF0000';
|
||||||
preface.Font.Bold := true;
|
preface.Font.Bold := true;
|
||||||
preface.Font.Size := 32;
|
preface.Font.Size := 16;
|
||||||
p1 := docx.AddParagraph(preface, -1, nil);
|
p1 := docx.AddParagraph(preface, -1, nil);
|
||||||
|
|
||||||
println(' >>OK\n');
|
println(' >>OK\n');
|
||||||
@@ -303,7 +305,7 @@ Begin
|
|||||||
p1.Run.SetText('本文档由天软科技制作。');
|
p1.Run.SetText('本文档由天软科技制作。');
|
||||||
p1.Run.rPr.Name := '宋体';
|
p1.Run.rPr.Name := '宋体';
|
||||||
p1.Run.rPr.Bold := true;
|
p1.Run.rPr.Bold := true;
|
||||||
p1.Run.rPr.Size := 32;
|
p1.Run.rPr.Size := 16;
|
||||||
p1.Run.rPr.Color := 'FF0000';
|
p1.Run.rPr.Color := 'FF0000';
|
||||||
p2 := docx.AddParagraph(p1, -1, nil);
|
p2 := docx.AddParagraph(p1, -1, nil);
|
||||||
//插入批注
|
//插入批注
|
||||||
@@ -391,7 +393,7 @@ Begin
|
|||||||
p1.Run.SetText( '插入案例。' );
|
p1.Run.SetText( '插入案例。' );
|
||||||
p1.Run.rPr.Name := '宋体';
|
p1.Run.rPr.Name := '宋体';
|
||||||
p1.Run.rPr.Bold := true;
|
p1.Run.rPr.Bold := true;
|
||||||
p1.Run.rPr.Size := 32;
|
p1.Run.rPr.Size := 16;
|
||||||
p1.Run.rPr.Color := 'FF0000';
|
p1.Run.rPr.Color := 'FF0000';
|
||||||
pAddRevision := docx.AddParagraph(p1, -1, nil);
|
pAddRevision := docx.AddParagraph(p1, -1, nil);
|
||||||
//插入修订
|
//插入修订
|
||||||
@@ -410,7 +412,7 @@ Begin
|
|||||||
p1.Run.SetText( '删除修订案例。' );
|
p1.Run.SetText( '删除修订案例。' );
|
||||||
p1.Run.rPr.Name := '宋体';
|
p1.Run.rPr.Name := '宋体';
|
||||||
p1.Run.rPr.Bold := true;
|
p1.Run.rPr.Bold := true;
|
||||||
p1.Run.rPr.Size := 32;
|
p1.Run.rPr.Size := 16;
|
||||||
p1.Run.rPr.Color := 'FF0000';
|
p1.Run.rPr.Color := 'FF0000';
|
||||||
pDelRevision := docx.AddParagraph(p1, -1, nil);
|
pDelRevision := docx.AddParagraph(p1, -1, nil);
|
||||||
//删除修订
|
//删除修订
|
||||||
@@ -500,7 +502,7 @@ Begin
|
|||||||
help.Font.Name := '宋体';
|
help.Font.Name := '宋体';
|
||||||
help.Font.Color := 'FF0000';
|
help.Font.Color := 'FF0000';
|
||||||
help.Font.Bold := true;
|
help.Font.Bold := true;
|
||||||
help.Font.Size := 30;
|
help.Font.Size := 15;
|
||||||
p1 := docx.AddParagraph(help, -1, nil);
|
p1 := docx.AddParagraph(help, -1, nil);
|
||||||
|
|
||||||
section := docx.Sections(-1);//获取缺省章节
|
section := docx.Sections(-1);//获取缺省章节
|
||||||
@@ -514,10 +516,10 @@ Begin
|
|||||||
p.Format.SpaceAfter := 0;
|
p.Format.SpaceAfter := 0;
|
||||||
p.Font.Name := '宋体';
|
p.Font.Name := '宋体';
|
||||||
p.Font.Color := 'FF0000';
|
p.Font.Color := 'FF0000';
|
||||||
p.Font.Size := 16;
|
p.Font.Size := 8;
|
||||||
p2 := footer.AddParagraph(p, -1, nil);
|
p2 := footer.AddParagraph(p, -1, nil);
|
||||||
p.Font.Size := 18;
|
p.Font.Size := 8;
|
||||||
pgno := footer.AddPageNumber('第 {0} 页,共 {1} 页', p.Font); //添加页码
|
pgno := footer.AddPageNumber('第 {-3} 页,共 {1} 页', p.Font); //添加页码
|
||||||
pgno.Format.Alignment := 'center'; //据中对齐
|
pgno.Format.Alignment := 'center'; //据中对齐
|
||||||
pgno.Format.SpaceAfter := 0;
|
pgno.Format.SpaceAfter := 0;
|
||||||
pgno.Apply();
|
pgno.Apply();
|
||||||
@@ -530,7 +532,7 @@ Begin
|
|||||||
//p.Format.Bdr.Bottom.val := 'single';//页眉横线
|
//p.Format.Bdr.Bottom.val := 'single';//页眉横线
|
||||||
p.Font.Name := '宋体';
|
p.Font.Name := '宋体';
|
||||||
p.Font.Color := 'FF0000';
|
p.Font.Color := 'FF0000';
|
||||||
p.Font.Size := 16;
|
p.Font.Size := 8;
|
||||||
p1 := header.AddParagraph(p, -1, nil);
|
p1 := header.AddParagraph(p, -1, nil);
|
||||||
|
|
||||||
println(' >>OK\n');
|
println(' >>OK\n');
|
||||||
@@ -583,19 +585,19 @@ Begin
|
|||||||
pTest := docx.AddParagraph(p1, -1, nil);
|
pTest := docx.AddParagraph(p1, -1, nil);
|
||||||
//修改部分文字字体
|
//修改部分文字字体
|
||||||
range := pTest.Range(3,2);
|
range := pTest.Range(3,2);
|
||||||
range.Font.Size := 32;
|
range.Font.Size := 16;
|
||||||
range.Font.Color := 'FF0000';
|
range.Font.Color := 'FF0000';
|
||||||
range.Font.Bold := true;
|
range.Font.Bold := true;
|
||||||
range.Apply();
|
range.Apply();
|
||||||
//添加文字1
|
//添加文字1
|
||||||
range1 := pTest.AddText(5, '科技开发有限');
|
range1 := pTest.AddText(5, '科技开发有限');
|
||||||
range1.Font.Size := 28;
|
range1.Font.Size := 14;
|
||||||
range1.Font.Color := '00FF00';
|
range1.Font.Color := '00FF00';
|
||||||
range1.Font.Bold := true;
|
range1.Font.Bold := true;
|
||||||
range1.Apply();
|
range1.Apply();
|
||||||
//添加文字2
|
//添加文字2
|
||||||
range2 := pTest.AddText(0, '广东省');
|
range2 := pTest.AddText(0, '广东省');
|
||||||
range2.Font.Size := 28;
|
range2.Font.Size := 14;
|
||||||
range2.Font.Color := '0000FF';
|
range2.Font.Color := '0000FF';
|
||||||
range2.Font.Bold := true;
|
range2.Font.Bold := true;
|
||||||
range2.Apply();
|
range2.Apply();
|
||||||
@@ -603,7 +605,7 @@ Begin
|
|||||||
//r.Text := 'Tinysoft';
|
//r.Text := 'Tinysoft';
|
||||||
|
|
||||||
r := pTest.AddText(-1, ':www.tinysoft.com.cn');//段落后追加
|
r := pTest.AddText(-1, ':www.tinysoft.com.cn');//段落后追加
|
||||||
r.Font.Size := 20;
|
r.Font.Size := 10;
|
||||||
r.Font.Color := '0000FF';
|
r.Font.Color := '0000FF';
|
||||||
r.Font.Bold := true;
|
r.Font.Bold := true;
|
||||||
r.Apply();
|
r.Apply();
|
||||||
@@ -656,7 +658,7 @@ Begin
|
|||||||
p := TOfficeObj('TParagraph');
|
p := TOfficeObj('TParagraph');
|
||||||
p.Format.numPr.Level := 0;//项目编号
|
p.Format.numPr.Level := 0;//项目编号
|
||||||
p.Format.numPr.numId := docx.NumberingObject().NumberId('bullet', i); //项目编号
|
p.Format.numPr.numId := docx.NumberingObject().NumberId('bullet', i); //项目编号
|
||||||
p.Font.Size := 28;
|
p.Font.Size := 14;
|
||||||
p.Font.Color := 'FF0000';
|
p.Font.Color := 'FF0000';
|
||||||
p.Font.Bold := true;
|
p.Font.Bold := true;
|
||||||
p.Format.LeftIndent := 700;//段落左边距
|
p.Format.LeftIndent := 700;//段落左边距
|
||||||
@@ -829,7 +831,7 @@ Begin
|
|||||||
p.Font.Name := '宋体';
|
p.Font.Name := '宋体';
|
||||||
p.Font.Color := 'FF0000';
|
p.Font.Color := 'FF0000';
|
||||||
p.Font.Bold := true;
|
p.Font.Bold := true;
|
||||||
p.Font.Size := 29;
|
p.Font.Size := 15;
|
||||||
p1 := docx.AddParagraph(p, -1, nil);
|
p1 := docx.AddParagraph(p, -1, nil);
|
||||||
|
|
||||||
println(' >>OK\n');
|
println(' >>OK\n');
|
||||||
@@ -940,10 +942,10 @@ Function _AddClassHelpTable(docx, data);
|
|||||||
Begin
|
Begin
|
||||||
//设置边框属性
|
//设置边框属性
|
||||||
tbl := docx.CreateTable(data, true, true);
|
tbl := docx.CreateTable(data, true, true);
|
||||||
tbl.Format.Borders.Top.Size := 24;
|
tbl.Format.Borders.Top.Size := 12;
|
||||||
tbl.Format.Borders.Left.Size := 24;
|
tbl.Format.Borders.Left.Size := 12;
|
||||||
tbl.Format.Borders.Bottom.Size := 24;
|
tbl.Format.Borders.Bottom.Size := 12;
|
||||||
tbl.Format.Borders.Right.Size := 24;
|
tbl.Format.Borders.Right.Size := 12;
|
||||||
tbl.Format.Borders.Top.Val := 'thinThickThinMediumGap';
|
tbl.Format.Borders.Top.Val := 'thinThickThinMediumGap';
|
||||||
tbl.Format.Borders.Left.Val := 'thinThickThinMediumGap';
|
tbl.Format.Borders.Left.Val := 'thinThickThinMediumGap';
|
||||||
tbl.Format.Borders.Bottom.Val := 'thinThickThinMediumGap';
|
tbl.Format.Borders.Bottom.Val := 'thinThickThinMediumGap';
|
||||||
@@ -1144,7 +1146,7 @@ Begin
|
|||||||
if title then Begin
|
if title then Begin
|
||||||
p.Format.numPr.Level := 0;//项目编号
|
p.Format.numPr.Level := 0;//项目编号
|
||||||
p.Format.numPr.numId := numId;
|
p.Format.numPr.numId := numId;
|
||||||
p.Font.Size := 28;
|
p.Font.Size := 14;
|
||||||
p.Font.Color := 'FF0000';
|
p.Font.Color := 'FF0000';
|
||||||
p.Font.Bold := true;
|
p.Font.Bold := true;
|
||||||
p.Format.LeftIndent := 500;//段落左边距
|
p.Format.LeftIndent := 500;//段落左边距
|
||||||
@@ -1,28 +1,28 @@
|
|||||||
path := ExtractFileDir(ExtractFileDir(PluginPath()));
|
path := ExtractFileDir(ExtractFileDir(PluginPath()));
|
||||||
{$IFNDEF Win32}
|
{$IFNDEF Win32}
|
||||||
path := path + '\\funcext\\TSOffice\\TSExcelFile.tsf';
|
path := path + '/funcext/TSOffice/TSXlsxFile.tsf';
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
path := path + '/funcext/TSOffice/TSExcelFile.tsf';
|
path := path + '\\funcext\\TSOffice\\TSXlsxFile.tsf';
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
funcs := LoadClassInfo(path);
|
funcs := LoadClassInfo(path);
|
||||||
|
|
||||||
testing := 1;
|
testing := 1;
|
||||||
file := new TSExcelFile();
|
file := new TSXlsxFile();
|
||||||
[err, errinfo] := file.NewFile();
|
[err, errinfo] := file.NewFile();
|
||||||
if err then
|
if err then
|
||||||
return PrintError("NewFile", err, errinfo);
|
return PrintError("NewFile", err, errinfo);
|
||||||
PrintSuccess("NewFile", testing++);
|
PrintSuccess("NewFile", testing++);
|
||||||
|
|
||||||
file.SetSheetName('Sheet1', 'ExcelFile');
|
file.SetSheetName('Sheet1', 'XlsxFile');
|
||||||
PrintSuccess("SetSheetName", testing++);
|
PrintSuccess("SetSheetName", testing++);
|
||||||
|
|
||||||
file.NewSheet("Functions");
|
file.NewSheet("Functions");
|
||||||
PrintSuccess("NewSheet", testing++);
|
PrintSuccess("NewSheet", testing++);
|
||||||
|
|
||||||
file.SetDefaultSheet('ExcelFile');
|
file.SetDefaultSheet('TSXlsxFile');
|
||||||
|
|
||||||
richtext := TOfficeObj('TRichText');
|
richtext := TOfficeObj('TRichText');
|
||||||
txt1 := richtext.AddText('TSExcelFile类 ');
|
txt1 := richtext.AddText('TSXlsxFile类 ');
|
||||||
txt1.Font.Size := 35;
|
txt1.Font.Size := 35;
|
||||||
txt1.Font.Color := "FF0000";
|
txt1.Font.Color := "FF0000";
|
||||||
txt1.Font.Bold := 1;
|
txt1.Font.Bold := 1;
|
||||||
@@ -34,15 +34,16 @@ txt2.Font.Bold := 1;
|
|||||||
txt2.Font.Italic := 1;
|
txt2.Font.Italic := 1;
|
||||||
txt2.Font.Color := "FFC0CB";
|
txt2.Font.Color := "FFC0CB";
|
||||||
|
|
||||||
file.SetCellRichText('ExcelFile', 'A1', richtext);
|
file.SetCellRichText('XlsxFile', 'A1', richtext);
|
||||||
PrintSuccess("SetCellRichText", testing++);
|
PrintSuccess("SetCellRichText", testing++);
|
||||||
[err, richText] := file.GetCellRichText('ExcelFile', 'A1');
|
[err, richText] := file.GetCellRichText('XlsxFile', 'A1');
|
||||||
if err then
|
if err then
|
||||||
return PrintError("GetCellRichText", err, errinfo);
|
return PrintError("GetCellRichText", err, errinfo);
|
||||||
PrintSuccess("GetCellRichText", testing++);
|
PrintSuccess("GetCellRichText", testing++);
|
||||||
|
|
||||||
file.MergeCell('ExcelFile', 'A1', 'C1');
|
file.MergeCell('XlsxFile', 'A1', 'C1');
|
||||||
PrintSuccess("MergeCell", testing++);
|
PrintSuccess("MergeCell", testing++);
|
||||||
|
file.SetRowHeight('XlsxFile', 1, 60);
|
||||||
|
|
||||||
|
|
||||||
style := TOfficeObj('TStyle');
|
style := TOfficeObj('TStyle');
|
||||||
@@ -65,15 +66,15 @@ style.Fill.Gradient.Stop2.Color := "E0EBF5";
|
|||||||
styleId := file.NewStyle(style);
|
styleId := file.NewStyle(style);
|
||||||
PrintSuccess("NewStyle", testing++);
|
PrintSuccess("NewStyle", testing++);
|
||||||
|
|
||||||
file.SetCellStyle("ExcelFile", 'A1', 'C1', styleId);
|
file.SetCellStyle("XlsxFile", 'A1', 'C1', styleId);
|
||||||
|
|
||||||
file.SetCellValue("ExcelFile", "A3", "索引");
|
file.SetCellValue("XlsxFile", "A3", "索引");
|
||||||
file.SetCellValue("ExcelFile", "B3", "函数名称");
|
file.SetCellValue("XlsxFile", "B3", "函数名称");
|
||||||
file.SetCellValue("ExcelFile", "C3", "功能");
|
file.SetCellValue("XlsxFile", "C3", "功能");
|
||||||
file.SetColWidth("ExcelFile", "A", "A", 6);
|
file.SetColWidth("XlsxFile", "A", "A", 6);
|
||||||
file.SetColWidth("ExcelFile", "B", "B", 55);
|
file.SetColWidth("XlsxFile", "B", "B", 55);
|
||||||
file.SetColWidth("ExcelFile", "C", "C", 100);
|
file.SetColWidth("XlsxFile", "C", "C", 100);
|
||||||
file.SetCellStyle("ExcelFile", "A3", "C3", styleId);
|
file.SetCellStyle("XlsxFile", "A3", "C3", styleId);
|
||||||
|
|
||||||
|
|
||||||
style2 := TOfficeObj("TStyle");
|
style2 := TOfficeObj("TStyle");
|
||||||
@@ -108,9 +109,9 @@ Begin
|
|||||||
[err0, cell0] := file.CoordinatesToCellName(1, i+4);
|
[err0, cell0] := file.CoordinatesToCellName(1, i+4);
|
||||||
[err1, cell1] := file.CoordinatesToCellName(2, i+4);
|
[err1, cell1] := file.CoordinatesToCellName(2, i+4);
|
||||||
[err2, cell2] := file.CoordinatesToCellName(3, i+4);
|
[err2, cell2] := file.CoordinatesToCellName(3, i+4);
|
||||||
file.SetCellValue("ExcelFile", cell0, i+1);
|
file.SetCellValue("XlsxFile", cell0, i+1);
|
||||||
file.SetCellValue("ExcelFile", cell1, funcs[i]['funcname']);
|
file.SetCellValue("XlsxFile", cell1, funcs[i]['funcname']);
|
||||||
file.SetCellValue("ExcelFile", cell2, funcs[i]['name']);
|
file.SetCellValue("XlsxFile", cell2, funcs[i]['name']);
|
||||||
|
|
||||||
str := funcs[i]['name'] + "\nFunction " + funcs[i]['funcname'] + funcs[i]['comment'];
|
str := funcs[i]['name'] + "\nFunction " + funcs[i]['funcname'] + funcs[i]['comment'];
|
||||||
arr := str2array(str, "\n");
|
arr := str2array(str, "\n");
|
||||||
@@ -130,15 +131,15 @@ Begin
|
|||||||
hyperlink.LinkType := "location";
|
hyperlink.LinkType := "location";
|
||||||
hyperlink.LinkUrl := "Functions!" $ c1;
|
hyperlink.LinkUrl := "Functions!" $ c1;
|
||||||
|
|
||||||
file.SetCellHyperLink("ExcelFile", cell1, hyperlink);
|
file.SetCellHyperLink("XlsxFile", cell1, hyperlink);
|
||||||
file.SetCellStyle("ExcelFile", cell1, cell1, styleId4);
|
file.SetCellStyle("XlsxFile", cell1, cell1, styleId4);
|
||||||
|
|
||||||
End
|
End
|
||||||
|
|
||||||
file.SetColWidth('Functions', 'A', 'A', 120);
|
file.SetColWidth('Functions', 'A', 'A', 120);
|
||||||
PrintSuccess('SetColWidth', testing++);
|
PrintSuccess('SetColWidth', testing++);
|
||||||
|
|
||||||
saveName := utf8toansi("ExcelFile使用帮助.xlsx");
|
saveName := "XlsxFile使用帮助.xlsx";
|
||||||
[err, errinfo] := file.SaveAs('', saveName);
|
[err, errinfo] := file.SaveAs('', saveName);
|
||||||
if err then
|
if err then
|
||||||
return PrintError("SaveAs", err, errinfo);
|
return PrintError("SaveAs", err, errinfo);
|
||||||
@@ -320,6 +321,7 @@ Begin
|
|||||||
excel.SetCellValue(sheet_name, cell_1, name);
|
excel.SetCellValue(sheet_name, cell_1, name);
|
||||||
excel.MergeCell(sheet_name, cell_1, cell_2);
|
excel.MergeCell(sheet_name, cell_1, cell_2);
|
||||||
excel.SetCellStyle(sheet_name, cell_1, cell_2, styleid1);
|
excel.SetCellStyle(sheet_name, cell_1, cell_2, styleid1);
|
||||||
|
excel.SetRowHeight(sheet_name, row, 25);
|
||||||
row++;
|
row++;
|
||||||
|
|
||||||
desc_arr := obj_info[i]['Desc'];
|
desc_arr := obj_info[i]['Desc'];
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
# OfficePlugin
|
# TSOffice
|
||||||
|
|
||||||
TSOffice 项目:纯 TSL 代码实现 excel、word 文件读写
|
TSOffice 项目:纯 TSL 代码实现 excel、word 文件读写
|
||||||
|
|
||||||
@@ -6,24 +6,36 @@ TSOffice 项目:纯 TSL 代码实现 excel、word 文件读写
|
|||||||
|
|
||||||
### windows
|
### windows
|
||||||
|
|
||||||
对应文件夹的dll文件按如下要求
|
对应文件夹的 dll 文件按如下要求
|
||||||
|
|
||||||
- `fmt_pubkrnl_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
|
|
||||||
- `office_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
|
- `office_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
|
||||||
|
|
||||||
|
可选:
|
||||||
|
|
||||||
|
- `fmt_pubkrnl_plugin` 放入 tsl 安装根目录下 Plugin 文件夹,若需要执行 Demo 文件夹下的[XlsxHelp.tsl](./Demo/XlsxHelp.tsl)和[DocxHelp.tsl](./Demo/DocxHelp.tsl),需要部署改动态库
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
根据架构选择aarch64或x86版本将对应文件夹内容进行部署
|
#### Ubuntu-18.04
|
||||||
|
|
||||||
|
根据架构选择 aarch64 或 x86 版本将对应文件夹内容进行部署
|
||||||
|
|
||||||
- `liboffice_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
|
- `liboffice_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
|
||||||
|
|
||||||
## 帮助文档
|
## 帮助文档
|
||||||
|
|
||||||
- [Excel 帮助文档](./ExcelFile使用帮助.xlsx)
|
- [Excel 帮助文档](./XlsxFile使用帮助.xlsx)
|
||||||
|
|
||||||
- [Word 帮助文档](./DocxFile使用帮助.docx)
|
- [Word 帮助文档](./DocxFile使用帮助.docx)
|
||||||
|
|
||||||
|
## 扩展
|
||||||
|
|
||||||
|
扩展模块的内容需要通过`git submodule update --init --recursive`获取,相关帮助文档在`./funcext/TSOffice/Extensions/模块名`目录下可获取
|
||||||
|
|
||||||
|
支持的扩展:
|
||||||
|
|
||||||
|
- **OfficeVba**: 可通过类 Vba 方式对 office文件 进行读写操作。
|
||||||
|
|
||||||
## Demo
|
## Demo
|
||||||
|
|
||||||
Demo文件夹提供了一些参考的demo
|
Demo 文件夹提供了一些参考的 demo
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Submodule
+1
Submodule funcext/TSOffice/Extensions/OfficeVba added at 0aa9639ae0
+1756
-1047
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
+127
-19
@@ -1,5 +1,4 @@
|
|||||||
// Version 1.3.0
|
// Version 1.8.8
|
||||||
|
|
||||||
Type TSDocxFile = Class
|
Type TSDocxFile = Class
|
||||||
///Version: V1.0 2022-09-20
|
///Version: V1.0 2022-09-20
|
||||||
///适用于 Microsoft Word docx格式文件
|
///适用于 Microsoft Word docx格式文件
|
||||||
@@ -18,7 +17,17 @@ Type TSDocxFile = Class
|
|||||||
Function Create(alias, fname); overload;
|
Function Create(alias, fname); overload;
|
||||||
Begin
|
Begin
|
||||||
init();
|
init();
|
||||||
OpenFile(alias, fname);
|
OpenFile(alias, fname, nil);
|
||||||
|
End;
|
||||||
|
|
||||||
|
///构造函数,打开已经存在的docx文件
|
||||||
|
///alias: string,文件目录别名
|
||||||
|
///fname: string,文件名
|
||||||
|
///passwd: string,密码
|
||||||
|
Function Create(alias, fname, passwd); overload;
|
||||||
|
Begin
|
||||||
|
init();
|
||||||
|
OpenFile(alias, fname, passwd);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function Destory();
|
Function Destory();
|
||||||
@@ -34,11 +43,13 @@ Type TSDocxFile = Class
|
|||||||
///打开docx文件
|
///打开docx文件
|
||||||
///alias: string,文件目录别名
|
///alias: string,文件目录别名
|
||||||
///fname: string,文件名
|
///fname: string,文件名
|
||||||
|
///[passwd]: string,密码
|
||||||
///返回:[err, errmsg]
|
///返回:[err, errmsg]
|
||||||
Function OpenFile(alias, fname);
|
Function OpenFile(alias, fname, passwd);
|
||||||
Begin
|
Begin
|
||||||
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
|
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
|
||||||
[err, errmsg] := zipfile_.Open(alias, fname);
|
if zipfile_.FilesCount() > 0 then zipfile_ := new ZipFile();
|
||||||
|
[err, errmsg] := zipfile_.Open(alias, TOfficeApi().CurCodePageToGBK(fname), passwd);
|
||||||
if err=0 then Begin
|
if err=0 then Begin
|
||||||
document_ := new docxDocument(zipfile_);
|
document_ := new docxDocument(zipfile_);
|
||||||
End;
|
End;
|
||||||
@@ -57,6 +68,12 @@ Type TSDocxFile = Class
|
|||||||
return array(err, errmsg);
|
return array(err, errmsg);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///设置密码
|
||||||
|
Function SetPassword(passwd)
|
||||||
|
Begin
|
||||||
|
zipfile_.Password := passwd;
|
||||||
|
End;
|
||||||
|
|
||||||
///保存文件
|
///保存文件
|
||||||
///返回: [err, info]
|
///返回: [err, info]
|
||||||
Function Save();
|
Function Save();
|
||||||
@@ -70,7 +87,7 @@ Type TSDocxFile = Class
|
|||||||
///返回: [err, info]
|
///返回: [err, info]
|
||||||
Function SaveAs(alias, fname);
|
Function SaveAs(alias, fname);
|
||||||
Begin
|
Begin
|
||||||
return zipfile_.Save(alias, fname);
|
return zipfile_.Save(alias, TOfficeApi().CurCodePageToGBK(fname));
|
||||||
End;
|
End;
|
||||||
|
|
||||||
///另存为二进制流数据
|
///另存为二进制流数据
|
||||||
@@ -96,7 +113,10 @@ Type TSDocxFile = Class
|
|||||||
///返回:string
|
///返回:string
|
||||||
Function FileName();
|
Function FileName();
|
||||||
Begin
|
Begin
|
||||||
return zipfile_.FileName();
|
file_name := zipfile_.FileName();
|
||||||
|
if TOfficeApi().IsUtf8() then
|
||||||
|
return AnsiToUTF8(file_name);
|
||||||
|
return file_name;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
///word文档所有段落
|
///word文档所有段落
|
||||||
@@ -106,6 +126,13 @@ Type TSDocxFile = Class
|
|||||||
return document_.Body().Paragraphs();
|
return document_.Body().Paragraphs();
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///word文档最后一个段落
|
||||||
|
///返回:TParagraph对象
|
||||||
|
Function LastParagraph();
|
||||||
|
Begin
|
||||||
|
return document_.Body().LastParagraph();
|
||||||
|
End;
|
||||||
|
|
||||||
///添加新段落
|
///添加新段落
|
||||||
///paragraph: TParagraph对象
|
///paragraph: TParagraph对象
|
||||||
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加段落
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加段落
|
||||||
@@ -123,6 +150,7 @@ Type TSDocxFile = Class
|
|||||||
///返回TParagraph对象
|
///返回TParagraph对象
|
||||||
Function AddHeading(title, posOpt, level);
|
Function AddHeading(title, posOpt, level);
|
||||||
Begin
|
Begin
|
||||||
|
if ifstring(level) then return document_.Body().AddHeading(title, getPosNode(posOpt), level);
|
||||||
styleName := level = 0 ? 'Title' : 'Heading ' $ level;
|
styleName := level = 0 ? 'Title' : 'Heading ' $ level;
|
||||||
style := StyleObject().GetStyle(styleName);
|
style := StyleObject().GetStyle(styleName);
|
||||||
if not ifObj(style) and ifInt(level) and level >= 0 and level <= 9 then
|
if not ifObj(style) and ifInt(level) and level >= 0 and level <= 9 then
|
||||||
@@ -189,7 +217,7 @@ Type TSDocxFile = Class
|
|||||||
End;
|
End;
|
||||||
|
|
||||||
///word文档指定表格
|
///word文档指定表格
|
||||||
///n: int 第n个表格
|
///n: int 从0开始,第n个表格
|
||||||
///返回:TTable对象
|
///返回:TTable对象
|
||||||
Function GetTable(n);
|
Function GetTable(n);
|
||||||
Begin
|
Begin
|
||||||
@@ -211,10 +239,12 @@ Type TSDocxFile = Class
|
|||||||
///插入数据表
|
///插入数据表
|
||||||
///tbl: TTable对象
|
///tbl: TTable对象
|
||||||
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加表格
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加表格
|
||||||
|
///customCell: 二维数组,自定义指定单元格的样式
|
||||||
|
/// 如:一行一列arr[0][0] := array(twtcPr, twpPr, twrPr);其中twtcPr是twtcPr对象,twpPr是twpPr对象,twrPr是twrPr对象
|
||||||
///返回: TTable对象
|
///返回: TTable对象
|
||||||
Function InsertTable(tbl, posOpt);
|
Function InsertTable(tbl, posOpt, customCell);
|
||||||
Begin
|
Begin
|
||||||
return document_.Body().InsertTable(tbl, getPosNode(posOpt));
|
return document_.Body().InsertTable(tbl, getPosNode(posOpt), customCell);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
///返回CoreProperties对象
|
///返回CoreProperties对象
|
||||||
@@ -240,6 +270,13 @@ Type TSDocxFile = Class
|
|||||||
return document_.Body().Sections(index);
|
return document_.Body().Sections(index);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///获取Structured Document Tag
|
||||||
|
///返回:TSdt集合
|
||||||
|
Function Sdts();
|
||||||
|
Begin
|
||||||
|
return document_.Body().Sdts();
|
||||||
|
End;
|
||||||
|
|
||||||
///添加章节
|
///添加章节
|
||||||
///session:TDocSection对象
|
///session:TDocSection对象
|
||||||
///posOpt: 位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加章节
|
///posOpt: 位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加章节
|
||||||
@@ -304,7 +341,7 @@ Type TSDocxFile = Class
|
|||||||
///返回TChart对象
|
///返回TChart对象
|
||||||
Function CopyExcelChart(excelFileName, excelSheetName, chartName, Width, Height, posOpt);
|
Function CopyExcelChart(excelFileName, excelSheetName, chartName, Width, Height, posOpt);
|
||||||
Begin
|
Begin
|
||||||
excel := new TSExcelFile();
|
excel := new TSXlsxFile();
|
||||||
[err, msg] := excel.OpenFile('', excelFileName);
|
[err, msg] := excel.OpenFile('', excelFileName);
|
||||||
if err then return nil;
|
if err then return nil;
|
||||||
[err, charts] := excel.GetCharts(excelSheetName);
|
[err, charts] := excel.GetCharts(excelSheetName);
|
||||||
@@ -353,6 +390,42 @@ Type TSDocxFile = Class
|
|||||||
return nil;
|
return nil;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///复制Word内容
|
||||||
|
///alias: string,文件目录别名
|
||||||
|
///fileName: string,文件名
|
||||||
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
|
||||||
|
///返回: [err, TDocxCopy对象]
|
||||||
|
///TDocxCopy.GetCopiedTable() 返回复制的对象表格数组
|
||||||
|
///TDocxCopy.GetCopiedParagraph() 返回复制对象的段落数组
|
||||||
|
///TDocxCopy.GetCopiedDrawing() 返回复制对象的图表数组
|
||||||
|
Function InsertFile(alias, fileName, posOpt);overload;
|
||||||
|
Begin
|
||||||
|
document_.AddNameSpace('w16du', 'http://schemas.microsoft.com/office/word/2023/wordml/word16du');
|
||||||
|
docxObj := new TSDocxFile();
|
||||||
|
[err, msg] := docxObj.OpenFile(alias, fileName);
|
||||||
|
if err then return array(err, msg);
|
||||||
|
copy_obj := new TDocxCopy(self, docxObj);
|
||||||
|
copy_obj.Init();
|
||||||
|
copy_obj.Copy(posOpt);
|
||||||
|
return array(0, copy_obj);
|
||||||
|
End;
|
||||||
|
|
||||||
|
///复制Word内容
|
||||||
|
///docxObj: TSDocxFile对象
|
||||||
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
|
||||||
|
///返回: [err, TDocxCopy对象]
|
||||||
|
///TDocxCopy.GetCopiedTable() 返回复制的对象表格数组
|
||||||
|
///TDocxCopy.GetCopiedParagraph() 返回复制对象的段落数组
|
||||||
|
///TDocxCopy.GetCopiedDrawing() 返回复制对象的图表数组
|
||||||
|
Function InsertFile(docxObj, posOpt);overload;
|
||||||
|
Begin
|
||||||
|
document_.AddNameSpace('w16du', 'http://schemas.microsoft.com/office/word/2023/wordml/word16du');
|
||||||
|
copy_obj := new TDocxCopy(self, docxObj);
|
||||||
|
copy_obj.Init();
|
||||||
|
copy_obj.Copy(posOpt);
|
||||||
|
return array(0, copy_obj);
|
||||||
|
End;
|
||||||
|
|
||||||
///遍历文档中所有[TSTAG][/TSTAG]标签,针对每一个TAG执行tagObj.Apply()
|
///遍历文档中所有[TSTAG][/TSTAG]标签,针对每一个TAG执行tagObj.Apply()
|
||||||
///tagName:string 标签名称
|
///tagName:string 标签名称
|
||||||
///tagObj:TAG对象方法
|
///tagObj:TAG对象方法
|
||||||
@@ -463,7 +536,26 @@ Type TSDocxFile = Class
|
|||||||
content.node_ := document_.Body().node_.InsertAfterChild(node, content.Marshal());
|
content.node_ := document_.Body().node_.InsertAfterChild(node, content.Marshal());
|
||||||
else
|
else
|
||||||
content.node_ := document_.Body().node_.InsertFirstChild(content.Marshal());
|
content.node_ := document_.Body().node_.InsertFirstChild(content.Marshal());
|
||||||
AddPageBreak(content.node_);
|
//AddPageBreak(content.node_);
|
||||||
|
return content;
|
||||||
|
End;
|
||||||
|
|
||||||
|
///添加自定义目录
|
||||||
|
///[posOpt: 段落位置],在posOpt之后新添加目录(否则在首页添加)
|
||||||
|
///UpperHeadingLevel:标题最高级别
|
||||||
|
///LowerHeadingLevel:标题最低级别
|
||||||
|
/// 使用 UpperHeadingLevel 属性可设置起始标题级别(最高)。例如,若要设置 TOC 域语法 {TOC \o "1-3"},可将 LowerHeadingLevel 属性设为 3,并将 UpperHeadingLevel 属性设为 1。
|
||||||
|
///因为word、wps、openoffice等软件对于页码的计算各不相同,本功能不直接设置页码,需要用相关客户端软件打开文件后,更新目录域。
|
||||||
|
Function AddCustomTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
||||||
|
Begin
|
||||||
|
content := new TTableContent(self);
|
||||||
|
node := getPosNode(posOpt);
|
||||||
|
content.CustomAdd(node, UpperHeadingLevel, LowerHeadingLevel); //标题级别
|
||||||
|
if ifObj(node) then
|
||||||
|
content.node_ := document_.Body().node_.InsertAfterChild(node, content.Marshal());
|
||||||
|
else
|
||||||
|
content.node_ := document_.Body().node_.InsertFirstChild(content.Marshal());
|
||||||
|
//AddPageBreak(content.node_);
|
||||||
return content;
|
return content;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@@ -473,7 +565,7 @@ Type TSDocxFile = Class
|
|||||||
///返回:array((("Level":level,"Paragraph":"object","Text":title));
|
///返回:array((("Level":level,"Paragraph":"object","Text":title));
|
||||||
Function GetHeadingList(UpperHeadingLevel, LowerHeadingLevel);
|
Function GetHeadingList(UpperHeadingLevel, LowerHeadingLevel);
|
||||||
Begin
|
Begin
|
||||||
return document_.Body().GetHeadingListImpl(self, nil, UpperHeadingLevel, LowerHeadingLevel, nil, true);
|
return document_.Body().GetHeadingListImpl(self, nil, UpperHeadingLevel, LowerHeadingLevel, nil);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
//返回Document对象
|
//返回Document对象
|
||||||
@@ -498,6 +590,17 @@ Type TSDocxFile = Class
|
|||||||
return numberingObj_;
|
return numberingObj_;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///返回:TFootnotes对象
|
||||||
|
Function FootNotesObject();
|
||||||
|
Begin
|
||||||
|
if not ifObj(footnotesObj_) then
|
||||||
|
begin
|
||||||
|
footnotesObj_ := new TOfficeObj('TFootnoteBody');
|
||||||
|
footnotesObj_.InitFootnotes(self.Zip());
|
||||||
|
end
|
||||||
|
return footnotesObj_;
|
||||||
|
End;
|
||||||
|
|
||||||
///执行word文档内嵌tsl代码(执行内嵌脚本的环境字符集为GBK)
|
///执行word文档内嵌tsl代码(执行内嵌脚本的环境字符集为GBK)
|
||||||
///返回:[err,tslFuncCount,errArr]: err 执行错误TSL代码段次数,tslFuncCount TSL代码段总数,errArr 执行TSL错误信息(array(('code':'代码', 'err':'错误信息')))
|
///返回:[err,tslFuncCount,errArr]: err 执行错误TSL代码段次数,tslFuncCount TSL代码段总数,errArr 执行TSL错误信息(array(('code':'代码', 'err':'错误信息')))
|
||||||
Function ExecInnerTSL();
|
Function ExecInnerTSL();
|
||||||
@@ -526,24 +629,28 @@ Type TSDocxFile = Class
|
|||||||
DocPrId_ := 0;
|
DocPrId_ := 0;
|
||||||
ps := Paragraphs();
|
ps := Paragraphs();
|
||||||
for i:=0 to length(ps)-1 do Begin
|
for i:=0 to length(ps)-1 do Begin
|
||||||
node := class(TSXml).GetNode(ps[i].node_, 'w:r/w:drawing/wp:inline/wp:docPr');
|
runs := ps[i].GetRuns();
|
||||||
|
for j:=0 to length(runs)-1 do Begin
|
||||||
|
node := class(TSXml).GetNode(runs[j].node_, 'w:drawing/wp:inline/wp:docPr');
|
||||||
if not ifObj(node) then
|
if not ifObj(node) then
|
||||||
node := class(TSXml).GetNode(ps[i].node_, 'w:r/w:pict/v:shape/v:textbox/w:txbxContent/wp:docPr');
|
node := class(TSXml).GetNode(runs[j].node_, 'w:drawing/wp:anchor/wp:docPr');
|
||||||
if not ifObj(node) then
|
if not ifObj(node) then
|
||||||
node := class(TSXml).GetNode(ps[i].node_, 'w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr');
|
node := class(TSXml).GetNode(runs[j].node_, 'w:pict/v:shape/v:textbox/w:txbxContent/wp:docPr');
|
||||||
|
if not ifObj(node) then
|
||||||
|
node := class(TSXml).GetNode(runs[j].node_, 'mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr');
|
||||||
if ifObj(node) then Begin
|
if ifObj(node) then Begin
|
||||||
id := class(TSXml).SafeStrToIntDef(node.GetAttribute('id'), 0);
|
id := class(TSXml).SafeStrToIntDef(node.GetAttribute('id'), 0);
|
||||||
if id > DocPrId_ then
|
if id > DocPrId_ then
|
||||||
DocPrId_ := id;
|
DocPrId_ := id;
|
||||||
break;
|
End;
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
DocPrId_ ++;
|
DocPrId_ ++;
|
||||||
return DocPrId_;
|
return DocPrId_;
|
||||||
End;
|
End;
|
||||||
private
|
|
||||||
Function getPosNode(posOpt);
|
Function GetPosNode(posOpt);
|
||||||
Begin
|
Begin
|
||||||
node := posOpt;
|
node := posOpt;
|
||||||
if ifObj(node) and not (node is Class(XmlNode)) then
|
if ifObj(node) and not (node is Class(XmlNode)) then
|
||||||
@@ -554,6 +661,7 @@ private
|
|||||||
zipfile_; //压缩文件对象
|
zipfile_; //压缩文件对象
|
||||||
document_; //Document对象
|
document_; //Document对象
|
||||||
styleObj_;
|
styleObj_;
|
||||||
|
footnotesObj_;
|
||||||
numberingObj_;
|
numberingObj_;
|
||||||
DocPrId_;
|
DocPrId_;
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Version 1.3.0
|
// Version 1.5.0
|
||||||
|
|
||||||
Type TSExcelFile = Class
|
Type TSExcelFile = Class
|
||||||
///Version: V1.0 2022-08-08
|
///Version: V1.0 2022-08-08
|
||||||
@@ -18,7 +18,17 @@ Type TSExcelFile = Class
|
|||||||
Function Create(alias, fname); overload;
|
Function Create(alias, fname); overload;
|
||||||
Begin
|
Begin
|
||||||
init();
|
init();
|
||||||
OpenFile(alias, fname);
|
OpenFile(alias, fname, nil);
|
||||||
|
End;
|
||||||
|
|
||||||
|
///构造函数,打开已经存在的excel文件
|
||||||
|
///alias: string,文件目录别名
|
||||||
|
///fname: string,文件名
|
||||||
|
///passwd: string,密码
|
||||||
|
Function Create(alias, fname, passwd); overload;
|
||||||
|
Begin
|
||||||
|
init();
|
||||||
|
OpenFile(alias, fname, passwd);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
//析构函数
|
//析构函数
|
||||||
@@ -35,12 +45,13 @@ Type TSExcelFile = Class
|
|||||||
///打开excel文件
|
///打开excel文件
|
||||||
///alias: string,文件目录别名
|
///alias: string,文件目录别名
|
||||||
///fname: string,文件名
|
///fname: string,文件名
|
||||||
|
///[passwd]: string,密码
|
||||||
///返回: [err, errmsg]
|
///返回: [err, errmsg]
|
||||||
Function OpenFile(alias, fname);
|
Function OpenFile(alias, fname, passwd);
|
||||||
Begin
|
Begin
|
||||||
init();
|
|
||||||
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
|
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
|
||||||
[err, errmsg] := zipfile_.Open(alias, fname);
|
if zipfile_.FilesCount() > 0 then zipfile_ := new ZipFile();
|
||||||
|
[err, errmsg] := zipfile_.Open(alias, fname, passwd);
|
||||||
if err=0 then Begin
|
if err=0 then Begin
|
||||||
workbook_ := new xlsxWorkBook(zipfile_);
|
workbook_ := new xlsxWorkBook(zipfile_);
|
||||||
workbook_.Load();
|
workbook_.Load();
|
||||||
@@ -69,6 +80,12 @@ Type TSExcelFile = Class
|
|||||||
return zipfile_.Save();
|
return zipfile_.Save();
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///设置密码
|
||||||
|
Function SetPassword(passwd)
|
||||||
|
Begin
|
||||||
|
zipfile_.Password := passwd;
|
||||||
|
End;
|
||||||
|
|
||||||
///打开二进制内容
|
///打开二进制内容
|
||||||
///data: 二进制数据
|
///data: 二进制数据
|
||||||
///返回: [err, errmsg]
|
///返回: [err, errmsg]
|
||||||
@@ -898,7 +915,7 @@ Type TSExcelFile = Class
|
|||||||
|
|
||||||
///复制Sheet
|
///复制Sheet
|
||||||
///sourceSheet: 源工作表
|
///sourceSheet: 源工作表
|
||||||
///destSheet: 目的工作表
|
///destSheet: 目的工作表,如果destSheet存在,则覆盖destSheet,否则末尾新增destSheet
|
||||||
Function CopySheet(sourceSheet, destSheet);
|
Function CopySheet(sourceSheet, destSheet);
|
||||||
Begin
|
Begin
|
||||||
return workbook_.CopySheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet));
|
return workbook_.CopySheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet));
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
Type NodeInfo = class
|
Type NodeInfo = class
|
||||||
|
|
||||||
public
|
public
|
||||||
Function Create(p, name);
|
Function Create(parentObj, name);
|
||||||
Begin
|
Begin
|
||||||
if ifObj(p) then
|
if ifObj(parentObj) then
|
||||||
NodeUri := p.NodeUri = '' ? name : (p.NodeUri + '/' + name);
|
NodeUri := parentObj.NodeUri = '' ? name : (parentObj.NodeUri + '/' + name);
|
||||||
else
|
else
|
||||||
NodeUri := '';
|
NodeUri := '';
|
||||||
NodeName := name;
|
NodeName := name;
|
||||||
@@ -18,25 +18,59 @@ public
|
|||||||
return RootObj;
|
return RootObj;
|
||||||
End
|
End
|
||||||
|
|
||||||
Function Update();
|
Function Update(position);overload;
|
||||||
Begin
|
Begin
|
||||||
if ifObj(RootObj) then Begin
|
if ifObj(RootObj) then Begin
|
||||||
arr := Marshal();
|
arr := Marshal();
|
||||||
if length(arr['attributes']) or length(arr['children']) then Begin
|
if length(arr['attributes']) or length(arr['children']) then Begin
|
||||||
curNode := class(TSXml).GetNode(RootObj, NodeUri);
|
curNode := class(TSXml).GetNode(RootObj, NodeUri, position);
|
||||||
if ifObj(curNode) then
|
if ifObj(curNode) then
|
||||||
class(TSXml).UpdateNode(curNode, arr['attributes'], arr['children']);
|
class(TSXml).UpdateNode(curNode, arr['attributes'], arr['children']);
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function HandleAttrs(); virtual;
|
Function Update();overload;
|
||||||
Begin
|
Begin
|
||||||
End
|
self.Update("end");
|
||||||
|
End;
|
||||||
|
|
||||||
Function HandleChildren(); virtual;
|
Function Delete();overload;
|
||||||
Begin
|
Begin
|
||||||
End
|
if ifObj(RootObj) then
|
||||||
|
begin
|
||||||
|
curNode := class(TSXml).GetNode(RootObj, NodeUri);
|
||||||
|
if ifObj(curNode) then curNode.DeleteChildren();
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function Delete(name);overload;
|
||||||
|
Begin
|
||||||
|
if not ifObj(RootObj) then return false;
|
||||||
|
node := NodeUri <> '' ? class(TSXml).GetNode(RootObj, NodeUri) : RootObj;
|
||||||
|
|
||||||
|
attrs := GetAttrsEx();
|
||||||
|
lName := lowerCase(name);
|
||||||
|
r := sselect * from attrs where lName = lowerCase([0]) end;
|
||||||
|
if istable(r) then
|
||||||
|
begin
|
||||||
|
node.DeleteAttribute(r[1]);
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
|
||||||
|
children := GetChildren();
|
||||||
|
r := select * from children where lName = lowerCase(['field']) end;
|
||||||
|
if istable(r) then Begin
|
||||||
|
r := r[0];
|
||||||
|
delete_node := node.FirstChildElement(r['name']);
|
||||||
|
if ifObj(delete_node) then
|
||||||
|
begin
|
||||||
|
node.DeleteChild(delete_node);
|
||||||
|
return true;
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
return false;
|
||||||
|
End;
|
||||||
|
|
||||||
Function GetAttrs(); virtual;
|
Function GetAttrs(); virtual;
|
||||||
Begin
|
Begin
|
||||||
@@ -71,35 +105,25 @@ public
|
|||||||
children_ := nil;
|
children_ := nil;
|
||||||
GetChildrenEx(); //优化为变量,减少数据COPY,2022-12-10
|
GetChildrenEx(); //优化为变量,减少数据COPY,2022-12-10
|
||||||
child_arr := array();
|
child_arr := array();
|
||||||
|
name_map := array();
|
||||||
len := 0;
|
len := 0;
|
||||||
for i:=0 to length(children_)-1 do
|
for i:=0 to length(children_)-1 do
|
||||||
begin
|
begin
|
||||||
node_type := children_[i]['nodeType'];
|
node_type := children_[i]['nodeType'];
|
||||||
obj := children_[i]['obj'];
|
obj := children_[i]['obj'];
|
||||||
if ifnil(obj) then continue;
|
if ifnil(obj) then continue;
|
||||||
//find := select thisrowindex as "rowindex_", * from child_arr where ['name'] = children_[i]['name'] end; //优化为循环,性能提高15-20%,2022-12-20
|
if not ifObj(obj) and not ifnil(name_map[children_[i]['name']]) and children_[i]['attrEx'] <> '' then
|
||||||
find := array();
|
|
||||||
for j:=length(child_arr)-1 downto 0 do Begin //支持列表模式(如多节点:<w:t xml:space=""></w:t>),查找最近的节点
|
|
||||||
if child_arr[j]['name'] = children_[i]['name'] then Begin
|
|
||||||
find[0] := child_arr[j];
|
|
||||||
find[0]['rowindex_'] := j;
|
|
||||||
break;
|
|
||||||
End;
|
|
||||||
End;
|
|
||||||
if not ifnil(obj) and not ifObj(obj) and istable(find) and ifstring(children_[i]['attrEx']) and children_[i]['attrEx'] <> '' then
|
|
||||||
begin
|
begin
|
||||||
if not ifarray(find[0]['attributes']) then find[0]['attributes'] := array();
|
child_arr[name_map[children_[i]['name']]]['attributes'] union=array(children_[i]['attrEx'] : obj);
|
||||||
key := children_[i]['attrEx'];
|
|
||||||
find[0]['attributes'] union= array(key : obj);
|
|
||||||
child_arr[find[0]['rowindex_']]['attributes'] := find[0]['attributes'];
|
|
||||||
continue;
|
continue;
|
||||||
end
|
end
|
||||||
|
|
||||||
arr := array('type': 'element', 'name': children_[i]['name'], 'attributes': array());
|
arr := array('type': 'element', 'name': children_[i]['name'], 'attributes': array());
|
||||||
if node_type = 'empty' then // <b/>
|
if node_type = 'empty' then // <b/>
|
||||||
begin
|
begin
|
||||||
if obj = 0 then arr['attributes'] := array('val': 0);
|
empty_name := children_[i]['attrEx'] ? children_[i]['attrEx'] : 'val';
|
||||||
else if obj = 1 then arr['attributes'] := array('val': 1)
|
if obj = 0 then arr['attributes'] := array(empty_name: 0);
|
||||||
|
else if obj = 1 then arr['attributes'] := array(empty_name: 1);
|
||||||
end
|
end
|
||||||
else if node_type = 'pcdata' then
|
else if node_type = 'pcdata' then
|
||||||
begin
|
begin
|
||||||
@@ -117,7 +141,7 @@ public
|
|||||||
key := children_[i]['attrName'] ? children_[i]['attrName'] : children_[i]['attrEx'] ? children_[i]['attrEx'] : 'val';
|
key := children_[i]['attrName'] ? children_[i]['attrName'] : children_[i]['attrEx'] ? children_[i]['attrEx'] : 'val';
|
||||||
arr['attributes'] := array(key : obj);
|
arr['attributes'] := array(key : obj);
|
||||||
end
|
end
|
||||||
|
name_map[children_[i]['name']] := len;
|
||||||
child_arr[len++] := arr;
|
child_arr[len++] := arr;
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -153,7 +177,7 @@ public
|
|||||||
return 1;
|
return 1;
|
||||||
End
|
End
|
||||||
|
|
||||||
Function Value(name);
|
Function Value(name, nottransferable);
|
||||||
Begin
|
Begin
|
||||||
if not ifObj(RootObj) then return nil;
|
if not ifObj(RootObj) then return nil;
|
||||||
if NodeUri <> '' then
|
if NodeUri <> '' then
|
||||||
@@ -168,7 +192,7 @@ public
|
|||||||
if istable(r) then
|
if istable(r) then
|
||||||
begin
|
begin
|
||||||
value := node.GetAttribute(r[1]);
|
value := node.GetAttribute(r[1]);
|
||||||
return trystrtofloat(value, r) ? r : value;
|
return nottransferable ? value : trystrtofloat(value, r) ? r : value;
|
||||||
end
|
end
|
||||||
|
|
||||||
children := GetChildren();
|
children := GetChildren();
|
||||||
@@ -176,7 +200,7 @@ public
|
|||||||
if istable(r) then Begin
|
if istable(r) then Begin
|
||||||
r := r[0];
|
r := r[0];
|
||||||
node := node.FirstChildElement(r['name']);
|
node := node.FirstChildElement(r['name']);
|
||||||
if not ifObj(node) and r['nodeType'] = 'empty' then return false;
|
if not ifObj(node) and r['nodeType'] = 'empty' and not nottransferable then return false;
|
||||||
if not ifObj(node) then return nil;
|
if not ifObj(node) then return nil;
|
||||||
if r['nodeType'] = 'pcdata' then //返回文本串
|
if r['nodeType'] = 'pcdata' then //返回文本串
|
||||||
return node.GetText();
|
return node.GetText();
|
||||||
@@ -185,7 +209,7 @@ public
|
|||||||
key := r['attrName'] ? r['attrName'] : r['attrEx'] ? r['attrEx'] : 'val';
|
key := r['attrName'] ? r['attrName'] : r['attrEx'] ? r['attrEx'] : 'val';
|
||||||
value := node.GetAttribute(key);
|
value := node.GetAttribute(key);
|
||||||
if r['nodeType'] = 'empty' and value = '' then return true;
|
if r['nodeType'] = 'empty' and value = '' then return true;
|
||||||
return trystrtofloat(value, r) ? r : value;
|
return nottransferable ? value : trystrtofloat(value, r) ? r : value;
|
||||||
End;
|
End;
|
||||||
return nil;
|
return nil;
|
||||||
End;
|
End;
|
||||||
@@ -268,9 +292,8 @@ public
|
|||||||
NodeName;
|
NodeName;
|
||||||
ExtAttr;
|
ExtAttr;
|
||||||
ExtNodes;
|
ExtNodes;
|
||||||
//Parent;
|
|
||||||
ReplaceArr;
|
ReplaceArr;
|
||||||
RootObj;
|
RootObj; // xml node
|
||||||
NodeUri:string;
|
NodeUri:string;
|
||||||
children_;
|
children_;
|
||||||
End
|
End
|
||||||
|
|||||||
@@ -179,6 +179,33 @@ Type TOffice = Class
|
|||||||
return getTextBoxImpl(p, true);
|
return getTextBoxImpl(p, true);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///获取docx的类型
|
||||||
|
///普通段落:0
|
||||||
|
///图片段落:1
|
||||||
|
///表格:2
|
||||||
|
///其他:-1
|
||||||
|
Function GetDocxPartType(part);
|
||||||
|
Begin
|
||||||
|
if not ifObj(part) then return -1;
|
||||||
|
case part.name_ of
|
||||||
|
'w:p':
|
||||||
|
begin
|
||||||
|
if class(TSXml).GetNode(part.node_, 'w:r/w:drawing') then return 1;
|
||||||
|
return 0;
|
||||||
|
end
|
||||||
|
'w:tbl':
|
||||||
|
return 2;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
end;
|
||||||
|
End;
|
||||||
|
|
||||||
|
///单元格内的标题是否添加到目录
|
||||||
|
Function SetCellTableContent(flag);
|
||||||
|
Begin
|
||||||
|
hash_["CELLFLAG"] := flag;
|
||||||
|
End;
|
||||||
|
|
||||||
Function Set(k, v);
|
Function Set(k, v);
|
||||||
Begin
|
Begin
|
||||||
hash_[k] := v;
|
hash_[k] := v;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Function TOfficeInit();
|
||||||
|
Begin
|
||||||
|
sysparams['TOffice sys api'] := nil;
|
||||||
|
End;
|
||||||
@@ -71,12 +71,14 @@ Type TSImage = Class
|
|||||||
Begin
|
Begin
|
||||||
des1 := 0xff;
|
des1 := 0xff;
|
||||||
des2 := 0xc0;
|
des2 := 0xc0;
|
||||||
|
des3 := 0xc2;
|
||||||
flag := 1;
|
flag := 1;
|
||||||
while flag do
|
while flag do
|
||||||
begin
|
begin
|
||||||
stringObj_.Read(byte1, 1);
|
r1 := stringObj_.Read(byte1, 1);
|
||||||
stringObj_.Read(byte2, 1);
|
r2 := stringObj_.Read(byte2, 1);
|
||||||
if byte1 = des1 and byte2 = des2 then flag := 0;
|
if r1 = 0 or r2 = 0 then break;
|
||||||
|
if byte1 = des1 and (byte2 = des2 or byte2 = des3) then flag := 0;
|
||||||
end
|
end
|
||||||
if flag then return array(0, 0);
|
if flag then return array(0, 0);
|
||||||
stringObj_.Read(tmp, 3);
|
stringObj_.Read(tmp, 3);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -30,16 +30,16 @@ Type TDocxChart = Class(TSChart)
|
|||||||
Function GetInnerXml();
|
Function GetInnerXml();
|
||||||
Begin
|
Begin
|
||||||
ETU := 360045;//1cm单位
|
ETU := 360045;//1cm单位
|
||||||
return fmt('<w:r>
|
return format('<w:r>
|
||||||
<w:drawing>
|
<w:drawing>
|
||||||
<wp:inline>
|
<wp:inline>
|
||||||
<wp:extent cx="{}" cy="{}"/>
|
<wp:extent cx="%d" cy="%d"/>
|
||||||
<wp:effectExtent l="0" t="0" r="19050" b="19050"/>
|
<wp:effectExtent l="0" t="0" r="19050" b="19050"/>
|
||||||
<wp:docPr id="{}" name="{}"/>
|
<wp:docPr id="%d" name="%s"/>
|
||||||
<wp:cNvGraphicFramePr />
|
<wp:cNvGraphicFramePr />
|
||||||
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
|
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
|
||||||
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">
|
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">
|
||||||
<c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId{}"/>
|
<c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId%d"/>
|
||||||
</a:graphicData>
|
</a:graphicData>
|
||||||
</a:graphic>
|
</a:graphic>
|
||||||
</wp:inline>
|
</wp:inline>
|
||||||
@@ -52,7 +52,7 @@ Type TDocxChart = Class(TSChart)
|
|||||||
return true;
|
return true;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
docx_;
|
[weakref]docx_;
|
||||||
chartId_;
|
chartId_;
|
||||||
rId_;
|
rId_;
|
||||||
xmlObj_;
|
xmlObj_;
|
||||||
|
|||||||
@@ -0,0 +1,625 @@
|
|||||||
|
Type TDocxCopy = class
|
||||||
|
|
||||||
|
Function Create(oldObj, newObj)
|
||||||
|
Begin
|
||||||
|
old_docx_obj_ := oldObj;
|
||||||
|
new_docx_obj_ := newObj;
|
||||||
|
copy_table_ := array();
|
||||||
|
copy_paragraph_ := array();
|
||||||
|
copy_drawing_ := array();
|
||||||
|
style_copy_obj_ := new TDocxStyleCopy(oldObj.StyleObject(), newObj.StyleObject());
|
||||||
|
number_copy_obj_ := new TDocxNumberCopy(oldObj, newObj);
|
||||||
|
footnote_copy_obj_ := new TDocxFootnoteCopy(oldObj, newObj);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function Init();
|
||||||
|
Begin
|
||||||
|
style_copy_obj_.Init();
|
||||||
|
End;
|
||||||
|
|
||||||
|
///从posOpt位置开始复制word
|
||||||
|
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
|
||||||
|
Function Copy(posOpt);
|
||||||
|
Begin
|
||||||
|
// 复制所有的样式
|
||||||
|
style_copy_obj_.CopyStyle(number_copy_obj_);
|
||||||
|
|
||||||
|
parts := new_docx_obj_.Body().Parts();
|
||||||
|
pos := old_docx_obj_.GetPosNode(posOpt);
|
||||||
|
for i:=0 to length(parts)-1 do
|
||||||
|
begin
|
||||||
|
case GetPartType(parts[i]) of
|
||||||
|
0: pos := CopyParagraph(parts[i], pos);
|
||||||
|
1: pos := CopyDrawing(parts[i], pos);
|
||||||
|
2: pos := CopyTable(parts[i], pos);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyParagraph(obj, pos);
|
||||||
|
Begin
|
||||||
|
paragraph := old_docx_obj_.Body().CopyWp(obj, pos);
|
||||||
|
SetParagraphInfo(paragraph);
|
||||||
|
copy_paragraph_[length(copy_paragraph_)] := paragraph;
|
||||||
|
return paragraph;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyDrawing(obj, pos);
|
||||||
|
Begin
|
||||||
|
paragraph := old_docx_obj_.Body().CopyWp(obj, pos);
|
||||||
|
SetDrawingInfo(paragraph);
|
||||||
|
copy_drawing_[length(copy_drawing_)] := paragraph;
|
||||||
|
return paragraph;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyTable(obj, pos);
|
||||||
|
Begin
|
||||||
|
table := old_docx_obj_.Body().CopyWtbl(obj, pos);
|
||||||
|
SetTableInfo(table);
|
||||||
|
copy_table_[length(copy_table_)] := table;
|
||||||
|
return table;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetCopiedTable();
|
||||||
|
Begin
|
||||||
|
return copy_table_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetCopiedParagraph();
|
||||||
|
Begin
|
||||||
|
return copy_paragraph_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetCopiedDrawing();
|
||||||
|
Begin
|
||||||
|
return copy_drawing_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
Function DeleteComment(paragraph);
|
||||||
|
Begin
|
||||||
|
node := paragraph.node_.FirstChildElement('w:commentRangeStart');
|
||||||
|
while ifObj(node) do
|
||||||
|
begin
|
||||||
|
name := node.GetName();
|
||||||
|
if name = "w:commentRangeStart" or name = "w:commentRangeEnd" then
|
||||||
|
begin
|
||||||
|
delete_node := node;
|
||||||
|
node := node.NextElement();
|
||||||
|
paragraph.node_.DeleteChild(delete_node);
|
||||||
|
if node.FirstChildElement('w:commentReference') then
|
||||||
|
begin
|
||||||
|
delete_node := node;
|
||||||
|
node := node.NextElement();
|
||||||
|
paragraph.node_.DeleteChild(delete_node);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
node := node.NextElement();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetRObject(node);
|
||||||
|
Begin
|
||||||
|
image_data_node := class(TSXml).GetNode(node, 'v:shape/v:imagedata');
|
||||||
|
if not ifObj(node) then return;
|
||||||
|
rid := image_data_node.GetAttribute('r:id');
|
||||||
|
id := CopyRidContent(rid, 'media/image', 'image');
|
||||||
|
if id then image_data_node.SetAttribute('r:id', 'rId' $ id);
|
||||||
|
ole_node := class(TSXml).GetNode(node, 'o:OLEObject');
|
||||||
|
if not ifObj(node) then return;
|
||||||
|
rid := ole_node.GetAttribute('r:id');
|
||||||
|
id := CopyRidContent(rid, 'embeddings/oleObject', 'oleObject');
|
||||||
|
if id then ole_node.SetAttribute('r:id', 'rId' $ id);
|
||||||
|
End;
|
||||||
|
|
||||||
|
function CopyRidContent(id, tar_prefix, type_postfix);
|
||||||
|
begin
|
||||||
|
rels := new_docx_obj_.Zip().Get('word/_rels/document.xml.rels');
|
||||||
|
target := class(TSXml).FindRelationshipTarget(rels, id);
|
||||||
|
image_file := new_docx_obj_.Zip().Get('word/' $ target).Data();
|
||||||
|
|
||||||
|
// 比较新文件的图片在旧文件中是否存在
|
||||||
|
zip := old_docx_obj_.Zip();
|
||||||
|
xml := zip.Get('word/_rels/document.xml.rels');
|
||||||
|
files := sselect ['FileName'] from zip.Files() where AnsiStartsText('word/' $ tar_prefix, ['FileName']) end;
|
||||||
|
for i:=0 to length(files)-1 do Begin
|
||||||
|
if zip.Diff(files[i], image_file) = 0 then Begin
|
||||||
|
prefix := ReplaceStr(files[i], 'word/', '');
|
||||||
|
[maxRid, imageFile, rid] := class(TSXml).FindRelationshipRid(xml, prefix);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
if rid = 0 then
|
||||||
|
begin
|
||||||
|
image_cnt := length(files) + 1;
|
||||||
|
if ParseRegExpr("\\w+$", target, "", result, Mpos, Mlen) then
|
||||||
|
begin
|
||||||
|
postfix := result[0][0];
|
||||||
|
image_path := tar_prefix $ image_cnt $ '.' $ postfix;
|
||||||
|
[rid, tar] := class(TSXml).FindRelationshipRid(xml, '');
|
||||||
|
rid ++;
|
||||||
|
class(TSXml).AddRelationshipRid(xml, image_path, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/' $ type_postfix, 'rId' $ rid);
|
||||||
|
zip.Add('word/' + image_path, image_file);
|
||||||
|
contentXml := zip.Get('[Content_Types].xml');
|
||||||
|
if postfix = 'wmf' then content_type := 'image/x-wmf';
|
||||||
|
else if postfix = 'bin' then content_type := 'application/vnd.openxmlformats-officedocument.oleObject';
|
||||||
|
class(TSXml).AddDefaultContentType(contentXml, postfix, content_type);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return rid;
|
||||||
|
end;
|
||||||
|
|
||||||
|
Function SetPic(node);
|
||||||
|
Begin
|
||||||
|
// 获取新文件的图片
|
||||||
|
rembed := node.GetAttribute('r:embed');
|
||||||
|
rels := new_docx_obj_.Zip().Get('word/_rels/document.xml.rels');
|
||||||
|
target := class(TSXml).FindRelationshipTarget(rels, rembed);
|
||||||
|
image_file := new_docx_obj_.Zip().Get('word/' $ target).Data();
|
||||||
|
|
||||||
|
// 比较新文件的图片在旧文件中是否存在
|
||||||
|
zip := old_docx_obj_.Zip();
|
||||||
|
xml := zip.Get('word/_rels/document.xml.rels');
|
||||||
|
files := sselect ['FileName'] from zip.Files() where AnsiStartsText('word/media/image', ['FileName']) end;
|
||||||
|
for i:=0 to length(files)-1 do Begin
|
||||||
|
if zip.Diff(files[i], image_file) = 0 then Begin
|
||||||
|
prefix := ReplaceStr(files[i], 'word/', '');
|
||||||
|
[maxRid, imageFile, rid] := class(TSXml).FindRelationshipRid(xml, prefix);
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
if rid = 0 then
|
||||||
|
begin
|
||||||
|
image_cnt := length(files) + 1;
|
||||||
|
if ParseRegExpr("\\w+$", target, "", result, Mpos, Mlen) then
|
||||||
|
begin
|
||||||
|
postfix := result[0][0];
|
||||||
|
image_path := "media/image" $ image_cnt $ '.' $ postfix;
|
||||||
|
[rid, tar] := class(TSXml).FindRelationshipRid(xml, '');
|
||||||
|
rid ++;
|
||||||
|
class(TSXml).AddRelationshipRid(xml, image_path, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid);
|
||||||
|
zip.Add('word/' + image_path, image_file);
|
||||||
|
contentXml := zip.Get('[Content_Types].xml');
|
||||||
|
class(TSXml).AddDefaultContentType(contentXml, postfix, 'image/' $ postfix);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
node.SetAttribute('r:embed', 'rId' $ rid);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetChart(node);
|
||||||
|
Begin
|
||||||
|
rid := node.GetAttribute('r:id');
|
||||||
|
rels := new_docx_obj_.Zip().Get('word/_rels/document.xml.rels');
|
||||||
|
target := class(TSXml).FindRelationshipTarget(rels, rid);
|
||||||
|
new_zip := new_docx_obj_.Zip();
|
||||||
|
chart_file := new_zip.Get('word/' $ target);
|
||||||
|
|
||||||
|
// 复制charN.xml
|
||||||
|
zip := old_docx_obj_.Zip();
|
||||||
|
files := sselect ['FileName'] from zip.Files() where AnsiStartsText('word/charts/chart', ['FileName']) end;
|
||||||
|
new_chart_file := "charts/chart" $ (length(files) + 1) $ ".xml";
|
||||||
|
xml := zip.Get('word/_rels/document.xml.rels');
|
||||||
|
[new_rid, tar] := class(TSXml).FindRelationshipRid(xml, '');
|
||||||
|
new_rid++;
|
||||||
|
class(TSXml).AddRelationshipRid(xml, new_chart_file, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", 'rId' $ new_rid);
|
||||||
|
zip.Add('word/' + new_chart_file, chart_file.Data());
|
||||||
|
contentXml := zip.Get('[Content_Types].xml');
|
||||||
|
class(TSXml).AddOverrideContentType(contentXml, '/word/' + new_chart_file, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
|
||||||
|
node.SetAttribute('r:id', 'rId' $ new_rid);
|
||||||
|
|
||||||
|
// 复制charN.xml.rels
|
||||||
|
chart_rels := "word/charts/_rels" + target[pos('/', target):] $ ".rels";
|
||||||
|
chart_rels_xml := new_zip.Get(chart_rels);
|
||||||
|
if ifObj(chart_rels_xml) then
|
||||||
|
begin
|
||||||
|
zip.Add('word/charts/_rels/chart' $ (length(files) + 1) $ ".xml.rels", chart_rels_xml.Data());
|
||||||
|
relationship := chart_rels_xml.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||||||
|
while ifObj(relationship) do
|
||||||
|
begin
|
||||||
|
target := relationship.GetAttribute('Target');
|
||||||
|
target_path := AnsiReplaceText(target, '..', 'word');
|
||||||
|
file := new_zip.Get(target_path);
|
||||||
|
if ifObj(file) then
|
||||||
|
begin
|
||||||
|
[new_file, filetype] := GetNewTargetFileName(zip, target_path);
|
||||||
|
zip.Add(new_file, file.Data());
|
||||||
|
if filetype then Class(TSXml).AddDefaultContentType(contentXml, filetype[2:], 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
|
||||||
|
end
|
||||||
|
relationship := relationship.NextElement();
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetNewTargetFileName(zip, fileName);
|
||||||
|
Begin
|
||||||
|
files := zip.Files()[:, 'FileName'];
|
||||||
|
ret := ParseRegExpr("(.*/)(\\w+)(\.\\w+)$", fileName, "", result, Mpos, Mlen);
|
||||||
|
count := 0;
|
||||||
|
while fileName in files do
|
||||||
|
begin
|
||||||
|
if ret then
|
||||||
|
fileName := result[0][1] $ result[0][2] $ "tinysoft" $ count $ result[0][3];
|
||||||
|
else fileName := fileName $ "tinysoft" $ count;
|
||||||
|
count++;
|
||||||
|
end
|
||||||
|
if ret then filetype := result[0][3];
|
||||||
|
return array(fileName, filetype);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetDrawingInfo(drawing);
|
||||||
|
Begin
|
||||||
|
drawing_node := GetDrawingNode(drawing.node_);
|
||||||
|
graphic_node := class(TSXml).GetNode(drawing_node,'wp:inline/a:graphic/a:graphicData');
|
||||||
|
// graphic_node := class(TSXml).GetNode(drawing.node_,'w:r/w:drawing/wp:inline/a:graphic/a:graphicData');
|
||||||
|
if ifObj(graphic_node) then
|
||||||
|
begin
|
||||||
|
node := class(TSXml).GetNode(graphic_node,'pic:pic/pic:blipFill/a:blip');
|
||||||
|
if ifObj(node) then SetPic(node);
|
||||||
|
node := class(TSXml).GetNode(graphic_node, 'c:chart');
|
||||||
|
if ifObj(node) then SetChart(node);
|
||||||
|
end;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetParagraphInfo(paragraph);
|
||||||
|
Begin
|
||||||
|
CopyStyle(paragraph.node_, 'w:pPr/w:pStyle');
|
||||||
|
CopyNumber(paragraph.node_, 'w:pPr/w:numPr/w:numId');
|
||||||
|
SetRunsInfo(paragraph.node_);
|
||||||
|
DeleteComment(paragraph); // 删除批注
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetRunsInfo(node);
|
||||||
|
Begin
|
||||||
|
run := node.FirstChildElement('w:r');
|
||||||
|
while ifObj(run) do
|
||||||
|
begin
|
||||||
|
CopyFootnote(run);
|
||||||
|
CopyStyle(run, 'w:rPr/w:rStyle');
|
||||||
|
obj_node := class(TSXml).GetNode(run, 'w:object');
|
||||||
|
if ifObj(obj_node) then
|
||||||
|
SetRObject(obj_node);
|
||||||
|
run := run.NextElement();
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyStyle(node, path);
|
||||||
|
Begin
|
||||||
|
style := class(TSXml).GetNode(node, path);
|
||||||
|
if ifObj(style) then
|
||||||
|
begin
|
||||||
|
styleid := style.GetAttribute('w:val');
|
||||||
|
new_id := style_copy_obj_.GetStyleNewId(styleid);
|
||||||
|
if new_id then style.SetAttribute('w:val', new_id);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyNumber(node, path);
|
||||||
|
Begin
|
||||||
|
numpr := class(TSXml).GetNode(node, path);
|
||||||
|
if ifObj(numpr) then
|
||||||
|
begin
|
||||||
|
id := numpr.GetAttribute('w:val');
|
||||||
|
numberid := number_copy_obj_.CopyNumbering(id);
|
||||||
|
numpr.SetAttribute('w:val', numberid);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyFootnote(node);
|
||||||
|
Begin
|
||||||
|
footnote := node.FirstChildElement('w:footnoteReference');
|
||||||
|
if not ifObj(footnote) then return;
|
||||||
|
id := footnote.GetAttribute('w:id');
|
||||||
|
if id then
|
||||||
|
begin
|
||||||
|
obj := footnote_copy_obj_.CopyFootnote(id);
|
||||||
|
footnote.SetAttribute('w:id', obj.Id);
|
||||||
|
parts := obj.Parts();
|
||||||
|
for i:=0 to length(parts)-1 do
|
||||||
|
begin
|
||||||
|
case GetPartType(parts[i]) of
|
||||||
|
0: SetParagraphInfo(parts[i]);
|
||||||
|
1: SetDrawingInfo(parts[i]);
|
||||||
|
2: SetTableInfo(parts[i]);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetTableInfo(table);
|
||||||
|
Begin
|
||||||
|
style := class(TSXml).GetNode(table.node_, 'w:tblPr/w:tblStyle');
|
||||||
|
if ifObj(style) then
|
||||||
|
begin
|
||||||
|
id := style.GetAttribute('w:val');
|
||||||
|
new_id := style_copy_obj_.GetStyleNewId(id);
|
||||||
|
if new_id then style.SetAttribute('w:val', new_id);
|
||||||
|
end
|
||||||
|
col := table.Cols();
|
||||||
|
row := table.Rows();
|
||||||
|
for r:=1 to row do
|
||||||
|
begin
|
||||||
|
for c:=1 to col do
|
||||||
|
begin
|
||||||
|
cell := table.Cell(r, c);
|
||||||
|
if not cell then continue;
|
||||||
|
node := cell.node_.FirstChildElement();
|
||||||
|
while ifObj(node) do
|
||||||
|
begin
|
||||||
|
name := node.GetName();
|
||||||
|
if name = 'w:tbl' then
|
||||||
|
begin
|
||||||
|
obj := TOfficeObj('TTable');
|
||||||
|
obj.Init(node);
|
||||||
|
SetTableInfo(obj);
|
||||||
|
end
|
||||||
|
else if name = "w:p" then
|
||||||
|
begin
|
||||||
|
// draw := class(TSXml).GetNode(node, 'w:r/w:drawing');
|
||||||
|
draw := GetDrawingNode(node);
|
||||||
|
if ifObj(draw) then
|
||||||
|
begin
|
||||||
|
obj := TOfficeObj('TPicture');
|
||||||
|
obj.Init(node);
|
||||||
|
SetDrawingInfo(obj);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
obj := TOfficeObj('TParagraph');
|
||||||
|
obj.Init(node);
|
||||||
|
SetParagraphInfo(obj);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
node := node.NextElement();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
/// 普通段落: 0
|
||||||
|
/// 图片段落: 1
|
||||||
|
/// 表格: 2
|
||||||
|
/// 其他类型暂不复制
|
||||||
|
Function GetPartType(part);
|
||||||
|
Begin
|
||||||
|
name := part.name_;
|
||||||
|
case name of
|
||||||
|
'w:p':
|
||||||
|
begin
|
||||||
|
if GetDrawingNode(part.node_) then return 1;
|
||||||
|
if class(TSXml).GetNode(part.node_, 'w:r/w:drawing') then return 1;
|
||||||
|
return 0;
|
||||||
|
end
|
||||||
|
'w:tbl':
|
||||||
|
return 2;
|
||||||
|
else
|
||||||
|
return -1;
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
function GetDrawingNode(node);
|
||||||
|
begin
|
||||||
|
r_node := node.FirstChild('w:r');
|
||||||
|
while ifObj(r_node) do
|
||||||
|
begin
|
||||||
|
sub_node := r_node.FirstChild();
|
||||||
|
sub_node_name := sub_node.GetName();
|
||||||
|
if sub_node_name = 'w:rPr' then
|
||||||
|
begin
|
||||||
|
sub_node := sub_node.NextElement();
|
||||||
|
sub_node_name := sub_node.GetName();
|
||||||
|
end
|
||||||
|
if sub_node_name = 'w:drawing' then return sub_node;
|
||||||
|
if sub_node_name = 'w:t' and sub_node.GetAttribute('xml:space') = 'preserve' then
|
||||||
|
r_node := r_node.NextElement();
|
||||||
|
else break;
|
||||||
|
end
|
||||||
|
return nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
private
|
||||||
|
old_docx_obj_;
|
||||||
|
new_docx_obj_;
|
||||||
|
style_copy_obj_;
|
||||||
|
number_copy_obj_;
|
||||||
|
footnote_copy_obj_;
|
||||||
|
|
||||||
|
copy_table_;
|
||||||
|
copy_paragraph_;
|
||||||
|
copy_drawing_;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Type TDocxStyleCopy = class
|
||||||
|
|
||||||
|
Function Create(oldObj, newObj);
|
||||||
|
Begin
|
||||||
|
old_style_obj_ := oldObj;
|
||||||
|
new_style_obj_ := newObj;
|
||||||
|
style_id_map_ := array();
|
||||||
|
style_name_map_ := array();
|
||||||
|
style_id_map2_ := array();
|
||||||
|
style_name_map2_ := array();
|
||||||
|
id_map_ := array();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function Init();
|
||||||
|
Begin
|
||||||
|
id_styles := new_style_obj_.Styles();
|
||||||
|
for id, obj in id_styles do
|
||||||
|
begin
|
||||||
|
new_obj := obj;
|
||||||
|
id_map_[id] := new_obj;
|
||||||
|
SetId(new_obj, id);
|
||||||
|
SetName(new_obj);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyStyle(numberobj);
|
||||||
|
Begin
|
||||||
|
for id, obj in id_map_ do
|
||||||
|
begin
|
||||||
|
SetBasedOn(obj);
|
||||||
|
SetNumId(obj, numberobj);
|
||||||
|
SetLink(obj);
|
||||||
|
old_style_obj_.CopyStyle(obj);
|
||||||
|
end;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetStyleNewId(oldId)
|
||||||
|
Begin
|
||||||
|
if ifnumber(oldId) then oldId := tostring(oldId);
|
||||||
|
return style_id_map_[oldId];
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
Function SetId(obj, id);
|
||||||
|
Begin
|
||||||
|
new_id := GetNewId(id);
|
||||||
|
obj.node_.SetAttribute('w:styleId', new_id);
|
||||||
|
style_id_map_[id] := new_id;
|
||||||
|
style_id_map2_[new_id] := id;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetName(obj);
|
||||||
|
Begin
|
||||||
|
name_node := obj.node_.FirstChildElement('w:name');
|
||||||
|
name := name_node.GetAttribute('w:val');
|
||||||
|
new_name := GetNewName(name);
|
||||||
|
name_node.SetAttribute('w:val', new_name);
|
||||||
|
style_name_map_[name] := new_name;
|
||||||
|
style_name_map2_[new_name] := name;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetBasedOn(obj);
|
||||||
|
Begin
|
||||||
|
basedon := obj.node_.FirstChildElement('w:basedOn');
|
||||||
|
if ifObj(basedon) then
|
||||||
|
begin
|
||||||
|
val := basedon.GetAttribute('w:val');
|
||||||
|
if style_id_map_[val] then basedOn.SetAttribute('w:val', style_id_map_[val]);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetLink(obj);
|
||||||
|
Begin
|
||||||
|
link := obj.node_.FirstChildElement('w:link');
|
||||||
|
if ifObj(link) then
|
||||||
|
begin
|
||||||
|
val := link.GetAttribute('w:val');
|
||||||
|
if style_id_map_[val] then link.SetAttribute('w:val', style_id_map_[val]);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetNumId(obj, numberobj);
|
||||||
|
Begin
|
||||||
|
if not ifObj(numberobj) then return;
|
||||||
|
numPr := class(TSXml).GetNode(obj.node_, 'w:pPr/w:numPr/w:numId');
|
||||||
|
if ifObj(numPr) then
|
||||||
|
begin
|
||||||
|
id := numpr.GetAttribute('w:val');
|
||||||
|
numberid := numberobj.CopyNumbering(id);
|
||||||
|
numpr.SetAttribute('w:val', numberid);
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetNewName(name);
|
||||||
|
Begin
|
||||||
|
new_name := name;
|
||||||
|
while ifObj(old_style_obj_.GetStyle(class(TSXml).Utf8ToCurCodePage(new_name))) or style_name_map2_[new_name] do
|
||||||
|
new_name := new_name $ crc32(inttostr(random(2000000)));
|
||||||
|
return new_name;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetNewId(id);
|
||||||
|
Begin
|
||||||
|
new_id := id;
|
||||||
|
while ifObj(old_style_obj_.GetStyleById(new_id)) or style_id_map2_[new_id] do
|
||||||
|
new_id := new_id $ crc32(inttostr(random(2000000)));
|
||||||
|
return new_id;
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
old_style_obj_;
|
||||||
|
new_style_obj_;
|
||||||
|
|
||||||
|
style_id_map_; // [old_id: new_id];
|
||||||
|
style_name_map_; // [old_name: new_name];
|
||||||
|
style_id_map2_; // [new_id: old_id];
|
||||||
|
style_name_map2_; // [old_name: new_name];
|
||||||
|
|
||||||
|
id_map_; // [id: styleobj]
|
||||||
|
End;
|
||||||
|
|
||||||
|
Type TDocxNumberCopy = class
|
||||||
|
|
||||||
|
Function Create(oldObj, newObj);
|
||||||
|
Begin
|
||||||
|
numberingxml := newObj.Zip().Get('word/numbering.xml');
|
||||||
|
if ifObj(numberingxml) then
|
||||||
|
begin
|
||||||
|
old_number_obj_ := oldObj.NumberingObject();
|
||||||
|
new_number_obj_ := newObj.NumberingObject();
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
old_number_obj_ := nil;
|
||||||
|
new_number_obj_ := nil;
|
||||||
|
end
|
||||||
|
id_map_ := array();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyNumbering(number);
|
||||||
|
Begin
|
||||||
|
if ifObj(old_number_obj_) and ifObj(new_number_obj_) then
|
||||||
|
begin
|
||||||
|
if (obj := new_number_obj_.NumberStyle(number)) and not id_map_[number] then
|
||||||
|
begin
|
||||||
|
number_obj := old_number_obj_.CopyNumber(obj);
|
||||||
|
id_map_[number] := number_obj;
|
||||||
|
end
|
||||||
|
return id_map_[number];
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
old_number_obj_;
|
||||||
|
new_number_obj_;
|
||||||
|
|
||||||
|
id_map_; // [id: styleobj]
|
||||||
|
End;
|
||||||
|
|
||||||
|
Type TDocxFootnoteCopy = class
|
||||||
|
|
||||||
|
Function Create(oldObj, newObj);
|
||||||
|
Begin
|
||||||
|
footnotexml := newObj.Zip().Get('word/footnotes.xml');
|
||||||
|
if ifObj(footnotexml) then
|
||||||
|
begin
|
||||||
|
old_footnote_obj_ := oldObj.FootNotesObject();
|
||||||
|
new_footnote_obj_ := newObj.FootNotesObject();
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
old_footnote_obj_ := nil;
|
||||||
|
new_footnote_obj_ := nil;
|
||||||
|
end
|
||||||
|
id_map_ := array();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function CopyFootnote(id);
|
||||||
|
Begin
|
||||||
|
if ifObj(old_footnote_obj_) and ifObj(new_footnote_obj_) then
|
||||||
|
begin
|
||||||
|
if (obj := new_footnote_obj_.GetFootnote(id)) and not id_map_[id] then
|
||||||
|
begin
|
||||||
|
footnote_obj := old_footnote_obj_.CopyFootnote(obj);
|
||||||
|
id_map_[id] := footnote_obj;
|
||||||
|
end
|
||||||
|
return id_map_[id];
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
private
|
||||||
|
[weakref]old_footnote_obj_;
|
||||||
|
new_footnote_obj_;
|
||||||
|
|
||||||
|
id_map_; // [id: footnote]
|
||||||
|
End;
|
||||||
@@ -52,7 +52,7 @@ Type TDocxStyles = Class
|
|||||||
///返回:TDocxStyle对象
|
///返回:TDocxStyle对象
|
||||||
Function GetStyle(name);
|
Function GetStyle(name);
|
||||||
Begin
|
Begin
|
||||||
return nameMap_[ lowercase(name) ];
|
return nameMap_[ class(TSXml).CurCodePageToUtf8(lowercase(name)) ];
|
||||||
End;
|
End;
|
||||||
|
|
||||||
///返回指定StyleId名称的TDocxStyle
|
///返回指定StyleId名称的TDocxStyle
|
||||||
@@ -60,7 +60,8 @@ Type TDocxStyles = Class
|
|||||||
///返回:TDocxStyle对象
|
///返回:TDocxStyle对象
|
||||||
Function GetStyleById(id);
|
Function GetStyleById(id);
|
||||||
Begin
|
Begin
|
||||||
return idMap_[ id ];
|
newid := ifnumber(id) ? tostring(id) : id;
|
||||||
|
return idMap_[ newid ];
|
||||||
End;
|
End;
|
||||||
|
|
||||||
//返回全部LatentStyles对象列表
|
//返回全部LatentStyles对象列表
|
||||||
@@ -133,6 +134,24 @@ Type TDocxStyles = Class
|
|||||||
return nil;
|
return nil;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///复制样式
|
||||||
|
///newstyle:样式节点TDocxStyle对象
|
||||||
|
///返回:TDocxStyle对象
|
||||||
|
Function CopyStyle(newstyle);
|
||||||
|
Begin
|
||||||
|
if ifObj(newstyle) and ifObj(newstyle.node_) then Begin
|
||||||
|
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(newstyle.node_.Marshal()[0]);
|
||||||
|
node.DeleteAttribute('w:default');
|
||||||
|
obj := TOfficeObj('TDocxStyle');
|
||||||
|
obj.StyleId := node.GetAttribute('w:styleId');
|
||||||
|
obj.Name := node.FirstChildElement('w:name').GetAttribute('w:val');
|
||||||
|
obj.Init(node);
|
||||||
|
_addStyle(obj);
|
||||||
|
return obj;
|
||||||
|
End;
|
||||||
|
return nil;
|
||||||
|
End;
|
||||||
|
|
||||||
///插入新的LatentStyle段落样式
|
///插入新的LatentStyle段落样式
|
||||||
///o:TDocxStyle对象
|
///o:TDocxStyle对象
|
||||||
///返回:TDocxStyle对象
|
///返回:TDocxStyle对象
|
||||||
@@ -180,7 +199,7 @@ Type TDocxStyles = Class
|
|||||||
defaultPpr_;
|
defaultPpr_;
|
||||||
defaultRpr_;
|
defaultRpr_;
|
||||||
private
|
private
|
||||||
docx_;
|
[weakref]docx_;
|
||||||
stylesXml_;
|
stylesXml_;
|
||||||
idMap_;
|
idMap_;
|
||||||
nameMap_;
|
nameMap_;
|
||||||
|
|||||||
@@ -77,6 +77,19 @@ Type TNumbering = Class
|
|||||||
return num.numId;
|
return num.numId;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
///复制number样式
|
||||||
|
///numberObj: 样式xmlNode
|
||||||
|
Function CopyNumber(numberObj);
|
||||||
|
Begin
|
||||||
|
obj := AddStyle(numberObj, true);
|
||||||
|
num := TOfficeObj('TNumber');
|
||||||
|
num.numId := maxNumId_++;
|
||||||
|
num.abstractNumId := obj.Id;
|
||||||
|
numberingXml_.FirstChildElement('w:numbering').InsertEndChild(num.Marshal());
|
||||||
|
numIdMap_[''$num.numId] := num.abstractNumId;
|
||||||
|
return num.numId;
|
||||||
|
End;
|
||||||
|
|
||||||
///根据numId获取TNumStyle对象(已存在)
|
///根据numId获取TNumStyle对象(已存在)
|
||||||
///返回:TNumStyle对象
|
///返回:TNumStyle对象
|
||||||
Function NumberStyle(numId);overload;
|
Function NumberStyle(numId);overload;
|
||||||
@@ -148,14 +161,20 @@ Type TNumbering = Class
|
|||||||
///新添加项目样式
|
///新添加项目样式
|
||||||
///o:TNumStyle对象
|
///o:TNumStyle对象
|
||||||
///返回:TNumStyle对象
|
///返回:TNumStyle对象
|
||||||
Function AddStyle(o);
|
Function AddStyle(o, flag);
|
||||||
Begin
|
Begin
|
||||||
if ifObj(o) then Begin
|
if ifObj(o) then Begin
|
||||||
o.abstractNumId := maxAbstractNumId_++;
|
o.abstractNumId := maxAbstractNumId_++;
|
||||||
|
if flag then
|
||||||
|
begin
|
||||||
|
o.node_.SetAttribute('w:abstractNumId', o.abstractNumId);
|
||||||
|
marshal := o.node_.Marshal()[0];
|
||||||
|
end
|
||||||
|
else marshal := o.Marshal();
|
||||||
if ifObj(lastAbstractNumStyle_) then
|
if ifObj(lastAbstractNumStyle_) then
|
||||||
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, o.Marshal());
|
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, marshal);
|
||||||
else
|
else
|
||||||
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(o.Marshal());
|
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(marshal);
|
||||||
lastAbstractNumStyle_ := node;
|
lastAbstractNumStyle_ := node;
|
||||||
o := TOfficeObj('TNumStyle');
|
o := TOfficeObj('TNumStyle');
|
||||||
o.Init(node);
|
o.Init(node);
|
||||||
@@ -209,7 +228,7 @@ Type TNumbering = Class
|
|||||||
class(TSXml).UpdateNode(o.node_, arr['attributes'], arr['children']);
|
class(TSXml).UpdateNode(o.node_, arr['attributes'], arr['children']);
|
||||||
End;
|
End;
|
||||||
private
|
private
|
||||||
docx_;
|
[weakref]docx_;
|
||||||
numberingXml_;
|
numberingXml_;
|
||||||
maxAbstractNumId_:integer;
|
maxAbstractNumId_:integer;
|
||||||
maxNumId_:integer;
|
maxNumId_:integer;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ Type TSTag = Class
|
|||||||
Begin
|
Begin
|
||||||
if not ifArray(map_) then Begin
|
if not ifArray(map_) then Begin
|
||||||
map_ := array();
|
map_ := array();
|
||||||
println('attribute={}',attribute_);
|
//println('attribute={}',attribute_);
|
||||||
arr := Str2Array(attribute_, ' ');
|
arr := Str2Array(attribute_, ' ');
|
||||||
for i := 0 to length(arr)-1 do Begin
|
for i := 0 to length(arr)-1 do Begin
|
||||||
kv := Str2Array(arr[i], '=');
|
kv := Str2Array(arr[i], '=');
|
||||||
|
|||||||
@@ -0,0 +1,297 @@
|
|||||||
|
Unit TSWordTemplateMethods;
|
||||||
|
Interface
|
||||||
|
Function ExcelChartCopyPic(excelFileName, excelSheetName, chartName, width, height);
|
||||||
|
Function WordAddOleObjectFromFile(fileName, width, height);
|
||||||
|
Function WordBr();
|
||||||
|
Function WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
|
||||||
|
Function WordGetCurrentDocument();
|
||||||
|
Function WordGetCurrentRange();
|
||||||
|
Function WordGetFont(prop, value);
|
||||||
|
Function WordGetLastRange();
|
||||||
|
Function WordGetLastShape();
|
||||||
|
Function WordGetLastTable();
|
||||||
|
Function WordGetLastTableCellProp(row, col, name, value);
|
||||||
|
Function WordGetLastTableProp(name, value);
|
||||||
|
Function WordLastTableMerge(row1, col1, row2, col2);
|
||||||
|
Function WordSetCurrentRange(range);
|
||||||
|
Function WordSetFont(prop, value);
|
||||||
|
Function WordSetLastTableCellProp(row, col, name, value);
|
||||||
|
Function WordSetLastTableProp(name, value);
|
||||||
|
Function WordSetRangeProp(name, value);
|
||||||
|
Function WordTemplate(data, template, fileName);
|
||||||
|
Function WordWrite();
|
||||||
|
Function WordWritePicFromFile(fileName);
|
||||||
|
Function WordWriteTable(table, writeIntIndex, writeIntTitle, incIntIndex);
|
||||||
|
|
||||||
|
Implementation
|
||||||
|
Function ExcelChartCopyPic(excelFileName, excelSheetName, chartName, width, height);
|
||||||
|
Begin
|
||||||
|
docx := TOfficeApi().GetDocument();
|
||||||
|
chart := docx.CopyExcelChart(excelFileName, excelSheetName, chartName, width, height, TOfficeApi().GetCurrentPosition());
|
||||||
|
return ifObj(chart);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordBr();
|
||||||
|
Begin
|
||||||
|
TOfficeApi().GetDocument().AddLineBreak(TOfficeApi().Get('CurrentPosition'));
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
|
||||||
|
Begin
|
||||||
|
excel := new TSXlsFile();
|
||||||
|
[err, msg] := excel.OpenFile('', excelFileName);
|
||||||
|
if err then return false;
|
||||||
|
total_row := excel.TotalRows(excelSheetName);
|
||||||
|
total_col := excel.TotalCols(excelSheetName);
|
||||||
|
if not total_row or not total_col then return false;
|
||||||
|
if ifnil(startRow) then
|
||||||
|
startRow := 1;
|
||||||
|
if ifnil(startCol) then
|
||||||
|
startCol := 1;
|
||||||
|
if ifnil(endRow) then
|
||||||
|
endRow := total_row;
|
||||||
|
if ifnil(endCol) then
|
||||||
|
endCol := total_col;
|
||||||
|
data := excel.GetTable(excelSheetName,
|
||||||
|
CoordinatesToCellName(startCol, startRow),
|
||||||
|
CoordinatesToCellName(endCol, endRow),
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false);
|
||||||
|
if length(data) = 0 then return false;
|
||||||
|
//println('data={}',data);
|
||||||
|
docx := TOfficeApi().GetDocument();
|
||||||
|
tbl := docx.CreateTable(data, false, false);
|
||||||
|
tbl.Format.Borders.Top.Val := 'dashed';
|
||||||
|
tbl.Format.Borders.Left.Val := 'dashed';
|
||||||
|
tbl.Format.Borders.Bottom.Val := 'dashed';
|
||||||
|
tbl.Format.Borders.Right.Val := 'dashed';
|
||||||
|
tbl.Format.Borders.InsideH.Val := 'dashed';
|
||||||
|
tbl.Format.Borders.InsideV.Val := 'dashed';
|
||||||
|
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetCurrentDocument();
|
||||||
|
Begin
|
||||||
|
return TOfficeApi().GetDocument();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetCurrentRange();
|
||||||
|
Begin
|
||||||
|
return TOfficeApi().GetCurrentPosition();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetFont(prop, value);
|
||||||
|
Begin
|
||||||
|
crun := TOfficeApi().GetCurrentRun();
|
||||||
|
node := crun.Node().FirstChildElement('w:rPr');
|
||||||
|
rPr := TOfficeObj('TwrPr');
|
||||||
|
rPr.InitRootNode(node);
|
||||||
|
value := rPr.Value(prop);
|
||||||
|
if not ifnil(value) then return true;
|
||||||
|
return false;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetLastShape();
|
||||||
|
Begin
|
||||||
|
node := TOfficeApi().Get('CurrentShape');
|
||||||
|
if not ifObj(node) then return nil;
|
||||||
|
uri := 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart';
|
||||||
|
cNode := class(TSXml).GetNode(node, uri);
|
||||||
|
if ifObj(cNode) then Begin
|
||||||
|
chart := TOfficeObj('TChart');
|
||||||
|
chart.Init(TOfficeApi().GetDocument(), node, cNode);
|
||||||
|
return chart;
|
||||||
|
End;
|
||||||
|
|
||||||
|
pic := TOfficeObj('TPicture');
|
||||||
|
pic.Init(node);
|
||||||
|
return pic;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetLastRange();
|
||||||
|
Begin
|
||||||
|
return TOfficeApi().GetCurrentPosition();
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetLastTable();
|
||||||
|
Begin
|
||||||
|
return TOfficeApi().Get('CurrentTable');
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetLastTableCellProp(row, col, name, value);
|
||||||
|
Begin
|
||||||
|
table_node := TOfficeApi().Get('CurrentTable');
|
||||||
|
if ifnil(table_node) then return false;
|
||||||
|
table := TOfficeObj("TTable");
|
||||||
|
table.Init(table_node);
|
||||||
|
table_cell := table.Cell(row, col);
|
||||||
|
ctr := _wordCompTable();
|
||||||
|
name_ := ctr[lowercase(name)];
|
||||||
|
if ifnil(name_) then name_ := name;
|
||||||
|
str := 'return table_cell.Format.' $ name_ $ '"' $ value $ '"';
|
||||||
|
value := eval(&str);
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordGetLastTableProp(name, value);
|
||||||
|
Begin
|
||||||
|
table_node := TOfficeApi().Get('CurrentTable');
|
||||||
|
if ifnil(table_node) then return false;
|
||||||
|
table := TOfficeObj("TTable");
|
||||||
|
table.Init(table_node);
|
||||||
|
ctr := _wordCompTable();
|
||||||
|
name_ := ctr[lowercase(name)];
|
||||||
|
if ifnil(name_) then name_ := name;
|
||||||
|
str := 'return table.Format.' $ name_ $ '"' $ value $ '"';
|
||||||
|
value := eval(&str);
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordLastTableMerge(row1, col1, row2, col2);
|
||||||
|
Begin
|
||||||
|
table_node := TOfficeApi().Get('CurrentTable');
|
||||||
|
if ifnil(table_node) then return false;
|
||||||
|
table := TOfficeObj("TTable");
|
||||||
|
table.Init(table_node);
|
||||||
|
[err1, beg_cell] := CoordinatesToCellName(col1, row1);
|
||||||
|
[err2, end_cell] := CoordinatesToCellName(col2, row2);
|
||||||
|
if err1 or err2 then return false;
|
||||||
|
table.Merge(beg_cell, end_cell, false);
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordSetCurrentRange(range);
|
||||||
|
Begin
|
||||||
|
TOfficeApi().Set('CurrentPosition', range);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordSetFont(prop, value);
|
||||||
|
Begin
|
||||||
|
run := TOfficeApi().GetCurrentRun();
|
||||||
|
str := 'run.font.' $ prop $ ' := ' $ '"' $ value $ '"';
|
||||||
|
eval(&str);
|
||||||
|
run.Apply();
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordSetLastTableCellProp(row, col, name, value);
|
||||||
|
Begin
|
||||||
|
table := TOfficeApi().Get('CurrentTable');
|
||||||
|
if ifnil(table) then return false;
|
||||||
|
table_cell := table.Cell(row, col);
|
||||||
|
ctr := _wordCompTable();
|
||||||
|
name_ := ctr[lowercase(name)];
|
||||||
|
if ifnil(name_) then name_ := name;
|
||||||
|
str := 'table_cell.Format.' $ name_ $ ' := ';
|
||||||
|
if ifstring(value) then
|
||||||
|
str += '"' $ value $ '"';
|
||||||
|
else
|
||||||
|
str := str $ value;
|
||||||
|
eval(&str);
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordSetLastTableProp(name, value);
|
||||||
|
Begin
|
||||||
|
table := TOfficeApi().Get('CurrentTable');
|
||||||
|
if ifnil(table) then return false;
|
||||||
|
ctr := _wordCompTable();
|
||||||
|
name_ := ctr[lowercase(name)];
|
||||||
|
if ifnil(name_) then name_ := name;
|
||||||
|
str := 'table.Format.' $ name_ $ ' := ';
|
||||||
|
if ifstring(value) then
|
||||||
|
str += '"' $ value $ '"';
|
||||||
|
else
|
||||||
|
str := str $ value;
|
||||||
|
eval(&str);
|
||||||
|
TOfficeApi().Set('CurrentTable', table);
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordSetRangeProp(name, value);
|
||||||
|
Begin
|
||||||
|
cur := TOfficeApi().GetCurrentPosition();
|
||||||
|
if ifnil(cur) then return nil;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordTemplate(data, template, fileName);
|
||||||
|
Begin
|
||||||
|
setsysparam('data', data);
|
||||||
|
docx := new TSDocxFile();
|
||||||
|
[err, msg] := docx.OpenFile('', template);
|
||||||
|
if err then return false;
|
||||||
|
docx.ExecInnerTSL();
|
||||||
|
if ifstring(fileName) then
|
||||||
|
begin
|
||||||
|
[err, msg] := docx.SaveAs('', fileName);
|
||||||
|
if err then return false;
|
||||||
|
end
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordWrite();
|
||||||
|
Begin
|
||||||
|
docx := TOfficeApi().GetDocument();
|
||||||
|
curParagraph := TOfficeApi().GetCurrentParagraph();
|
||||||
|
curRun := TOfficeApi().GetCurrentRun();
|
||||||
|
for i:=1 to PARAMCOUNT do Begin
|
||||||
|
argv := params[i];
|
||||||
|
if ifstring( argv ) then
|
||||||
|
curRun.AddText( argv );
|
||||||
|
else if ifnumber(argv) then
|
||||||
|
curRun.AddText('' $ argv);
|
||||||
|
else if ifarray(argv) then Begin
|
||||||
|
tbl := docx.CreateTable(argv, false, false);
|
||||||
|
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
|
||||||
|
End
|
||||||
|
End
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordWritePicFromFile(fileName);
|
||||||
|
Begin
|
||||||
|
file_size := fileSize('', fileName);
|
||||||
|
flag := readfile(rwbinary(), '', fileName, 0, file_size, data);
|
||||||
|
if not flag then return false;
|
||||||
|
picture := TOfficeObj('TPicture');
|
||||||
|
picture.Image := data;
|
||||||
|
docx := TOfficeApi().GetDocument();
|
||||||
|
docx.AddPicture(picture, TOfficeApi().GetCurrentPosition());
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function WordWriteTable(table, writeIntIndex, writeIntTitle, incIntIndex);
|
||||||
|
Begin
|
||||||
|
docx := TOfficeApi().GetDocument();
|
||||||
|
tbl := docx.CreateTable(table, true, writeIntIndex);
|
||||||
|
table := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
|
||||||
|
return true;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function _wordCompTable();
|
||||||
|
Begin
|
||||||
|
return array(
|
||||||
|
'alignment': 'Alignment',
|
||||||
|
'shadingcolor': 'Shading.Color',
|
||||||
|
'style': 'StyleID',
|
||||||
|
'verticalalignment': 'Valign',
|
||||||
|
'width': 'Width',
|
||||||
|
);
|
||||||
|
End;
|
||||||
|
|
||||||
|
// TODO:尚未支持
|
||||||
|
Function WordAddOleObjectFromFile(fileName, width, height);
|
||||||
|
Begin
|
||||||
|
End;
|
||||||
|
Function WordCopyPicFormatExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol, picType);
|
||||||
|
Begin
|
||||||
|
End;
|
||||||
|
Function WordGetRangeProp(name, value);
|
||||||
|
Begin
|
||||||
|
End;
|
||||||
|
Function WordLastTableSplit(row, col, rCnt, cCnt);
|
||||||
|
Begin
|
||||||
|
End;
|
||||||
|
|
||||||
|
End.
|
||||||
|
|
||||||
@@ -18,32 +18,36 @@ Type TTableContent = class
|
|||||||
|
|
||||||
Function SetDefaultFormat();
|
Function SetDefaultFormat();
|
||||||
Begin
|
Begin
|
||||||
defultFont := impl_.stdPr.rPr;
|
defultFont := impl_.sdtPr.rPr;
|
||||||
defultFont.rFont.cstheme := 'minorBidi';
|
defultFont.rFont.cstheme := 'minorBidi';
|
||||||
defultFont.rFont.XMLeastAsia := '宋体';
|
defultFont.rFont.XMLeastAsia := '宋体';
|
||||||
defultFont.rFont.XMLhAnsi := '宋体';
|
defultFont.rFont.XMLhAnsi := '宋体';
|
||||||
defultFont.rFont.XMLascii := '宋体';
|
defultFont.rFont.XMLascii := '宋体';
|
||||||
//defultFont.kern := 2;
|
//defultFont.kern := 2;
|
||||||
defultFont.Size := 21;
|
defultFont.Size := 21/2;
|
||||||
defultFont.SzCs := 24;
|
defultFont.SzCs := 24;
|
||||||
defultFont.Lang := 'en-US';
|
defultFont.Lang := 'en-US';
|
||||||
defultFont.bidi := 'ar-SA';
|
defultFont.bidi := 'ar-SA';
|
||||||
defultFont.eastAsia := 'zh-CN';
|
defultFont.eastAsia := 'zh-CN';
|
||||||
defultFont.Color := 'DBDBDB';
|
defultFont.Color := 'DBDBDB';
|
||||||
defultFormat := impl_.stdPr;
|
defultFormat := impl_.sdtPr;
|
||||||
defultFormat.ID := integer(time()*24*3600);
|
defultFormat.ID := integer(time()*24*3600);
|
||||||
//defultFormat.Color := 'DBDBDB';
|
//defultFormat.Color := 'DBDBDB';
|
||||||
defultFormat.docPartObj.docPartGallery := 'Table of Contents';
|
defultFormat.docPartObj.docPartGallery := 'Table of Contents';
|
||||||
defultFormat.docPartObj.docPartUnique := 1;
|
defultFormat.docPartObj.docPartUnique := 1;
|
||||||
//impl_.stdEndPr.rPr.Size := 20;
|
//impl_.sdtEndPr.rPr.Size := 21;
|
||||||
//impl_.stdEndPr.rPr.SzCs := 20;
|
//impl_.sdtEndPr.rPr.SzCs := 22;
|
||||||
impl_.stdEndPr.rPr.Bold := true;
|
impl_.sdtEndPr.rPr.Bold := true;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
///应用目录样式
|
///应用目录样式
|
||||||
Function Apply(); override;
|
Function Apply(); override;
|
||||||
Begin
|
Begin
|
||||||
arr := impl_.Marshal();
|
// sdtContent 不应该updateNode
|
||||||
|
tmp_impl := TOfficeObj('TTableContentImpl');
|
||||||
|
tmp_impl.sdtPr := impl_.sdtPr;
|
||||||
|
tmp_impl.sdtEndPr := impl_.sdtEndPr;
|
||||||
|
arr := tmp_impl.Marshal();
|
||||||
class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
|
class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@@ -68,10 +72,12 @@ Type TTableContent = class
|
|||||||
mParagraph.pPr.RightIndent := 0;
|
mParagraph.pPr.RightIndent := 0;
|
||||||
mParagraph.pPr.LeftChars := 0;
|
mParagraph.pPr.LeftChars := 0;
|
||||||
mParagraph.pPr.LeftIndent := 0;
|
mParagraph.pPr.LeftIndent := 0;
|
||||||
|
mParagraph.pPr.StyleID := _GetStyle('TOC');
|
||||||
mParagraph.Run.T := '目录';
|
mParagraph.Run.T := '目录';
|
||||||
mParagraph.Run.rPr.SetName('宋体', true);
|
mParagraph.Run.rPr.Lang := 'zh-CN';
|
||||||
mParagraph.Run.rPr.Size := 21;
|
//mParagraph.Run.rPr.SetName('宋体', true);
|
||||||
mParagraph.Run.rPr.Bold := true;
|
//mParagraph.Run.rPr.Size := 21/2;
|
||||||
|
//mParagraph.Run.rPr.Bold := true;
|
||||||
_AddStdContent(mParagraph);
|
_AddStdContent(mParagraph);
|
||||||
|
|
||||||
goback := TOfficeObj('TParagraph');
|
goback := TOfficeObj('TParagraph');
|
||||||
@@ -79,13 +85,23 @@ Type TTableContent = class
|
|||||||
goback.MarkStart.Name := '_GoBack';
|
goback.MarkStart.Name := '_GoBack';
|
||||||
goback.MarkStart.ID := id;
|
goback.MarkStart.ID := id;
|
||||||
goback.MarkEnd.ID := id;
|
goback.MarkEnd.ID := id;
|
||||||
_AddStdContent(goback);
|
//_AddStdContent(goback);
|
||||||
|
|
||||||
//缺省目录,需要word或wps打开后,更新目录
|
//缺省目录,需要word或wps打开后,更新目录
|
||||||
_AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
|
//_AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
|
||||||
|
|
||||||
//自定义页码计算与word、wps有差异,不推荐使用
|
//自定义页码计算与word、wps有差异,不推荐使用
|
||||||
//_AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
_AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
||||||
|
End;
|
||||||
|
|
||||||
|
///添加目录条目
|
||||||
|
///UpperHeadingLevel:标题最高级别
|
||||||
|
///LowerHeadingLevel:标题最低级别
|
||||||
|
/// 使用 UpperHeadingLevel 属性可设置起始标题级别(最高)。例如,若要设置 TOC 域语法 {TOC \o "1-3"},可将 LowerHeadingLevel 属性设为 3,并将 UpperHeadingLevel 属性设为 1。
|
||||||
|
Function CustomAdd(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
||||||
|
Begin
|
||||||
|
//自定义页码计算与word、wps有差异,不推荐使用
|
||||||
|
_AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function _AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
|
Function _AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
|
||||||
@@ -112,18 +128,18 @@ Type TTableContent = class
|
|||||||
tab := TOfficeObj('TTabStop');
|
tab := TOfficeObj('TTabStop');
|
||||||
tab.Val := 'right';
|
tab.Val := 'right';
|
||||||
tab.leader := 'dot';
|
tab.leader := 'dot';
|
||||||
tab.Position := 8640;
|
tab.Position := TOfficeApi().Get("TTableContent-tab-position") ?: 8306;
|
||||||
p.Format.Tabs.Add(0, tab);
|
p.Format.Tabs.Add(0, tab);
|
||||||
if first then Begin
|
if first then Begin
|
||||||
//fldCharType
|
//fldCharType
|
||||||
r1 := p.AddRun();
|
r1 := p.AddRun();
|
||||||
r1.fldCharType := 'begin';
|
r1.fldCharType := 'begin';
|
||||||
r1.Dirty := 'true';
|
r1.Dirty := 0;
|
||||||
|
|
||||||
//instrText
|
//instrText
|
||||||
r2 := p.AddRun();
|
r2 := p.AddRun();
|
||||||
r2.instrTextSpace := 'preserve';
|
r2.instrTextSpace := 'preserve';
|
||||||
r2.instrText := 'TOC \\o \"' $ UpperHeadingLevel $ '-' $ LowerHeadingLevel $ '\" \\h \\u ';
|
r2.instrText := 'TOC \\o \"' $ UpperHeadingLevel $ '-' $ LowerHeadingLevel $ '\" \\h \\z \\u ';
|
||||||
|
|
||||||
//fldCharType
|
//fldCharType
|
||||||
r3 := p.AddRun();
|
r3 := p.AddRun();
|
||||||
@@ -136,79 +152,77 @@ Type TTableContent = class
|
|||||||
Begin
|
Begin
|
||||||
///获取标题列表 array((("Level":level,"Paragraph":"object","Text":title,"numId":,"ilvl":,"numArr":));
|
///获取标题列表 array((("Level":level,"Paragraph":"object","Text":title,"numId":,"ilvl":,"numArr":));
|
||||||
numMap := array();
|
numMap := array();
|
||||||
r := docx_.Document().Body().GetHeadingListImpl(docx_, posOpt, UpperHeadingLevel, LowerHeadingLevel, numMap, true);
|
r := docx_.Document().Body().GetHeadingListImpl(docx_, nil, UpperHeadingLevel, LowerHeadingLevel, numMap);
|
||||||
for i:=0 to length(r)-1 do Begin
|
for i:=0 to length(r)-1 do Begin
|
||||||
p := _AddItem(UpperHeadingLevel, LowerHeadingLevel, r[i]['Level'], i = 0 ? true: false);
|
p := _AddItem(UpperHeadingLevel, LowerHeadingLevel, r[i]['Level'], i = 0 ? true: false);
|
||||||
//fldCharType
|
//fldCharType
|
||||||
r4 := p.AddRun();
|
h := p.AddHyperLink();
|
||||||
r4.fldCharType := 'begin';
|
|
||||||
|
|
||||||
//instrText
|
|
||||||
bookmarke := _GetBookMarkId(r[i]['Paragraph']);
|
bookmarke := _GetBookMarkId(r[i]['Paragraph']);
|
||||||
r5 := p.AddRun();
|
h.Anchor := bookmarke;
|
||||||
r5.instrTextSpace := 'preserve';
|
h.history := 1;
|
||||||
r5.instrText := ' HYPERLINK \\l ' $ bookmarke $ ' ';
|
|
||||||
|
|
||||||
//fldCharType
|
r1 := h.AddRun();
|
||||||
r6 := p.AddRun();
|
r1.rPr.StyleId := _GetStyle(level);
|
||||||
r6.fldCharType := 'separate';
|
r1.rPr.noProof := true;
|
||||||
|
|
||||||
//目录条目文字内容
|
|
||||||
r7 := p.AddRun();
|
|
||||||
r7.Font.SetName('宋体', true);
|
|
||||||
numStr := ''; //数字项目编号
|
numStr := ''; //数字项目编号
|
||||||
if r[i]['numId'] then Begin
|
if r[i]['numId'] then Begin
|
||||||
style := docx_.NumberingObject().NumberStyle(r[i]['numId']);//支持数字、字符串StyleId
|
style := docx_.NumberingObject().NumberStyle(r[i]['numId']);//支持数字、字符串StyleId
|
||||||
if ifObj(style) then
|
if ifObj(style) then
|
||||||
numStr := style.GetText(r[i]['ilvl'], r[i]['numArr']);
|
numStr := style.GetText(r[i]['ilvl'], r[i]['numArr']);
|
||||||
End
|
End
|
||||||
r7.T := numStr + r[i]['Text'];
|
run_t := class(TSXml).CurCodePageToUtf8(r[i]['Text']);
|
||||||
|
if numStr <> '' then run_t := numStr + ' ' + run_t;
|
||||||
|
r1.SetText(run_t, 1);
|
||||||
|
|
||||||
//Tab
|
r2 := h.AddRun();
|
||||||
r8 := p.AddRun();
|
r2.rPr.noProof := true;
|
||||||
r8.Tab := true;
|
r2.rPr.WebHidden := true;
|
||||||
|
r2.Tab := true;
|
||||||
|
|
||||||
//fldCharType
|
r3 := h.AddRun();
|
||||||
r9 := p.AddRun();
|
r3.rPr.noProof := true;
|
||||||
r9.fldCharType := 'begin';
|
r3.rPr.WebHidden := true;
|
||||||
|
r3.fldCharType := 'begin';
|
||||||
|
|
||||||
//instrText
|
//instrText
|
||||||
r10 := p.AddRun();
|
r4 := h.AddRun();
|
||||||
r10.instrTextSpace := 'preserve';
|
r4.rPr.noProof := true;
|
||||||
r10.instrText := ' PAGEREF ' $ bookmarke $ ' \\h ';
|
r4.rPr.WebHidden := true;
|
||||||
|
r4.instrTextSpace := 'preserve';
|
||||||
|
r4.instrText := ' PAGEREF ' $ bookmarke $ ' \\h ';
|
||||||
|
|
||||||
|
r5 := h.AddRun();
|
||||||
|
r5.rPr.noProof := true;
|
||||||
|
r5.rPr.WebHidden := true;
|
||||||
|
r5.Tab := true;
|
||||||
|
|
||||||
//fldCharType
|
//fldCharType
|
||||||
r11 := p.AddRun();
|
r6 := h.AddRun();
|
||||||
r11.fldCharType := 'separate';
|
r6.rPr.noProof := true;
|
||||||
|
r6.rPr.WebHidden := true;
|
||||||
|
r6.fldCharType := 'separate';
|
||||||
|
|
||||||
//页码
|
//页码
|
||||||
r12 := p.AddRun();
|
r7 := h.AddRun();
|
||||||
r12.T := '' $ r[i]['pageNo'];
|
r7.T := 0;//'' $ r[i]['pageNo'];
|
||||||
|
|
||||||
//fldCharType
|
//fldCharType
|
||||||
r13 := p.AddRun();
|
r8 := h.AddRun();
|
||||||
r13.fldCharType := 'end';
|
r8.rPr.noProof := true;
|
||||||
|
r8.rPr.WebHidden := true;
|
||||||
|
r8.fldCharType := 'end';
|
||||||
|
|
||||||
//fldCharType
|
|
||||||
r14 := p.AddRun();
|
|
||||||
r14.fldCharType := 'end';
|
|
||||||
|
|
||||||
if r[i]['Level']+1 = UpperHeadingLevel then Begin //第一级标题,设置为粗体
|
|
||||||
p.Format.rPr.Bold := true;
|
|
||||||
r4.rPr.Bold := true;
|
|
||||||
r5.rPr.Bold := true;
|
|
||||||
r6.rPr.Bold := true;
|
|
||||||
r7.rPr.Bold := true;
|
|
||||||
r8.rPr.Bold := true;
|
|
||||||
//r9.rPr.Bold := true;
|
|
||||||
r10.rPr.Bold := true;
|
|
||||||
//r11.rPr.Bold := true;
|
|
||||||
r12.Font.Bold := true;
|
|
||||||
//r13.rPr.Bold := true;
|
|
||||||
r14.rPr.Bold := true;
|
|
||||||
End;
|
|
||||||
_AddStdContent(p);
|
_AddStdContent(p);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
p2 := TOfficeObj('TParagraph');
|
||||||
|
//p2.Format.SpaceAfter := 0;
|
||||||
|
run := p2.AddRun();
|
||||||
|
run.rPr.Bold := true;
|
||||||
|
run.rPr.noProof := true;
|
||||||
|
run.fldCharType := 'end';
|
||||||
|
_AddStdContent(p2);
|
||||||
|
|
||||||
End;
|
End;
|
||||||
|
|
||||||
///更新目录
|
///更新目录
|
||||||
@@ -216,6 +230,26 @@ Type TTableContent = class
|
|||||||
Begin
|
Begin
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
Function Paragraphs();
|
||||||
|
Begin
|
||||||
|
node := class(TSXml).GetNode(docx_.Document().Body().Node(), 'w:sdt/w:sdtContent');
|
||||||
|
r := array();
|
||||||
|
if ifObj(node) then
|
||||||
|
begin
|
||||||
|
twbody := TOfficeObj('TwBody');
|
||||||
|
twbody.Create(nil, 'w:sdtContent');
|
||||||
|
twbody.InitRootNode(node);
|
||||||
|
twbody.InitNode(node);
|
||||||
|
parts := twbody.Paragraphs();
|
||||||
|
for i:=0 to length(parts)-1 do
|
||||||
|
begin
|
||||||
|
r[i] := TOfficeObj('TParagraph');
|
||||||
|
r[i].Init(parts[i].node_);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return r;
|
||||||
|
End;
|
||||||
|
|
||||||
Function Marshal();
|
Function Marshal();
|
||||||
Begin
|
Begin
|
||||||
return impl_.Marshal();
|
return impl_.Marshal();
|
||||||
@@ -224,19 +258,19 @@ Type TTableContent = class
|
|||||||
Property Format read readFormat;
|
Property Format read readFormat;
|
||||||
Function readFormat();
|
Function readFormat();
|
||||||
Begin
|
Begin
|
||||||
return impl_.stdPr;
|
return impl_.sdtPr;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Property EndFormat read readEndFormat;
|
Property EndFormat read readEndFormat;
|
||||||
Function readEndFormat();
|
Function readEndFormat();
|
||||||
Begin
|
Begin
|
||||||
return impl_.stdEndPr;
|
return impl_.sdtEndPr;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Property Font read readFont;
|
Property Font read readFont;
|
||||||
Function readFont();
|
Function readFont();
|
||||||
Begin
|
Begin
|
||||||
return impl_.stdPr.rPr;
|
return impl_.sdtPr.rPr;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function _AddStdContent(o);
|
Function _AddStdContent(o);
|
||||||
@@ -246,18 +280,10 @@ Type TTableContent = class
|
|||||||
|
|
||||||
Function _GetStyle(level);
|
Function _GetStyle(level);
|
||||||
Begin
|
Begin
|
||||||
styleName := 'Tinysoft目录 ' $ (level + 1);
|
styleName := ifstring(level) ? level : 'TOC' $ (level + 1);
|
||||||
style := docx_.StyleObject().GetStyle(styleName);
|
style := docx_.StyleObject().GetStyleById(styleName);
|
||||||
if not ifObj(style) then Begin
|
if not ifObj(style) then Begin
|
||||||
style := TOfficeObj('TDocxStyle');
|
style := docx_.StyleObject().AddDefaultStyle(styleName);
|
||||||
style.wType := 'paragraph';
|
|
||||||
style.CustomStyle := 1;
|
|
||||||
style.Name := styleName;
|
|
||||||
style.uiPriority := 0;
|
|
||||||
style.pPr.LeftChars := 200 * level;
|
|
||||||
style.rPr.Size := 20;
|
|
||||||
style.rPr.SzCs := 20;
|
|
||||||
docx_.StyleObject().AddStyle(style, 'TsToc' $ (level + 1));
|
|
||||||
End;
|
End;
|
||||||
return style.StyleId;
|
return style.StyleId;
|
||||||
End;
|
End;
|
||||||
@@ -268,7 +294,7 @@ Type TTableContent = class
|
|||||||
if ifObj(node) then
|
if ifObj(node) then
|
||||||
return node.GetAttribute('w:name');
|
return node.GetAttribute('w:name');
|
||||||
bookMarkID := docx_.Document().GetBookMarkID();
|
bookMarkID := docx_.Document().GetBookMarkID();
|
||||||
return p.AddBookMark();
|
return p.AddBookMark(bookMarkID);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function _CheckNodes(name);
|
Function _CheckNodes(name);
|
||||||
@@ -298,7 +324,8 @@ Type TTableContent = class
|
|||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
docx_;
|
[weakref]docx_;
|
||||||
node_;
|
node_;
|
||||||
impl_;
|
impl_;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Type docxDocument = Class
|
|||||||
bodyNode_ := root_.FirstChildElement('w:body');
|
bodyNode_ := root_.FirstChildElement('w:body');
|
||||||
body_ := TOfficeObj('TwBody');
|
body_ := TOfficeObj('TwBody');
|
||||||
body_.InitNode(bodyNode_);
|
body_.InitNode(bodyNode_);
|
||||||
|
body_.InitRootNode(bodyNode_);
|
||||||
body_.zipfile_ := z;
|
body_.zipfile_ := z;
|
||||||
body_.document_ := self;
|
body_.document_ := self;
|
||||||
bookmarkid_ := -1;
|
bookmarkid_ := -1;
|
||||||
@@ -20,6 +21,11 @@ Type docxDocument = Class
|
|||||||
return body_;
|
return body_;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
Function AddNameSpace(prefix, uri);
|
||||||
|
Begin
|
||||||
|
root_.SetAttribute('xmlns:' + prefix, uri);
|
||||||
|
End;
|
||||||
|
|
||||||
Function GetBookMarkID();
|
Function GetBookMarkID();
|
||||||
Begin
|
Begin
|
||||||
if bookmarkid_ < 0 then Begin
|
if bookmarkid_ < 0 then Begin
|
||||||
@@ -29,7 +35,7 @@ Type docxDocument = Class
|
|||||||
markStart := p.FirstChildElement('w:bookmarkStart');
|
markStart := p.FirstChildElement('w:bookmarkStart');
|
||||||
if ifObj(markStart) then Begin
|
if ifObj(markStart) then Begin
|
||||||
id := markStart.GetAttribute('w:id');
|
id := markStart.GetAttribute('w:id');
|
||||||
if ifstring(id) then Begin
|
if ifstring(id) and id <> '' then Begin
|
||||||
iVal := strtoint(id);
|
iVal := strtoint(id);
|
||||||
if bookmarkid_ <= iVal then
|
if bookmarkid_ <= iVal then
|
||||||
bookmarkid_ := iVal + 1;
|
bookmarkid_ := iVal + 1;
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
Function _ExcelChartCopyPic(excelFileName, excelSheetName, chartName, Width, Height);
|
|
||||||
Begin
|
|
||||||
docx := TOfficeApi().GetDocument();
|
|
||||||
chart := docx.CopyExcelChart(excelFileName, excelSheetName, chartName, Width, Height, TOfficeApi().GetCurrentPosition());
|
|
||||||
return ifObj(chart);
|
|
||||||
End;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Function _WordAddOleObjectFromFile(fileName, width, height);
|
|
||||||
Begin
|
|
||||||
End;
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Function _WordBr();
|
|
||||||
Begin
|
|
||||||
TOfficeApi().GetDocument().AddLineBreak(TOfficeApi().Get('CurrentPosition'));
|
|
||||||
End;
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
Function _WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
|
|
||||||
Begin
|
|
||||||
excel := new TSExcelFile();
|
|
||||||
[err, msg] := excel.OpenFile('', excelFileName);
|
|
||||||
if err then return false;
|
|
||||||
total_row := excel.TotalRows(excelSheetName);
|
|
||||||
total_col := excel.TotalCols(excelSheetName);
|
|
||||||
if not total_row or not total_col then return false;
|
|
||||||
if ifnil(startRow) then
|
|
||||||
startRow := 1;
|
|
||||||
if ifnil(startCol) then
|
|
||||||
startCol := 1;
|
|
||||||
if ifnil(endRow) then
|
|
||||||
endRow := total_row;
|
|
||||||
if ifnil(endCol) then
|
|
||||||
endCol := total_col;
|
|
||||||
data := excel.GetTable(excelSheetName,
|
|
||||||
CoordinatesToCellName(startCol, startRow),
|
|
||||||
CoordinatesToCellName(endCol, endRow),
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false);
|
|
||||||
if length(data) = 0 then return false;
|
|
||||||
//println('data={}',data);
|
|
||||||
docx := TOfficeApi().GetDocument();
|
|
||||||
tbl := docx.CreateTable(data, false, false);
|
|
||||||
tbl.Format.Borders.Top.Val := 'dashed';
|
|
||||||
tbl.Format.Borders.Left.Val := 'dashed';
|
|
||||||
tbl.Format.Borders.Bottom.Val := 'dashed';
|
|
||||||
tbl.Format.Borders.Right.Val := 'dashed';
|
|
||||||
tbl.Format.Borders.InsideH.Val := 'dashed';
|
|
||||||
tbl.Format.Borders.InsideV.Val := 'dashed';
|
|
||||||
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
|
|
||||||
End;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Function _WordCopyPicFormatExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol, picType);
|
|
||||||
Begin
|
|
||||||
End;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Function _WordGetCurrentDocument();
|
|
||||||
Begin
|
|
||||||
return TOfficeApi().GetDocument();
|
|
||||||
End;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Function _WordGetCurrentRange();
|
|
||||||
Begin
|
|
||||||
return TOfficeApi().GetCurrentPosition();
|
|
||||||
End;
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
Function _WordGetFont(prop, value);
|
|
||||||
Begin
|
|
||||||
crun := TOfficeApi().GetCurrentRun();
|
|
||||||
node := crun.Node().FirstChildElement('w:rPr');
|
|
||||||
rPr := TOfficeObj('TwrPr');
|
|
||||||
rPr.InitRootNode(node);
|
|
||||||
value := rPr.Value(prop);
|
|
||||||
if not ifnil(value) then return true;
|
|
||||||
return false;
|
|
||||||
End;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Function _WordGetLastRange();
|
|
||||||
Begin
|
|
||||||
return TOfficeApi().GetCurrentPosition();
|
|
||||||
End;
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
Function _WordGetLastShape();
|
|
||||||
Begin
|
|
||||||
node := TOfficeApi().Get('CurrentShape');
|
|
||||||
if not ifObj(node) then return nil;
|
|
||||||
uri := 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart';
|
|
||||||
cNode := class(TSXml).GetNode(node, uri);
|
|
||||||
if ifObj(cNode) then Begin
|
|
||||||
chart := TOfficeObj('TChart');
|
|
||||||
chart.Init(TOfficeApi().GetDocument(), node, cNode);
|
|
||||||
return chart;
|
|
||||||
End;
|
|
||||||
|
|
||||||
pic := TOfficeObj('TPicture');
|
|
||||||
pic.Init(node);
|
|
||||||
return pic;
|
|
||||||
End;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Function _WordGetLastTable();
|
|
||||||
Begin
|
|
||||||
return TOfficeApi().Get('LastTable');
|
|
||||||
End;
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
Function _WordGetLastTableCellProp(row, col, name, value);
|
|
||||||
Begin
|
|
||||||
table := TOfficeApi().Get('LastTable');
|
|
||||||
if ifnil(table) then return false;
|
|
||||||
table_cell := table.Cell(row, col);
|
|
||||||
ctr := _wordCompTable();
|
|
||||||
name_ := ctr[lowercase(name)];
|
|
||||||
if ifnil(name_) then name_ := name;
|
|
||||||
str := 'return table_cell.Format.' $ name_ $ '"' $ value $ '"';
|
|
||||||
value := eval(&str);
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
Function _WordGetLastTableProp(name, value);
|
|
||||||
Begin
|
|
||||||
table := TOfficeApi().Get('LastTable');
|
|
||||||
if ifnil(table) then return false;
|
|
||||||
ctr := _wordCompTable();
|
|
||||||
name_ := ctr[lowercase(name)];
|
|
||||||
if ifnil(name_) then name_ := name;
|
|
||||||
str := 'return table.Format.' $ name_ $ '"' $ value $ '"';
|
|
||||||
value := eval(&str);
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Function _WordGetRangeProp(name, value);
|
|
||||||
Begin
|
|
||||||
End;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
Function _WordLastTableMerge(row1, col1, row2, col2);
|
|
||||||
Begin
|
|
||||||
table := TOfficeApi().Get('LastTable');
|
|
||||||
if ifnil(table) then return false;
|
|
||||||
[err1, beg_cell] := CoordinatesToCellName(col1, row1);
|
|
||||||
[err2, end_cell] := CoordinatesToCellName(col2, row2);
|
|
||||||
if err1 or err2 then return false;
|
|
||||||
table.Merge(beg_cell, end_cell, false);
|
|
||||||
TOfficeApi().Set('LastTable', table);
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
Function _WordLastTableSplit(row, col, rCnt, cCnt);
|
|
||||||
Begin
|
|
||||||
End;
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Function _WordSetCurrnetRange(range);
|
|
||||||
Begin
|
|
||||||
TOfficeApi().Set('CurrentPosition', range);
|
|
||||||
End;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
Function _WordSetFont(prop, value);
|
|
||||||
Begin
|
|
||||||
run := TOfficeApi().GetCurrentRun();
|
|
||||||
str := 'run.font.' $ prop $ ' := ' $ '"' $ value $ '"';
|
|
||||||
eval(&str);
|
|
||||||
run.Apply();
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
Function _WordSetLastTableCellProp(row, col, name, value);
|
|
||||||
Begin
|
|
||||||
table := TOfficeApi().Get('LastTable');
|
|
||||||
if ifnil(table) then return false;
|
|
||||||
table_cell := table.Cell(row, col);
|
|
||||||
ctr := _wordCompTable();
|
|
||||||
name_ := ctr[lowercase(name)];
|
|
||||||
if ifnil(name_) then name_ := name;
|
|
||||||
str := 'table_cell.Format.' $ name_ $ ' := ';
|
|
||||||
if ifstring(value) then
|
|
||||||
str += '"' $ value $ '"';
|
|
||||||
else
|
|
||||||
str = str $ value;
|
|
||||||
eval(&str);
|
|
||||||
TOfficeApi().Set('LastTable', table);
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
Function _WordSetLastTableProp(name, value);
|
|
||||||
Begin
|
|
||||||
table := TOfficeApi().Get('LastTable');
|
|
||||||
if ifnil(table) then return false;
|
|
||||||
ctr := _wordCompTable();
|
|
||||||
name_ := ctr[lowercase(name)];
|
|
||||||
if ifnil(name_) then name_ := name;
|
|
||||||
str := 'table.Format.' $ name_ $ ' := ';
|
|
||||||
if ifstring(value) then
|
|
||||||
str += '"' $ value $ '"';
|
|
||||||
else
|
|
||||||
str = str $ value;
|
|
||||||
eval(&str);
|
|
||||||
TOfficeApi().Set('LastTable', table);
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Function _WordSetRangeProp(name, value);
|
|
||||||
Begin
|
|
||||||
cur := TOfficeApi().GetCurrentPosition();
|
|
||||||
if ifnil(cur) then return nil;
|
|
||||||
End;
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
Function _WordTemplate(data, template, fileName);
|
|
||||||
Begin
|
|
||||||
setsysparam('data', data);
|
|
||||||
docx := new TSDocxFile();
|
|
||||||
[err, msg] := docx.OpenFile('', template);
|
|
||||||
if err then return false;
|
|
||||||
docx.ExecInnerTSL();
|
|
||||||
if ifstring(fileName) then
|
|
||||||
begin
|
|
||||||
[err, msg] := docx.SaveAs('', fileName);
|
|
||||||
if err then return false;
|
|
||||||
end
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
Function _WordWrite();
|
|
||||||
Begin
|
|
||||||
docx := TOfficeApi().GetDocument();
|
|
||||||
curParagraph := TOfficeApi().GetCurrentParagraph();
|
|
||||||
curRun := TOfficeApi().GetCurrentRun();
|
|
||||||
for i:=1 to PARAMCOUNT do Begin
|
|
||||||
argv := params[i];
|
|
||||||
if ifstring( argv ) then
|
|
||||||
curRun.AddText( argv );
|
|
||||||
else if ifnumber(argv) then
|
|
||||||
curRun.AddText('' $ argv);
|
|
||||||
else if ifarray(argv) then Begin
|
|
||||||
tbl := docx.CreateTable(argv, false, false);
|
|
||||||
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
|
|
||||||
End
|
|
||||||
End
|
|
||||||
End;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
Function _WordWritePicFromFile(fileName);
|
|
||||||
Begin
|
|
||||||
file_size := fileSize('', fileName);
|
|
||||||
flag := readfile(rwbinary(), '', fileName, 0, file_size, data);
|
|
||||||
if not flag then return false;
|
|
||||||
picture := TOfficeObj('TPicture');
|
|
||||||
picture.Image := data;
|
|
||||||
docx := TOfficeApi().GetDocument();
|
|
||||||
docx.AddPicture(picture, TOfficeApi().GetCurrentPosition());
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
Function _WordWriteTable(table, writeIntIndex, writeIntTitle, incIntIndex);
|
|
||||||
Begin
|
|
||||||
docx := TOfficeApi().GetDocument();
|
|
||||||
tbl := docx.CreateTable(table, true, writeIntIndex);
|
|
||||||
table := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
|
|
||||||
TOfficeApi().Set('LastTable', table);
|
|
||||||
return true;
|
|
||||||
End;
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
Function _wordCompTable();
|
|
||||||
Begin
|
|
||||||
return array(
|
|
||||||
'alignment': 'Alignment',
|
|
||||||
'shadingcolor': 'Shading.Color',
|
|
||||||
'style': 'StyleID',
|
|
||||||
'verticalalignment': 'Valign',
|
|
||||||
'width': 'Width',
|
|
||||||
);
|
|
||||||
End;
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
_WordTemplate(alias, fileName);
|
|
||||||
_WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
|
|
||||||
_WordCopyPicFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol, picType);
|
|
||||||
_ExcelChartCopyPic(excelFileName, excelSheetName, picType);
|
|
||||||
_WordGetCurrentDocument();
|
|
||||||
_WordGetCurrentRange();
|
|
||||||
_WordSetCurrnetRange(range);
|
|
||||||
_WordGetLastRange();
|
|
||||||
_WordGetLastTable();
|
|
||||||
_WordGetLastShape();
|
|
||||||
_WordWrite();
|
|
||||||
_WordBr();
|
|
||||||
_WordWriteTable(table, writeIntIndex, writeIntTile, incIntIndex);
|
|
||||||
_WordWritePicFromFile(fileName);
|
|
||||||
_WordSetFont(prop, value);
|
|
||||||
_WordGetFont(prop, value);
|
|
||||||
_WordAddOleObjectFromFile(fileName, width, height);
|
|
||||||
_WordLastTableSplit(row, col, rCnt, cCnt);
|
|
||||||
_WordLastTableMerge(row1, col1, row2, col2);
|
|
||||||
_WordSetRangeProp(name, value);
|
|
||||||
_WordGetRangeProp(name, value);
|
|
||||||
_WordSetLastTableProp(name, value);
|
|
||||||
_WordGetLastTableProp(name, value);
|
|
||||||
_WordSetLastTableCellProp(row, col, name, value);
|
|
||||||
_WordGetLastTableCellProp(row, col, name, value);
|
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ Type xlsxChart = Class(TSChart)
|
|||||||
node := drawingXmlObj_.FirstChild('xdr:wsDr').InsertEndChild(o.Marshal());
|
node := drawingXmlObj_.FirstChild('xdr:wsDr').InsertEndChild(o.Marshal());
|
||||||
End;
|
End;
|
||||||
private
|
private
|
||||||
excel_;
|
[weakref]excel_;
|
||||||
drawingRID_:integer;
|
drawingRID_:integer;
|
||||||
chartId_;
|
chartId_;
|
||||||
chartRid_;
|
chartRid_;
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ xmlns:v="urn:schemas-microsoft-com:vml">
|
|||||||
if ifObj(node) then Begin
|
if ifObj(node) then Begin
|
||||||
[err, col, row] := excel_.CellNameToCoordinates(cell);
|
[err, col, row] := excel_.CellNameToCoordinates(cell);
|
||||||
clientData := TOfficeObj('TClientData');
|
clientData := TOfficeObj('TClientData');
|
||||||
clientData.Anchor := fmt('{},23,{},0,{},{},{},5',col, row, 1+col+lineCount, colCount+col-1, 1+row+lineCount);
|
clientData.Anchor := format('%d,23,%d,0,%d,%d,%d,5',col, row, 1+col+lineCount, colCount+col-1, 1+row+lineCount);
|
||||||
clientData.Row := row - 1;
|
clientData.Row := row - 1;
|
||||||
ClientData.Column := col - 1;
|
ClientData.Column := col - 1;
|
||||||
node.UnMarshal(clientData.Marshal());
|
node.UnMarshal(clientData.Marshal());
|
||||||
@@ -148,7 +148,11 @@ xmlns:v="urn:schemas-microsoft-com:vml">
|
|||||||
comment += r_node.FirstChildElement('t').GetText();
|
comment += r_node.FirstChildElement('t').GetText();
|
||||||
r_node := r_node.NextElement();
|
r_node := r_node.NextElement();
|
||||||
end
|
end
|
||||||
if length(comment) > 1 then comment := comment[2:];
|
if length(comment) > 1 then
|
||||||
|
begin
|
||||||
|
if comment[1] = "\n" then comment := comment[2:];
|
||||||
|
else if comment[1:2] = "\r\n" then comment := comment[3:];
|
||||||
|
end
|
||||||
return array(author, comment);
|
return array(author, comment);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@@ -180,6 +184,7 @@ private
|
|||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
[weakref]excel_;//TSXlsxFile对象
|
||||||
authors_;
|
authors_;
|
||||||
commentId_;
|
commentId_;
|
||||||
commentFileName_:string;//'../comments/comment1.xml'
|
commentFileName_:string;//'../comments/comment1.xml'
|
||||||
@@ -187,7 +192,6 @@ private
|
|||||||
rId_:string;
|
rId_:string;
|
||||||
sheetName_:string;//sheet名称
|
sheetName_:string;//sheet名称
|
||||||
sheetFileName_;//xl/worksheets/sheetN.xml
|
sheetFileName_;//xl/worksheets/sheetN.xml
|
||||||
excel_;//TSExcelFile对象
|
|
||||||
commentXmlFile_;//XmlFile对象
|
commentXmlFile_;//XmlFile对象
|
||||||
commentObjs_;
|
commentObjs_;
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -45,5 +45,5 @@ Type xlsxDocProps = Class
|
|||||||
End;
|
End;
|
||||||
|
|
||||||
private
|
private
|
||||||
excel_; //TSExcelFile对象
|
[weakref]excel_; //TSExcelFile对象
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -33,6 +33,6 @@ Type xlsxHeaderFooter = Class
|
|||||||
|
|
||||||
private
|
private
|
||||||
sheet_; //XmlSheet对象
|
sheet_; //XmlSheet对象
|
||||||
file_; //TSExcelFile对象
|
[weakref]file_; //TSExcelFile对象
|
||||||
xmlFile_; //sheet对应的xml对象
|
xmlFile_; //sheet对应的xml对象
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ Type xlsxHyperLink = Class
|
|||||||
End;
|
End;
|
||||||
|
|
||||||
private
|
private
|
||||||
file_; //TSExcelFile对象
|
[weakref]file_; //TSExcelFile对象
|
||||||
xmlFile_;//XmlFile对象
|
xmlFile_;//XmlFile对象
|
||||||
sheetName_;
|
sheetName_;
|
||||||
|
|
||||||
|
|||||||
@@ -169,6 +169,6 @@ private
|
|||||||
|
|
||||||
private
|
private
|
||||||
sheetName_:string; //sheet名称
|
sheetName_:string; //sheet名称
|
||||||
excel_;//TSExcelFile对象
|
[weakref]excel_;//TSExcelFile对象
|
||||||
zipfile_;
|
zipfile_;
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ Type xlsxPageLayout = Class
|
|||||||
End;
|
End;
|
||||||
|
|
||||||
private
|
private
|
||||||
file_; //TSExcelFile对象
|
[weakref]file_; //TSExcelFile对象
|
||||||
sheet_;//XmlSheet对象
|
sheet_;//XmlSheet对象
|
||||||
xmlFile_; //sheet对应的xml对象
|
xmlFile_; //sheet对应的xml对象
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ private
|
|||||||
|
|
||||||
private
|
private
|
||||||
sheetName_:string; //sheet名称
|
sheetName_:string; //sheet名称
|
||||||
excel_;//TSExcelFile对象
|
[weakref]excel_;//TSExcelFile对象
|
||||||
zipfile_;
|
zipfile_;
|
||||||
drawingXmlObj_;
|
drawingXmlObj_;
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ Type xlsxSheetView = Class
|
|||||||
End;
|
End;
|
||||||
|
|
||||||
private
|
private
|
||||||
file_; //TSExcelFile对象
|
[weakref]file_; //TSExcelFile对象
|
||||||
sheet_;//XmlSheet对象
|
sheet_;//XmlSheet对象
|
||||||
xmlFile_; //sheet对应的xml对象
|
xmlFile_; //sheet对应的xml对象
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -1,15 +1,29 @@
|
|||||||
Type xlsxStyles = Class
|
Type xlsxStyles = Class
|
||||||
|
|
||||||
Function Create(sheetobj, file);
|
Function Create(file);
|
||||||
Begin
|
Begin
|
||||||
sheet_ := sheetobj;
|
|
||||||
file_ := file;
|
file_ := file;
|
||||||
styleXmlFile_ := file_.WorkBook().GetXmlFileObj('xl/styles.xml');
|
style_xml_file_ := file_.WorkBook().GetXmlFileObj('xl/styles.xml');
|
||||||
|
style_ := array();
|
||||||
|
Init();
|
||||||
|
End
|
||||||
|
|
||||||
|
Function Init();
|
||||||
|
Begin
|
||||||
|
style_node := style_xml_file_.FirstChildElement("styleSheet");
|
||||||
|
xfs_node := style_node.FirstChildElement("cellXfs");
|
||||||
|
xf_node := xfs_node.FirstChildElement("xf");
|
||||||
|
count := 0;
|
||||||
|
while ifObj(xf_node) do
|
||||||
|
begin
|
||||||
|
style_[inttostr(count++)] := xf_node;
|
||||||
|
xf_node := xf_node.NextElement("xf");
|
||||||
|
end
|
||||||
End
|
End
|
||||||
|
|
||||||
Function GetStyleId(style);overload;
|
Function GetStyleId(style);overload;
|
||||||
Begin
|
Begin
|
||||||
node := styleXmlFile_.FirstChildElement('styleSheet');
|
node := style_xml_file_.FirstChildElement('styleSheet');
|
||||||
font_id := insertNode(node, 'fonts', style.Font);
|
font_id := insertNode(node, 'fonts', style.Font);
|
||||||
border_id := insertNode(node, 'borders', style.Border);
|
border_id := insertNode(node, 'borders', style.Border);
|
||||||
fill_id := insertNode(node, 'fills', style.Fill);
|
fill_id := insertNode(node, 'fills', style.Fill);
|
||||||
@@ -40,15 +54,16 @@ Type xlsxStyles = Class
|
|||||||
|
|
||||||
node := node.FirstChildElement('cellXfs');
|
node := node.FirstChildElement('cellXfs');
|
||||||
count := node.GetAttribute('count');
|
count := node.GetAttribute('count');
|
||||||
node.InsertEndChild(xf.Marshal());
|
|
||||||
node.SetAttribute('count', strtoint(count) + 1);
|
node.SetAttribute('count', strtoint(count) + 1);
|
||||||
|
xf_node := node.InsertEndChild(xf.Marshal());
|
||||||
|
style_[count] := xf_node;
|
||||||
return count;
|
return count;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function GetStyleId(newStyle, oldStyleId);overload;
|
Function GetStyleId(newStyle, oldStyleId);overload;
|
||||||
Begin
|
Begin
|
||||||
if oldStyleId = '' then return nil;
|
if oldStyleId = '' then return nil;
|
||||||
style_node := styleXmlFile_.FirstChildElement('styleSheet');
|
style_node := style_xml_file_.FirstChildElement('styleSheet');
|
||||||
cellXfs_node := style_node.FirstChildElement('cellXfs');
|
cellXfs_node := style_node.FirstChildElement('cellXfs');
|
||||||
count := strtoint(cellXfs_node.GetAttribute('count'));
|
count := strtoint(cellXfs_node.GetAttribute('count'));
|
||||||
Id := strtoint(oldStyleId);
|
Id := strtoint(oldStyleId);
|
||||||
@@ -89,19 +104,14 @@ Type xlsxStyles = Class
|
|||||||
xf_node.SetAttribute('applyProtection', 1);
|
xf_node.SetAttribute('applyProtection', 1);
|
||||||
end
|
end
|
||||||
|
|
||||||
|
style_[inttostr(count)] := xf_node;
|
||||||
return inttostr(count);
|
return inttostr(count);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function GetStyle(styleId);
|
Function GetStyle(styleId);
|
||||||
Begin
|
Begin
|
||||||
if styleId = '' then return nil;
|
xf := style_[styleId];
|
||||||
style_node := styleXmlFile_.FirstChildElement('styleSheet');
|
if not ifObj(xf) then return nil;
|
||||||
cellXfs_node := style_node.FirstChildElement('cellXfs');
|
|
||||||
count := strtoint(cellXfs_node.GetAttribute('count'));
|
|
||||||
Id := strtoint(styleId);
|
|
||||||
if Id > count-1 then return nil;
|
|
||||||
|
|
||||||
xf := getNode(cellXfs_node, 'xf', Id);
|
|
||||||
attrs := xf.Attributes();
|
attrs := xf.Attributes();
|
||||||
numfmt_id := trystrtoint(attrs['numFmtId'], r) ? r : 0;
|
numfmt_id := trystrtoint(attrs['numFmtId'], r) ? r : 0;
|
||||||
font_id := trystrtoint(attrs['fontId'], r) ? r : 0;
|
font_id := trystrtoint(attrs['fontId'], r) ? r : 0;
|
||||||
@@ -110,6 +120,7 @@ Type xlsxStyles = Class
|
|||||||
|
|
||||||
alignment := xf.FirstChildElement('alignment');
|
alignment := xf.FirstChildElement('alignment');
|
||||||
protection := xf.FirstChildElement('protection');
|
protection := xf.FirstChildElement('protection');
|
||||||
|
style_node := style_xml_file_.FirstChildElement('styleSheet');
|
||||||
style := TOfficeObj('TStyle');
|
style := TOfficeObj('TStyle');
|
||||||
numFmts_node := style_node.FirstChildElement('numFmts');
|
numFmts_node := style_node.FirstChildElement('numFmts');
|
||||||
fonts_node := style_node.FirstChildElement('fonts');
|
fonts_node := style_node.FirstChildElement('fonts');
|
||||||
@@ -127,12 +138,51 @@ Type xlsxStyles = Class
|
|||||||
return style;
|
return style;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
class Function NewObject(sheetname, file);
|
Function GetNumFmtId(styleId);
|
||||||
Begin
|
Begin
|
||||||
o := file.WorkBook().GetSheetObj(sheetname);
|
node := style_[styleId];
|
||||||
if not ifObj(o) then return 0;
|
if ifnil(node) then return '0';
|
||||||
styles := new xlsxStyles(o, file);
|
numfmt := node.GetAttribute("numFmtId");
|
||||||
return styles;
|
return numfmt = '' ? '' : numfmt;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function GetType(styleId, value);
|
||||||
|
Begin
|
||||||
|
numfmt_id := GetNumFmtId(styleId);
|
||||||
|
if numfmt_id = '' then return array(nil, value);
|
||||||
|
numfmt_id := strtoint(numfmt_id);
|
||||||
|
if numfmt_id = 0 then return array(nil, value);
|
||||||
|
if numfmt_id >= 1 and numfmt_id <= 10 then return array('n', value);
|
||||||
|
if numfmt_id >= 11 and numfmt_id <= 26 then
|
||||||
|
begin
|
||||||
|
if ifstring(value) and (trystrtodate(value, r) or trystrtodatetime(value, r) or trystrtotime(value, r)) then return array('n', r);
|
||||||
|
t := ifstring(value) ? 's' : 'n';
|
||||||
|
return array(t, value);
|
||||||
|
end
|
||||||
|
if numfmt_id >= 27 and numfmt_id <= 34 then return array('e', value);
|
||||||
|
if numfmt_id >= 35 and numfmt_id <= 48 then return array('n', value);
|
||||||
|
if numfmt_id = 49 then return array('s', value);
|
||||||
|
if numfmt_id >= 50 and numfmt_id <= 55 then
|
||||||
|
begin
|
||||||
|
if ifstring(value) and trystrtodate(value, r) then return array('n', r);
|
||||||
|
t := ifstring(value) ? 's' : 'n';
|
||||||
|
return array(t, value);
|
||||||
|
end
|
||||||
|
if numfmt_id >= 56 and numfmt_id <= 58 then
|
||||||
|
begin
|
||||||
|
if ifstring(value) and trystrtodatetime(value, r) then return array('n', r);
|
||||||
|
t := ifstring(value) ? 's' : 'n';
|
||||||
|
return array(t, value);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if ifstring(value) then
|
||||||
|
begin
|
||||||
|
if (pos("-", value) or pos("/", value)) and (trystrtodatetime(value, r) or trystrtodate(value, r)) then return array('n', r);
|
||||||
|
if trystrtofloat(value, r) then return array("n", value);
|
||||||
|
return array("s", value);
|
||||||
|
end
|
||||||
|
return array("n", value);
|
||||||
|
end
|
||||||
End;
|
End;
|
||||||
|
|
||||||
private
|
private
|
||||||
@@ -286,7 +336,61 @@ private
|
|||||||
End
|
End
|
||||||
|
|
||||||
private
|
private
|
||||||
sheet_; //XmlSheet对象
|
[weakref]file_; //TSXlsxFile对象
|
||||||
file_; //TSExcelFile对象
|
style_xml_file_;
|
||||||
styleXmlFile_; //xmlFile对象
|
style_; // 缓存style
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
// 参考:https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.numberingformat?view=openxml-3.0.1
|
||||||
|
// 0 General
|
||||||
|
// 1 0
|
||||||
|
// 2 0.00
|
||||||
|
// 3 #,##0
|
||||||
|
// 4 #,##0.00
|
||||||
|
// 5 整数,货币符号旁边($#,##0_);($#,##0))
|
||||||
|
// 6 带两位小数的货币符号($#,##0.00_);($#,##0.00)
|
||||||
|
// 7 整数,带括号表示负数($#,##0_);Red
|
||||||
|
// 8 带两位小数的货币符号和红色负数($#,##0.00_);Red
|
||||||
|
// 9 0%
|
||||||
|
// 10 0.00%
|
||||||
|
// 11 0.00E+00
|
||||||
|
// 12 # ?/?
|
||||||
|
// 13 # ??/??
|
||||||
|
// 14 mm-dd-yy
|
||||||
|
// 15 d-mmm-yy
|
||||||
|
// 16 d-mmm
|
||||||
|
// 17 mmm-yy
|
||||||
|
// 18 h:mm AM/PM
|
||||||
|
// 19 h:mm:ss AM/PM
|
||||||
|
// 20 h:mm
|
||||||
|
// 21 h:mm:ss
|
||||||
|
// 22 m/d/yy h:mm
|
||||||
|
// 27 [$-404]e/m/d yyyy"年"m"月"
|
||||||
|
// 28 [$-404]e"年"m"月"d"日" m"月"d"日"
|
||||||
|
// 29 [$-404]e"年"m"月"d"日" m"月"d"日"
|
||||||
|
// 30 m/d/yy m-d-yy
|
||||||
|
// 31 yyyy"年"m"月"d"日" yyyy"年"m"月"d"日"
|
||||||
|
// 32 hh"時"mm"分" h"时"mm"分"
|
||||||
|
// 33 hh"時"mm"分"ss"秒" h"时"mm"分"ss"秒"
|
||||||
|
// 34 上午/下午hh"時"mm"分" 上午/下午h"时"mm"分"
|
||||||
|
// 35 上午/下午hh"時"mm"分"ss"秒" 上午/下午h"时"mm"分"ss"秒"
|
||||||
|
// 36 [$-404]e/m/d yyyy"年"m"月"
|
||||||
|
// 37 #,##0 ;(#,##0)
|
||||||
|
// 38 #,##0 ;[Red](#,##0)
|
||||||
|
// 39 #,##0.00;(#,##0.00)
|
||||||
|
// 40 #,##0.00;[Red](#,##0.00)
|
||||||
|
// 45 mm:ss
|
||||||
|
// 46 [h]:mm:ss
|
||||||
|
// 47 mmss.0
|
||||||
|
// 48 ##0.0E+0
|
||||||
|
// 49 @(文本)
|
||||||
|
// 50 [$-404]e/m/d yyyy"年"m"月"
|
||||||
|
// 51 [$-404]e"年"m"月"d"日" m"月"d"日"
|
||||||
|
// 52 上午/下午hh"時"mm"分" yyyy"年"m"月"
|
||||||
|
// 53 上午/下午hh"時"mm"分"ss"秒" m"月"d"日"
|
||||||
|
// 54 [$-404]e"年"m"月"d"日" m"月"d"日"
|
||||||
|
// 55 上午/下午hh"時"mm"分" 上午/下午h"时"mm"分"
|
||||||
|
// 56 上午/下午hh"時"mm"分"ss"秒" 上午/下午h"时"mm"分"ss"秒"
|
||||||
|
// 57 [$-404]e/m/d yyyy"年"m"月"
|
||||||
|
// 58 [$-404]e"年"m"月"d"日" m"月"d"日"
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ private
|
|||||||
name := "列" $ col_index++;
|
name := "列" $ col_index++;
|
||||||
excel_.WorkBook().SetCellValue(sheetName_, cell, name);
|
excel_.WorkBook().SetCellValue(sheetName_, cell, name);
|
||||||
end
|
end
|
||||||
table_str += fmt('<tableColumn id="{}" name="{}" />', id++, name);
|
table_str += format('<tableColumn id="%d" name="%s" />', id, name);
|
||||||
end
|
end
|
||||||
table_str += "</tableColumns>";
|
table_str += "</tableColumns>";
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ private
|
|||||||
|
|
||||||
private
|
private
|
||||||
sheetName_:string; //sheet名称
|
sheetName_:string; //sheet名称
|
||||||
excel_;//TSExcelFile对象
|
[weakref]excel_;//TSExcelFile对象
|
||||||
zipfile_;
|
zipfile_;
|
||||||
tableXmlFile_;
|
tableXmlFile_;
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ Type xlsxWorkBook = Class
|
|||||||
//workbook.Print();
|
//workbook.Print();
|
||||||
//workbook.Dump();
|
//workbook.Dump();
|
||||||
//echo tostn(workbook.dom());
|
//echo tostn(workbook.dom());
|
||||||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement();
|
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
|
||||||
while ifObj(node) do Begin
|
while ifObj(node) do Begin
|
||||||
name := node.GetAttribute("name");
|
name := node.GetAttribute("name");
|
||||||
sheetNames_[sheetsCount_]['name'] := name;
|
sheetNames_[sheetsCount_]['name'] := name;
|
||||||
@@ -50,7 +50,7 @@ Type xlsxWorkBook = Class
|
|||||||
sheetNames_[sheetsCount_]['file'] := 'xl/' + rids[ rid ];
|
sheetNames_[sheetsCount_]['file'] := 'xl/' + rids[ rid ];
|
||||||
sheetIndexMap_[ LowerCase(name) ] := sheetsCount_;
|
sheetIndexMap_[ LowerCase(name) ] := sheetsCount_;
|
||||||
sheetsCount_ ++;
|
sheetsCount_ ++;
|
||||||
node := node.NextElement();
|
node := node.NextElement('sheet');
|
||||||
End;
|
End;
|
||||||
|
|
||||||
files := zipfile_.Files();
|
files := zipfile_.Files();
|
||||||
@@ -108,7 +108,39 @@ Type xlsxWorkBook = Class
|
|||||||
Function SetCellValue(sheet, axis, val, opt);
|
Function SetCellValue(sheet, axis, val, opt);
|
||||||
Begin
|
Begin
|
||||||
o := GetSheetObj(sheet);
|
o := GetSheetObj(sheet);
|
||||||
if ifObj(o) then return o.SetCellValue(axis, val, opt);
|
if ifObj(o) then
|
||||||
|
ret := o.SetCellValue(axis, val, opt);
|
||||||
|
return ret;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function SetCellStyleOpt(sheet, axis, opt);
|
||||||
|
Begin
|
||||||
|
o := GetSheetObj(sheet);
|
||||||
|
if ifObj(o) then
|
||||||
|
begin
|
||||||
|
if ifnil(opt['s']) and not o.CellIsExists(axis) then
|
||||||
|
begin
|
||||||
|
[err, col, row] := CellNameToCoordinates(axis);
|
||||||
|
xml := GetSheetXmlFile(sheet);
|
||||||
|
cols_node := xml.FirstChildElement('worksheet').FirstChildElement('cols');
|
||||||
|
if ifObj(cols_node) then
|
||||||
|
begin
|
||||||
|
col_node := cols_node.FirstChildElement();
|
||||||
|
while ifObj(col_node) do
|
||||||
|
begin
|
||||||
|
min := strtoint(col_node.GetAttribute('min'));
|
||||||
|
max := strtoint(col_node.GetAttribute('max'));
|
||||||
|
style := col_node.GetAttribute('style');
|
||||||
|
if col >= min and col <= max and style <> '' then
|
||||||
|
begin
|
||||||
|
opt['s'] := style;
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
col_node := col_node.NextElement();
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function GetCellRichText(sheet, axis);
|
Function GetCellRichText(sheet, axis);
|
||||||
@@ -146,7 +178,7 @@ Type xlsxWorkBook = Class
|
|||||||
data := o.Import(topLeft, bottomRight, includeHeader, includeIndex, forceSingle);
|
data := o.Import(topLeft, bottomRight, includeHeader, includeIndex, forceSingle);
|
||||||
if not TOfficeApi().IsUtf8() then
|
if not TOfficeApi().IsUtf8() then
|
||||||
begin
|
begin
|
||||||
fields := fieldnames(data);
|
fields := mcols(data, 1);
|
||||||
if ifarray(fields) and length(fields) then
|
if ifarray(fields) and length(fields) then
|
||||||
begin
|
begin
|
||||||
map := array();
|
map := array();
|
||||||
@@ -166,62 +198,142 @@ Type xlsxWorkBook = Class
|
|||||||
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.';
|
||||||
rid := getWorkbookRelsRid();
|
|
||||||
|
|
||||||
|
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||||||
|
sheetId := addSheetN(fname);
|
||||||
|
rid := setWorkbookRels();
|
||||||
|
setWorkbookSheet(sheet, sheetId, rid);
|
||||||
|
setDocPropsApp(sheet);
|
||||||
|
setContentTypes(fname);
|
||||||
|
|
||||||
|
sheetNames_[sheetsCount_]['name'] := sheet;
|
||||||
|
sheetNames_[sheetsCount_]['sheetId'] := sheetId;
|
||||||
|
sheetNames_[sheetsCount_]['rid'] := rid;
|
||||||
|
sheetNames_[sheetsCount_]['file'] := fname;
|
||||||
|
sheetIndexMap_[ lname ] := sheetsCount_;
|
||||||
|
sheetsCount_ ++;
|
||||||
|
SetDefaultSheet(sheet);
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function addSheetN(fname);
|
||||||
|
Begin
|
||||||
//添加文件xl/worksheets/sheetN.xml
|
//添加文件xl/worksheets/sheetN.xml
|
||||||
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
|
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
|
||||||
sheetId := integer(sheetId) + 1;
|
sheetId := integer(sheetId) + 1;
|
||||||
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
|
||||||
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
|
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
|
||||||
|
return sheetId;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function setWorkbookRels();
|
||||||
|
Begin
|
||||||
|
rid := getWorkbookRelsRid();
|
||||||
//设置 workbook.xml.rels
|
//设置 workbook.xml.rels
|
||||||
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
||||||
rels := workbook_rels.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship');
|
rels := workbook_rels.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship');
|
||||||
rels.SetAttribute('Target', getTarget( sheetsCount_ + 1));
|
rels.SetAttribute('Target', getTarget( sheetsCount_ + 1));
|
||||||
rels.SetAttribute('Type', class(TSXml).GetTemplate('RelationshipWorkSheet'));
|
rels.SetAttribute('Type', class(TSXml).GetTemplate('RelationshipWorkSheet'));
|
||||||
rels.SetAttribute('Id', rid);
|
rels.SetAttribute('Id', rid);
|
||||||
//workbook_rels.Print;
|
return rid;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function setWorkbookSheet(sheetName, sheetId, rid);
|
||||||
|
Begin
|
||||||
//设置 xl/workbook.xml
|
//设置 xl/workbook.xml
|
||||||
workbook := GetXmlFileObj('xl/workbook.xml');
|
workbook := GetXmlFileObj('xl/workbook.xml');
|
||||||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
|
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
|
||||||
node.SetAttribute('name', sheet);
|
node.SetAttribute('name', sheetName);
|
||||||
node.SetAttribute('sheetId', sheetId);
|
node.SetAttribute('sheetId', sheetId);
|
||||||
node.SetAttribute('r:id', rid);
|
node.SetAttribute('r:id', rid);
|
||||||
//workbook.Print();
|
End;
|
||||||
|
|
||||||
|
Function setDocPropsApp(sheet);
|
||||||
|
Begin
|
||||||
//设置docProps/app.xml
|
//设置docProps/app.xml
|
||||||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||||||
//app.Print();
|
properties_node := app.FirstChildElement('Properties');
|
||||||
node := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts');
|
// HeadingPairs
|
||||||
if not ifObj(node) then Begin
|
variant_node := class(TSXml).GetNode(properties_node, 'HeadingPairs/vt:vector/vt:variant');
|
||||||
node := app.FirstChildElement('Properties').InsertEndChild('element','TitlesOfParts');
|
while ifObj(variant_node) do
|
||||||
End;
|
begin
|
||||||
vector := node.FirstChildElement('vt:vector');
|
vt_node := variant_node.FirstChildElement('vt:i4');
|
||||||
if not ifObj(vector) then Begin
|
if ifObj(vt_node) then
|
||||||
vector := node.InsertEndChild('element', 'vt:vector');
|
begin
|
||||||
vector.SetAttribute('baseType', 'lpstr');
|
vt_node.SetValue(length(sheetNames_) + 1);
|
||||||
vector.SetAttribute('size', length(sheetNames_) + 1);
|
break;
|
||||||
for i:=0 to length(sheetNames_)-1 do Begin
|
end
|
||||||
vector.InsertEndChild('element', 'vt:lpstr', sheetNames_[i]['name']);
|
variant_node := variant_node.NextElement();
|
||||||
End;
|
end
|
||||||
End
|
|
||||||
else
|
// TitlesOfParts
|
||||||
|
vector := class(TSXml).GetNode(properties_node, 'TitlesOfParts/vt:vector');
|
||||||
vector.SetAttribute('size', length(sheetNames_) + 1);
|
vector.SetAttribute('size', length(sheetNames_) + 1);
|
||||||
vector.InsertEndChild('element', 'vt:lpstr', sheet);
|
vector.InsertEndChild('element', 'vt:lpstr', sheet);
|
||||||
//app.Print();
|
End;
|
||||||
|
|
||||||
|
Function setContentTypes(fname);
|
||||||
|
Begin
|
||||||
//设置[Content_Types].xml
|
//设置[Content_Types].xml
|
||||||
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
||||||
class(TSXml).AddOverrideContentType(content_xml, '/' + fname, class(TSXml).GetTemplate('sheetContentType'));
|
class(TSXml).AddOverrideContentType(content_xml, '/' + fname, class(TSXml).GetTemplate('sheetContentType'));
|
||||||
|
End;
|
||||||
|
|
||||||
sheetNames_[sheetsCount_]['name'] := sheet;
|
Function insertWorkbookSheet(targetSheetName, newSheetName, sheetId, rId, direction);
|
||||||
sheetNames_[sheetsCount_]['sheetId'] := sheetId;
|
Begin
|
||||||
sheetNames_[sheetsCount_]['rid'] := rid;
|
workbook := GetXmlFileObj('xl/workbook.xml');
|
||||||
sheetNames_[sheetsCount_]['file'] := fname;
|
node := class(TSXml).GetNode(workbook, 'workbook/sheets');
|
||||||
sheetIndexMap_[ LowerCase(sheet) ] := sheetsCount_;
|
sheet_node := node.FirstChildElement('sheet');
|
||||||
sheetsCount_ ++;
|
while ifObj(sheet_node) do
|
||||||
SetDefaultSheet(sheet);
|
begin
|
||||||
|
if sheet_node.GetAttribute('name') = targetSheetName then
|
||||||
|
begin
|
||||||
|
if direction = "after" then
|
||||||
|
sheet_node := node.InsertAfterChild(sheet_node, 'element', 'sheet');
|
||||||
|
else
|
||||||
|
sheet_node := node.InsertBeforeChild(sheet_node, 'element', 'sheet');
|
||||||
|
sheet_node.SetAttribute('name', newSheetName);
|
||||||
|
sheet_node.SetAttribute('sheetId', sheetId);
|
||||||
|
sheet_node.SetAttribute('r:id', rid);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
sheet_node := sheet_node.NextElement();
|
||||||
|
end
|
||||||
|
End;
|
||||||
|
|
||||||
|
Function insertDocPropsApp(targetSheetName, newSheetName, direction);
|
||||||
|
Begin
|
||||||
|
//设置docProps/app.xml
|
||||||
|
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||||||
|
properties_node := app.FirstChildElement('Properties');
|
||||||
|
// HeadingPairs
|
||||||
|
variant_node := class(TSXml).GetNode(properties_node, 'HeadingPairs/vt:vector/vt:variant');
|
||||||
|
while ifObj(variant_node) do
|
||||||
|
begin
|
||||||
|
vt_node := variant_node.FirstChildElement('vt:i4');
|
||||||
|
if ifObj(vt_node) then
|
||||||
|
begin
|
||||||
|
vt_node.SetValue(length(sheetNames_) + 1);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
variant_node := variant_node.NextElement();
|
||||||
|
end
|
||||||
|
|
||||||
|
// TitlesOfParts
|
||||||
|
vector := class(TSXml).GetNode(properties_node, 'TitlesOfParts/vt:vector');
|
||||||
|
vector.SetAttribute('size', length(sheetNames_) + 1);
|
||||||
|
lpstr := vector.FirstChildElement('vt:lpstr');
|
||||||
|
while ifObj(lpstr) do
|
||||||
|
begin
|
||||||
|
if LowerCase(lpstr.GetText()) = LowerCase(targetSheetName) then
|
||||||
|
begin
|
||||||
|
if direction = 'after' then
|
||||||
|
lpstr := vector.InsertAfterChild(lpstr, 'element', 'vt:lpstr');
|
||||||
|
else
|
||||||
|
lpstr := vector.InsertBeforeChild(lpstr, 'element', 'vt:lpstr');
|
||||||
|
lpstr.SetValue(newSheetName);
|
||||||
|
break;
|
||||||
|
end
|
||||||
|
lpstr := lpstr.NextElement();
|
||||||
|
end
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Function NewSheet(sourceSheet, destSheet);overload;
|
Function NewSheet(sourceSheet, destSheet);overload;
|
||||||
@@ -231,60 +343,12 @@ Type xlsxWorkBook = Class
|
|||||||
sname := LowerCase(sourceSheet);
|
sname := LowerCase(sourceSheet);
|
||||||
if not ifint(sheetIndexMap_[ sname ]) then return 'sourceSheet does not exists';
|
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';
|
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||||||
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
|
sheetId := addSheetN(fname);
|
||||||
|
rid := setWorkbookRels();
|
||||||
//设置 workbook.xml.rels
|
insertWorkbookSheet(sourceSheet, destSheet, sheetId, rid, 'after');
|
||||||
rid := getWorkbookRelsRid();
|
insertDocPropsApp(sourceSheet, destSheet, 'after');
|
||||||
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
setContentTypes(fname);
|
||||||
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];
|
ind := sheetIndexMap_[sname];
|
||||||
for i:=sheetsCount_ downto ind+2 do
|
for i:=sheetsCount_ downto ind+2 do
|
||||||
@@ -311,66 +375,12 @@ Type xlsxWorkBook = Class
|
|||||||
sname := LowerCase(sourceSheet);
|
sname := LowerCase(sourceSheet);
|
||||||
if not ifint(sheetIndexMap_[ sname ]) then return 'sourceSheet does not exists';
|
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';
|
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||||||
zipfile_.Add(fname, class(TSXml).XmlHeader() + class(TSXml).GetTemplate('sheet1'));
|
sheetId := addSheetN(fname);
|
||||||
|
rid := setWorkbookRels();
|
||||||
//设置 workbook.xml.rels
|
insertWorkbookSheet(sourceSheet, destSheet, sheetId, rid, 'before');
|
||||||
rid := getWorkbookRelsRid();
|
insertDocPropsApp(sourceSheet, destSheet, 'before');
|
||||||
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
setContentTypes(fname);
|
||||||
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');
|
|
||||||
prev_node := nil;
|
|
||||||
while ifObj(sheet_node) do
|
|
||||||
begin
|
|
||||||
if LowerCase(sheet_node.GetAttribute('name')) = LowerCase(sourceSheet) then
|
|
||||||
begin
|
|
||||||
if ifnil(prev_node) then sheet_node := node.InsertFirstChild('element', 'sheet');
|
|
||||||
else sheet_node := node.InsertAfterChild(prev_node, 'element', 'sheet');
|
|
||||||
sheet_node.SetAttribute('name', destSheet);
|
|
||||||
sheet_node.SetAttribute('sheetId', sheetId);
|
|
||||||
sheet_node.SetAttribute('r:id', rid);
|
|
||||||
break;
|
|
||||||
end
|
|
||||||
prev_node := sheet_node;
|
|
||||||
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');
|
|
||||||
pstr := nil;
|
|
||||||
while ifObj(lpstr) do
|
|
||||||
begin
|
|
||||||
if LowerCase(lpstr.GetText()) = LowerCase(sourceSheet) then
|
|
||||||
begin
|
|
||||||
if ifnil(pstr) then lpstr := vector.InsertFirstChild('element', 'vt:lpstr');
|
|
||||||
else lpstr := vector.InsertAfterChild(pstr, 'element', 'vt:lpstr');
|
|
||||||
lpstr.SetValue(destSheet);
|
|
||||||
break;
|
|
||||||
end
|
|
||||||
pstr := lpstr;
|
|
||||||
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];
|
ind := sheetIndexMap_[sname];
|
||||||
for i:=sheetsCount_ downto ind+1 do
|
for i:=sheetsCount_ downto ind+1 do
|
||||||
@@ -409,7 +419,8 @@ Type xlsxWorkBook = Class
|
|||||||
for i:=0 to length(sheetNames_)-1 do Begin
|
for i:=0 to length(sheetNames_)-1 do Begin
|
||||||
sheetNames_[i]['rid'] := 'rId' + inttostr(i + 1); //重置rId
|
sheetNames_[i]['rid'] := 'rId' + inttostr(i + 1); //重置rId
|
||||||
oldname := sheetNames_[i]['file'];
|
oldname := sheetNames_[i]['file'];
|
||||||
newname := sheetPrefix_ + inttostr(i + 1) + '.xml';
|
fdir := ExtractFileDir(oldname);
|
||||||
|
newname := fdir + "/" + "sheet" + inttostr(i + 1) + '.xml';
|
||||||
sheetNames_[i]['file'] := newname;
|
sheetNames_[i]['file'] := newname;
|
||||||
if oldname <> newname then Begin
|
if oldname <> newname then Begin
|
||||||
n := vselect thisrowindex from files where ['FileName'] = oldname end;
|
n := vselect thisrowindex from files where ['FileName'] = oldname end;
|
||||||
@@ -463,7 +474,7 @@ Type xlsxWorkBook = Class
|
|||||||
node.SetAttribute('sheetId', sheetNames_[i]['sheetId']);
|
node.SetAttribute('sheetId', sheetNames_[i]['sheetId']);
|
||||||
node.SetAttribute('r:id', sheetNames_[i]['rid']);
|
node.SetAttribute('r:id', sheetNames_[i]['rid']);
|
||||||
End;
|
End;
|
||||||
//workbook.Print();
|
// workbook.Print();
|
||||||
|
|
||||||
//设置docProps/app.xml
|
//设置docProps/app.xml
|
||||||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||||||
@@ -512,15 +523,19 @@ Type xlsxWorkBook = Class
|
|||||||
|
|
||||||
Function CopySheet(sourceSheet, destSheet);
|
Function CopySheet(sourceSheet, destSheet);
|
||||||
Begin
|
Begin
|
||||||
ind := sheetIndexMap_[ LowerCase(destSheet) ];
|
|
||||||
if ifint(ind) then return destSheet $ ' already exists.';
|
|
||||||
ind := sheetIndexMap_[ LowerCase(sourceSheet) ];
|
ind := sheetIndexMap_[ LowerCase(sourceSheet) ];
|
||||||
if not ifint(ind) then return sourceSheet $ ' does not exists.';
|
if not ifint(ind) then return sourceSheet $ ' does not exists.';
|
||||||
|
dest_ind := sheetIndexMap_[ LowerCase(destSheet) ];
|
||||||
|
|
||||||
//copy sheet
|
//copy sheet
|
||||||
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
|
if ifint(dest_ind) then
|
||||||
sheetId := integer(sheetId) + 1;
|
begin
|
||||||
|
fname := sheetNames_[dest_ind]['file'];
|
||||||
|
zipfile_.Remove(fname);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
fname := sheetPrefix_ $ inttostr(sheetsCount_ + 1) $ '.xml';
|
||||||
|
end
|
||||||
sheet := GetSheetXmlFile(sourceSheet);
|
sheet := GetSheetXmlFile(sourceSheet);
|
||||||
zipfile_.Add(fname, sheet.Data());
|
zipfile_.Add(fname, sheet.Data());
|
||||||
xml_file := GetXmlFileObj(fname);
|
xml_file := GetXmlFileObj(fname);
|
||||||
@@ -549,7 +564,14 @@ Type xlsxWorkBook = Class
|
|||||||
sheet_rels := GetSheetRelsFile(sourceSheet);
|
sheet_rels := GetSheetRelsFile(sourceSheet);
|
||||||
if ifObj(sheet_rels) then
|
if ifObj(sheet_rels) then
|
||||||
begin
|
begin
|
||||||
|
if ifint(dest_ind) then
|
||||||
|
begin
|
||||||
|
rels_name := 'xl/worksheets/_rels/' + ExtractFileName(sheetNames_[dest_ind]['file']) + '.rels';
|
||||||
|
zipfile_.Remove(rels_name);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
rels_name := 'xl/worksheets/_rels/' + 'sheet' + inttostr(sheetsCount_ + 1) + '.xml.rels';
|
rels_name := 'xl/worksheets/_rels/' + 'sheet' + inttostr(sheetsCount_ + 1) + '.xml.rels';
|
||||||
|
end
|
||||||
zipfile_.Add(rels_name, sheet_rels.Data());
|
zipfile_.Add(rels_name, sheet_rels.Data());
|
||||||
rels_file := GetXmlFileObj(rels_name);
|
rels_file := GetXmlFileObj(rels_name);
|
||||||
relationship := rels_file.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
relationship := rels_file.FirstChildElement('Relationships').FirstChildElement('Relationship');
|
||||||
@@ -576,6 +598,8 @@ Type xlsxWorkBook = Class
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if ifint(dest_ind) then return;
|
||||||
|
|
||||||
//workbook.xml.rels
|
//workbook.xml.rels
|
||||||
rid := getWorkbookRelsRid();
|
rid := getWorkbookRelsRid();
|
||||||
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
workbook_rels := GetXmlFileObj('xl/_rels/workbook.xml.rels');
|
||||||
@@ -585,6 +609,8 @@ Type xlsxWorkBook = Class
|
|||||||
rels.SetAttribute('Id', rid);
|
rels.SetAttribute('Id', rid);
|
||||||
|
|
||||||
//xl/workbook.xml
|
//xl/workbook.xml
|
||||||
|
sheetId := vselect maxof(['sheetId']) from sheetNames_ end;
|
||||||
|
sheetId := integer(sheetId) + 1;
|
||||||
workbook := GetXmlFileObj('xl/workbook.xml');
|
workbook := GetXmlFileObj('xl/workbook.xml');
|
||||||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
|
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').InsertEndChild('element','sheet');
|
||||||
node.SetAttribute('name', destSheet);
|
node.SetAttribute('name', destSheet);
|
||||||
@@ -593,9 +619,17 @@ Type xlsxWorkBook = Class
|
|||||||
|
|
||||||
//app.xml
|
//app.xml
|
||||||
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
app := GetXmlFileObj(class(TSXml).GetFileName('docProps_app'));
|
||||||
vector := app.FirstChildElement('Properties').FirstChildElement('TitlesOfParts').FirstChildElement('vt:vector');
|
prop := app.FirstChildElement('Properties');
|
||||||
vector.SetAttribute('size', sheetId);
|
vector := prop.FirstChildElement('TitlesOfParts').FirstChildElement('vt:vector');
|
||||||
|
vector.SetAttribute('size', sheetsCount_+1);
|
||||||
vector.InsertEndChild('element', 'vt:lpstr', destSheet);
|
vector.InsertEndChild('element', 'vt:lpstr', destSheet);
|
||||||
|
vector := prop.FirstChildElement('HeadingPairs').FirstChildElement('vt:vector');
|
||||||
|
if ifObj(vector) then
|
||||||
|
begin
|
||||||
|
variant := vector.FirstChildElement('vt:variant').NextElement('vt:variant');
|
||||||
|
i4 := variant.FirstChildElement('vt:i4');
|
||||||
|
i4.SetValue(sheetsCount_ + 1);
|
||||||
|
end
|
||||||
|
|
||||||
//[Content_Types].xml
|
//[Content_Types].xml
|
||||||
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
content_xml := GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
|
||||||
@@ -726,23 +760,25 @@ Type xlsxWorkBook = Class
|
|||||||
Function SetSheetVisible(sheet, visible);
|
Function SetSheetVisible(sheet, visible);
|
||||||
Begin
|
Begin
|
||||||
workbook := GetXmlFileObj('xl/workbook.xml');
|
workbook := GetXmlFileObj('xl/workbook.xml');
|
||||||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
|
node := class(TSXml).GetNode(workbook, 'workbook/sheets/sheet');
|
||||||
hidden := visible = 1 ? 0 : 1;
|
if GetSheetsCount() = 1 then return "Only one sheet, can't set visible.";
|
||||||
default_sheet_name := GetDefaultSheet();
|
sheet := lowercase(sheet);
|
||||||
if default_sheet_name = sheet then
|
default_sheet_name := lowercase(GetDefaultSheet());
|
||||||
|
if default_sheet_name = sheet and not visible then
|
||||||
begin
|
begin
|
||||||
ind := sheetIndexMap_[LowerCase(default_sheet_name)];
|
ind := sheetIndexMap_[LowerCase(default_sheet_name)];
|
||||||
if ind = 0 then default_name := sheetNames_[ind + 1]['name'];
|
default_name := ind = 0 ? sheetNames_[1]['name'] : sheetNames_[ind - 1]['name'];
|
||||||
else default_name := sheetNames_[ind - 1]['name'];
|
|
||||||
SetDefaultSheet(default_name);
|
SetDefaultSheet(default_name);
|
||||||
end
|
end
|
||||||
|
if visible then SetDefaultSheet(sheet);
|
||||||
|
state := visible ? "nohidden" : "hidden";
|
||||||
while ifObj(node) do
|
while ifObj(node) do
|
||||||
Begin
|
Begin
|
||||||
name := node.GetAttribute('name');
|
name := lowercase(node.GetAttribute('name'));
|
||||||
if name = sheet then
|
if name = sheet then
|
||||||
Begin
|
Begin
|
||||||
if hidden then node.SetAttribute('state', 'hidden');
|
node.SetAttribute('state', state);
|
||||||
else node.DeleteAttribute('state');
|
break;
|
||||||
End
|
End
|
||||||
node := node.NextElement();
|
node := node.NextElement();
|
||||||
End
|
End
|
||||||
@@ -753,11 +789,12 @@ Type xlsxWorkBook = Class
|
|||||||
Begin
|
Begin
|
||||||
sheet_file := GetSheetXmlFile(sheet);
|
sheet_file := GetSheetXmlFile(sheet);
|
||||||
if not ifObj(sheet_file) then return 0;
|
if not ifObj(sheet_file) then return 0;
|
||||||
|
sheet := lowercase(sheet);
|
||||||
workbook := GetXmlFileObj('xl/workbook.xml');
|
workbook := GetXmlFileObj('xl/workbook.xml');
|
||||||
node := workbook.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
|
node := class(TSXml).GetNode(workbook, 'workbook/sheets/sheet');
|
||||||
while ifObj(node) do
|
while ifObj(node) do
|
||||||
Begin
|
Begin
|
||||||
name := node.GetAttribute('name');
|
name := lowercase(node.GetAttribute('name'));
|
||||||
if name = sheet then
|
if name = sheet then
|
||||||
Begin
|
Begin
|
||||||
val := node.GetAttribute('state');
|
val := node.GetAttribute('state');
|
||||||
@@ -863,6 +900,11 @@ Type xlsxWorkBook = Class
|
|||||||
Function SetRowHeight(sheet, row, height);
|
Function SetRowHeight(sheet, row, height);
|
||||||
Begin
|
Begin
|
||||||
obj := GetSheetObj(sheet);
|
obj := GetSheetObj(sheet);
|
||||||
|
if not obj.RowIsExists(row) then
|
||||||
|
begin
|
||||||
|
axis := CoordinatesToCellName(1, row, False)[1];
|
||||||
|
if not obj.CellIsExists(axis) then SetCellValue(sheet, axis, '');
|
||||||
|
end
|
||||||
obj.SetAttribute(row, array('ht': height, "customHeight": 1));
|
obj.SetAttribute(row, array('ht': height, "customHeight": 1));
|
||||||
End
|
End
|
||||||
|
|
||||||
@@ -952,7 +994,7 @@ Type xlsxWorkBook = Class
|
|||||||
col_node := work_node.FirstChildElement('cols');
|
col_node := work_node.FirstChildElement('cols');
|
||||||
default_width := work_node.FirstChildElement('sheetFormatPr').GetAttribute('defaultColWidth');
|
default_width := work_node.FirstChildElement('sheetFormatPr').GetAttribute('defaultColWidth');
|
||||||
default_width := trystrtofloat(default_width, r) ? r: -1;
|
default_width := trystrtofloat(default_width, r) ? r: -1;
|
||||||
if not ifObj(col_node) then return array(0, default_width);
|
if not ifObj(col_node) then return nil;
|
||||||
|
|
||||||
col_number := ColumnNameToNumber(col)[1];
|
col_number := ColumnNameToNumber(col)[1];
|
||||||
node := col_node.FirstChildElement('col');
|
node := col_node.FirstChildElement('col');
|
||||||
@@ -1104,29 +1146,17 @@ Type xlsxWorkBook = Class
|
|||||||
node := sheet_node.InsertFirstChild('element', 'sheetView');
|
node := sheet_node.InsertFirstChild('element', 'sheetView');
|
||||||
node.SetAttribute('workbookViewId', 0);
|
node.SetAttribute('workbookViewId', 0);
|
||||||
end
|
end
|
||||||
if name = sheet then
|
if lowercase(name) = lowercase(sheet) then
|
||||||
Begin
|
Begin
|
||||||
node.SetAttribute('tabselected', 1);
|
node.SetAttribute('tabSelected', 1);
|
||||||
workbook := GetXmlFileObj('xl/workbook.xml');
|
workbook := GetXmlFileObj('xl/workbook.xml');
|
||||||
workbook_node := workbook.FirstChildElement('workbook');
|
view_node := class(TSXml).GetNode(workbook, 'workbook/bookViews/workbookView');
|
||||||
book_view_node := workbook_node.FirstChildElement('bookViews');
|
|
||||||
if not ifObj(book_view_node) then
|
|
||||||
begin
|
|
||||||
prev_node := class(TSXml).GetWorkBookPrevNode(workbook_node, 'bookViews');
|
|
||||||
if not ifObj(prev_node) then book_view_node := workbook_node.InsertFirstChild('element', 'bookViews');
|
|
||||||
else book_view_node := workbook_node.InsertAfterChild(prev_node, 'element', 'bookViews');
|
|
||||||
end;
|
|
||||||
view_node := book_view_node.FirstChildElement('workbookView');
|
|
||||||
if not ifObj(view_node) then
|
|
||||||
begin
|
|
||||||
view_node := book_view_node.InsertFirstChild('element', 'workbookView');
|
|
||||||
end
|
|
||||||
view_node.SetAttribute('activeTab', ind);
|
view_node.SetAttribute('activeTab', ind);
|
||||||
End
|
End
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
node := root_node.FirstChildElement('sheetViews').FirstChildElement('sheetView');
|
node := root_node.FirstChildElement('sheetViews').FirstChildElement('sheetView');
|
||||||
node.SetAttribute('tabselected', 0);
|
node.SetAttribute('tabSelected', 0);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
End
|
End
|
||||||
@@ -1147,14 +1177,6 @@ Type xlsxWorkBook = Class
|
|||||||
|
|
||||||
Function ProtectSheet(sheet, protect);
|
Function ProtectSheet(sheet, protect);
|
||||||
Begin
|
Begin
|
||||||
if protect.AlgorithmName and protect.Password then
|
|
||||||
begin
|
|
||||||
protect.SaltValue := nil;//protect.Password;
|
|
||||||
protect.HashValue := nil;//GetMsgDigest(protect.SaltValue, 6);
|
|
||||||
protect.SpinCount := nil;
|
|
||||||
protect.Password := nil;
|
|
||||||
protect.AlgorithmName := nil;
|
|
||||||
end
|
|
||||||
sheet_obj := GetSheetXmlfile(sheet);
|
sheet_obj := GetSheetXmlfile(sheet);
|
||||||
work_node := sheet_obj.FirstChildElement('worksheet');
|
work_node := sheet_obj.FirstChildElement('worksheet');
|
||||||
sheet_protection_node := work_node.FirstChildElement('sheetProtection');
|
sheet_protection_node := work_node.FirstChildElement('sheetProtection');
|
||||||
@@ -1472,7 +1494,7 @@ Type xlsxWorkBook = Class
|
|||||||
if col >= min and col <= max then
|
if col >= min and col <= max then
|
||||||
Begin
|
Begin
|
||||||
level_val := node.GetAttribute('outlineLevel');
|
level_val := node.GetAttribute('outlineLevel');
|
||||||
if strtoint(level_val) = level then return;
|
if trystrtoint(level_val, r) and r = level then return;
|
||||||
else Begin
|
else Begin
|
||||||
if col = min and col = max then node.SetAttribute('outlineLevel', level);
|
if col = min and col = max then node.SetAttribute('outlineLevel', level);
|
||||||
else begin
|
else begin
|
||||||
@@ -1588,9 +1610,9 @@ private
|
|||||||
Function copyFile(obj, target, content);
|
Function copyFile(obj, target, content);
|
||||||
Begin
|
Begin
|
||||||
file_name := ReplaceStr(target, '..', 'xl');
|
file_name := ReplaceStr(target, '..', 'xl');
|
||||||
counts := GetFilesCount(ReplaceStrByReg(file_name, "\\d+.*ml", '')) + 1;
|
counts := GetFilesCount(ReplaceStrUsingReg(file_name, "\\d+.*ml", '')) + 1;
|
||||||
xml := GetXmlFileObj(file_name);
|
xml := GetXmlFileObj(file_name);
|
||||||
new_file_postfix := ReplaceStrByReg(file_name[3:], "\\d+", inttostr(counts));
|
new_file_postfix := ReplaceStrUsingReg(file_name[3:], "\\d+", inttostr(counts));
|
||||||
zipfile_.Add('xl' + new_file_postfix, xml.Data());
|
zipfile_.Add('xl' + new_file_postfix, xml.Data());
|
||||||
obj.SetAttribute('Target', '..' + new_file_postfix);
|
obj.SetAttribute('Target', '..' + new_file_postfix);
|
||||||
|
|
||||||
@@ -1602,11 +1624,22 @@ private
|
|||||||
return array(counts, 'xl' + new_file_postfix);
|
return array(counts, 'xl' + new_file_postfix);
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
function ReplaceStrUsingReg(s, regFromText, toText);
|
||||||
|
begin
|
||||||
|
ParseCtrls := 'r';
|
||||||
|
if ifnil(toText) then toText := '';
|
||||||
|
ParseRegExpr(RegFromText,s,ParseCtrls,toText,s2);
|
||||||
|
if ansicontainstext(ParseCtrls,'r') then //表替换,输出s2
|
||||||
|
return ifstring(s2)?s2:s;
|
||||||
|
else
|
||||||
|
return ifArray(toText) and length(toText) > 0 ? toText : array();
|
||||||
|
end;
|
||||||
|
|
||||||
sheetsCount_:integer;
|
sheetsCount_:integer;
|
||||||
sheetNames_;
|
sheetNames_;
|
||||||
sheetIndexMap_;
|
sheetIndexMap_;
|
||||||
sheetPrefix_:string;
|
sheetPrefix_:string;
|
||||||
zipfile_;
|
[weakref]zipfile_;
|
||||||
xmlFileObjMap_; //XmlFile对象存储
|
xmlFileObjMap_; //XmlFile对象存储
|
||||||
sheetObjMap_; //XmlSheet对象存储
|
sheetObjMap_; //XmlSheet对象存储
|
||||||
End;
|
End;
|
||||||
|
|||||||
@@ -1,5 +1,551 @@
|
|||||||
# 更新日志
|
# 更新日志
|
||||||
|
|
||||||
|
## 2026-09-10
|
||||||
|
|
||||||
|
### V1.8.8
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复`InsertFile`时,图片前有空格无法识别问题
|
||||||
|
|
||||||
|
## 2026-07-30
|
||||||
|
|
||||||
|
### V1.8.7
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复`InsertFile`时,样式重复导致wps/word识别失败从而渲染错误问题
|
||||||
|
|
||||||
|
## 2026-01-16
|
||||||
|
|
||||||
|
### V1.8.6
|
||||||
|
|
||||||
|
修复语法问题
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复`InsertTable`多行数据插入缺失问题
|
||||||
|
|
||||||
|
## 2025-12-15
|
||||||
|
|
||||||
|
### V1.8.5
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复插入word时,单元格内容不完整问题
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复`GetColWithd`返回值出现数组问题,没有设置宽度返回`nil`
|
||||||
|
|
||||||
|
## 2025-11-07
|
||||||
|
|
||||||
|
### V1.8.4
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复合并单元格时候设置属性不规范
|
||||||
|
|
||||||
|
## 2025-10-30
|
||||||
|
|
||||||
|
### V1.8.3
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. `setData`移除`fieldNames`依赖
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. `InsertTable/GetTable`移除`fieldNames` 依赖
|
||||||
|
|
||||||
|
## 2025-10-29
|
||||||
|
|
||||||
|
### V1.8.2
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 升级段落判空`Empty`
|
||||||
|
2. 修复`FileName`总是返回 gbk
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复`CopySheet`依赖的`ReplaceStrByReg`公共方法问题,不再依赖该方法
|
||||||
|
2. 修复`FileName`总是返回 gbk
|
||||||
|
|
||||||
|
## 2025-7-22
|
||||||
|
|
||||||
|
### V1.8.1
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. **feat**: 支持同一段落多图片文字
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
picture := TOfficeObj('TPicture');
|
||||||
|
picture.Descr := '插入图像案例';
|
||||||
|
picture.Image := TOfficeTemplate('tinysoft.gif',true);
|
||||||
|
|
||||||
|
docx := new TSDocxFile();
|
||||||
|
docx.NewFile();
|
||||||
|
p := new TOfficeObj('TParagraph');
|
||||||
|
r := p.AddRun();
|
||||||
|
r.SetText("abc");
|
||||||
|
r := p.AddRun();
|
||||||
|
r.SetDrawing(picture, docx); // 需要一个图片对象和TSDocxFile对象
|
||||||
|
r := p.AddRun();
|
||||||
|
r.SetText("def");
|
||||||
|
docx.AddParagraph(p, -1);
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2025-6-23
|
||||||
|
|
||||||
|
### V1.8.0
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. **feat**: 支持添加自定目录`TSDocxFile.AddCustomTableContent`
|
||||||
|
2. **fix**: 修复单元格内容换行,自定义属性失效问题
|
||||||
|
|
||||||
|
## 2025-2-28
|
||||||
|
|
||||||
|
### V1.7.9
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. **feat**:支持目录自定义宽度`TOfficeApi().Get("TTableContent-tab-position")`
|
||||||
|
2. **fix**:插入图片 id 计算错误,导致`office 2016 16.0.4266`版本不兼容
|
||||||
|
|
||||||
|
## 2025-1-22
|
||||||
|
|
||||||
|
### V1.7.8
|
||||||
|
|
||||||
|
❗ 解决`TSDocxFile`和`TSXlsxFile`内存泄露
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. **fix**:`CreateTable`由于`fieldnames.tsf`差异报错
|
||||||
|
|
||||||
|
## 2025-1-17
|
||||||
|
|
||||||
|
### V1.7.7
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. **feat**:`TPicture`对象设置画布大小`CanvasWidth`、`CanvasHeight`
|
||||||
|
2. **fix**:`InsertTable`表格数据不对齐报错
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. **fix**:`SetColOutlineLevel`错误
|
||||||
|
|
||||||
|
## 2025-1-8
|
||||||
|
|
||||||
|
### V1.7.6
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. **fix**:`SetRowHeight`单元格不存在无法设置
|
||||||
|
2. **fix**:`Set[Get]ColVisible`修改传入的列参数
|
||||||
|
|
||||||
|
## 2025-1-7
|
||||||
|
|
||||||
|
### V1.7.5
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 支持获取`sdt`标签类型的内容(如文本框),通过`TSDocxFile.Sdts()`获取文档的的所有`sdt`
|
||||||
|
|
||||||
|
> ```pascal
|
||||||
|
> sdts := docx.Sdts();
|
||||||
|
> paragraphs := sdts[0].Paragraphs();
|
||||||
|
> textbox := paragraphs[1].TextBoxs();
|
||||||
|
> ```
|
||||||
|
|
||||||
|
## 2024-12-23
|
||||||
|
|
||||||
|
### V1.7.4
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. `insertfile`时候默认添加`w16du`命名空间
|
||||||
|
|
||||||
|
## 2024-12-05
|
||||||
|
|
||||||
|
### V1.7.3
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. `insertfile`支持 ole 对象的插入,如 wmf 公式,excel 表格
|
||||||
|
|
||||||
|
## 2024-12-04
|
||||||
|
|
||||||
|
### V1.7.2
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 支持单元格标题生成到目录,需要额外设置`TOfficeApi().SetCellTableContent(true);`,默认是`false`
|
||||||
|
|
||||||
|
## 2024-11-19
|
||||||
|
|
||||||
|
### V1.7.1
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 对生成目录的 xml 结构进行更改
|
||||||
|
2. 修复引用 excel 错误
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复获取`comment`时候,换行符问题
|
||||||
|
|
||||||
|
## 2024-7-8
|
||||||
|
|
||||||
|
### V1.7.0
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复`CopySheet`操作后,文件报错问题
|
||||||
|
|
||||||
|
## 2024-5-6
|
||||||
|
|
||||||
|
### V1.6.9
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复单元格继承列样式失败问题
|
||||||
|
|
||||||
|
## 2024-4-12
|
||||||
|
|
||||||
|
### V1.6.8
|
||||||
|
|
||||||
|
### excel
|
||||||
|
|
||||||
|
1. 修复`SetCellValue`单元格对列样式的识别,不需要手动用格式刷对所有单元格刷新样式
|
||||||
|
|
||||||
|
## 2024-3-21
|
||||||
|
|
||||||
|
### V1.6.7
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 新增对象的`Delete`方法,可以通过`Delete(name)`删除对象的指定属性
|
||||||
|
2. 新增`TPageNumType`对象
|
||||||
|
3. 扩展`TDocSection`方法,`AppendReference`和`AddReference`,前者是对已有的`Section`对象添加`TReference`对象,而后者是对新的`Section`对象添加
|
||||||
|
|
||||||
|
## 2024-3-14
|
||||||
|
|
||||||
|
### V1.6.6
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复`TDocSection`节点获取错误
|
||||||
|
2. 支持分栏自定义宽度
|
||||||
|
|
||||||
|
## 2024-3-4
|
||||||
|
|
||||||
|
### V1.6.5
|
||||||
|
|
||||||
|
支持扩展扩展模块
|
||||||
|
|
||||||
|
### excel
|
||||||
|
|
||||||
|
1. 样式获取报错问题
|
||||||
|
|
||||||
|
### V1.6.4
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复`InsertTable`内容`\n`无换行问题
|
||||||
|
2. `TextBox`支持`Clear`清空内容
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复目录生成陷入死循环问题
|
||||||
|
|
||||||
|
## 2024-2-23
|
||||||
|
|
||||||
|
### V1.6.3
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复目录生成陷入死循环问题
|
||||||
|
|
||||||
|
## 2024-2-7
|
||||||
|
|
||||||
|
### V1.6.2
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复设置段落属性`TextAlignment`失败问题
|
||||||
|
|
||||||
|
## 2024-2-5
|
||||||
|
|
||||||
|
### V1.6.1
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复 excel 文件单元格原有类型与 tsl 类型转换报错问题(trystrtofloat)
|
||||||
|
|
||||||
|
## 2024-2-5
|
||||||
|
|
||||||
|
### V1.6.0
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 兼容 Excel2016,通过`NewSheet/InsertSheet`创建工作表不再提示修复错误
|
||||||
|
2. 修复带有表头的二维数组通过`InsertTable`写入数据只写入表头未写入数据问题
|
||||||
|
|
||||||
|
## 2024-1-31
|
||||||
|
|
||||||
|
### V1.5.9
|
||||||
|
|
||||||
|
修复`tsl`脚本格式为`utf8`时无法打开中文命名的文件
|
||||||
|
|
||||||
|
### V1.5.8
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 支持写入单元格内容时判断当前单元格的数据类型,并以单元格数据类型为准
|
||||||
|
|
||||||
|
## 2024-1-17
|
||||||
|
|
||||||
|
### V1.5.7
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复单元格写入浮点数数据 bug,如写入 0.0,excel 某些版本打开会显示 0.00000000000000000
|
||||||
|
|
||||||
|
## 2024-1-11
|
||||||
|
|
||||||
|
### V1.5.6
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复单元格写入浮点数数据,精度丢失问题
|
||||||
|
|
||||||
|
## 2023-12-29
|
||||||
|
|
||||||
|
### V1.5.5
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复生成的目录打开后重新生成页码可能产生页码失败问题
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复`InsertTable`与``SetCellValue`返回值问题
|
||||||
|
|
||||||
|
## 2023-12-18
|
||||||
|
|
||||||
|
### V1.5.4
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 优化`InsertTable`的写入效率
|
||||||
|
|
||||||
|
## 2023-12-11
|
||||||
|
|
||||||
|
### V1.5.3
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 支持写入单元格时且单元格不存在时,新的单元格会沿用设置的样式 ID(若有设置)
|
||||||
|
|
||||||
|
## 2023-12-1
|
||||||
|
|
||||||
|
### V1.5.2
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复公式中文转码问题
|
||||||
|
|
||||||
|
## 2023-11-15
|
||||||
|
|
||||||
|
### V1.5.1
|
||||||
|
|
||||||
|
1. 支持识别图片中含有`0xffc2`段的 jpg 格式的大小
|
||||||
|
|
||||||
|
## 2023-11-14
|
||||||
|
|
||||||
|
### V1.5.0
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 新增对脚注的支持,方法`TSDocxFile.FootnotesObject().Add`
|
||||||
|
2. `TSDocxFile.InsertFile`支持脚注插入
|
||||||
|
|
||||||
|
### excel
|
||||||
|
|
||||||
|
1. 升级`TSXlsxFile.CopySheet`
|
||||||
|
|
||||||
|
## 2023-10-16
|
||||||
|
|
||||||
|
### V1.4.9
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 新增`TSDocxFile.InsertFile`重载方法
|
||||||
|
2. 新增`Table.SetStyle`方法
|
||||||
|
|
||||||
|
## 2023-9-27
|
||||||
|
|
||||||
|
### V1.4.8
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 支持`Inserttable`时候加入对单元格样式的设置
|
||||||
|
2. 新增`TSDocxFile.LastParagraph`方法
|
||||||
|
3. 新增`TParagraph.PrevParagraph`方法
|
||||||
|
4. 性能优化
|
||||||
|
|
||||||
|
## 2023-9-22
|
||||||
|
|
||||||
|
### V1.4.7
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复项目符号属于样式时,生成目录无法识别出项目符号问题
|
||||||
|
|
||||||
|
## 2023-9-19
|
||||||
|
|
||||||
|
### V1.4.6
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复表格存在合并单元格,生成目录报错问题
|
||||||
|
2. 修复单元格添加 run 对象,设置样式不生效问题
|
||||||
|
3. 修复插入 word 后,中文样式重复问题
|
||||||
|
|
||||||
|
### excel
|
||||||
|
|
||||||
|
🔔 重要升级:`TSExcelFile`更名为`TSXlsxFile`,建议更改,旧名字现阶段仍可使用
|
||||||
|
|
||||||
|
1. 整理`NewSheet`和`SetSheetVisible`代码
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复`NewSheet`excel 打开遇到提示错误问题
|
||||||
|
|
||||||
|
## 2023-8-30
|
||||||
|
|
||||||
|
### V1.4.5
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 支持生成目录后返回目录对象的所有段落内容`目录对象.Paragraphs()`
|
||||||
|
|
||||||
|
#### excel
|
||||||
|
|
||||||
|
1. 修复`NewSheet`excel 打开遇到提示错误问题
|
||||||
|
|
||||||
|
## 2023-8-28
|
||||||
|
|
||||||
|
### V1.4.4
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复`insertFile`样式错误问题
|
||||||
|
2. 修复`insertFile`后删除段落再新增段落位置错误问题
|
||||||
|
3. 修复生成目录中文编码未转换导致 word 打开失败问题
|
||||||
|
|
||||||
|
## 2023-8-22
|
||||||
|
|
||||||
|
### V1.4.3
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
支持段落判空`TParagraph.Empty()`
|
||||||
|
|
||||||
|
## 2023-8-18
|
||||||
|
|
||||||
|
### V1.4.2
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
支持插入另一个 word 内容`InsertFile(alias, fileName, posOpt)`
|
||||||
|
|
||||||
|
## 2023-8-11
|
||||||
|
|
||||||
|
### V1.4.1
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
修复插入表格后,设置样式 ID 无法全部生效问题
|
||||||
|
|
||||||
|
## 2023-8-10
|
||||||
|
|
||||||
|
### V1.4.0
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
支持三级以内目录设置字体,一级目录样式 ID 为`TOC1`,二级目录样式 ID 为`TOC2`,三级为`TOC3`,通过样式设置相关属性即可修改目录字体
|
||||||
|
|
||||||
|
## 2023-8-7
|
||||||
|
|
||||||
|
### V1.3.9
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
支持`AddHeading`时传入样式 Id
|
||||||
|
|
||||||
|
## 2023-8-2
|
||||||
|
|
||||||
|
### V1.3.8
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
修复插入图片后,设置对齐失效问题
|
||||||
|
|
||||||
|
## 2023-7-26
|
||||||
|
|
||||||
|
### V1.3.7
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
新增表格获取高度和宽度方法`table.Height(row) table.Width(col)`
|
||||||
|
|
||||||
|
## 2023-7-19
|
||||||
|
|
||||||
|
### V1.3.6
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
新增对表格的行高设置`table.RowHeight(row, height)`
|
||||||
|
|
||||||
|
## 2023-7-14
|
||||||
|
|
||||||
|
### V1.3.5
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
段落字体大小设置调整,对齐 VBA 设置
|
||||||
|
|
||||||
|
## 2023-7-11
|
||||||
|
|
||||||
|
### V1.3.4
|
||||||
|
|
||||||
|
修复加密 Bug
|
||||||
|
|
||||||
|
## 2023-7-4
|
||||||
|
|
||||||
|
### V1.3.3
|
||||||
|
|
||||||
|
word/excel 新增加密方法`SetPassword`,升级`OpenFile(alias, fileName, Password)`
|
||||||
|
|
||||||
|
## 2023-6-26
|
||||||
|
|
||||||
|
### V1.3.2
|
||||||
|
|
||||||
|
修复.net 使用 rdo2 执行失败问题,使用 rdo2 时候,需调用`TOfficeInit()`初始化
|
||||||
|
|
||||||
|
#### word
|
||||||
|
|
||||||
|
1. 修复 word 模板`template.docx`执行失败问题
|
||||||
|
|
||||||
|
## 2023-6-20
|
||||||
|
|
||||||
|
更新部署方式,不再依赖`fmt_pubkrnl_plugin.dll`,详情见[README](./README.md)
|
||||||
|
|
||||||
## 2023-4-26
|
## 2023-4-26
|
||||||
|
|
||||||
### V1.3.1
|
### V1.3.1
|
||||||
@@ -14,7 +560,7 @@
|
|||||||
|
|
||||||
#### excel
|
#### excel
|
||||||
|
|
||||||
1. 支持excel程序设置字体样式粗体,斜体等此类问题的返回类型,如`style.Font.Bold`返回`true 或 false`
|
1. 支持 excel 程序设置字体样式粗体,斜体等此类问题的返回类型,如`style.Font.Bold`返回`true 或 false`
|
||||||
|
|
||||||
## 2023-4-4
|
## 2023-4-4
|
||||||
|
|
||||||
@@ -30,7 +576,7 @@
|
|||||||
|
|
||||||
#### excel
|
#### excel
|
||||||
|
|
||||||
1. 修复由.net客户端导出的excel兼容性问题,`SetColWidth`、`Set/GetDefaultSheet`、`SetSheetHeaderFooter`
|
1. 修复由.net 客户端导出的 excel 兼容性问题,`SetColWidth`、`Set/GetDefaultSheet`、`SetSheetHeaderFooter`
|
||||||
|
|
||||||
## 2023-3-23
|
## 2023-3-23
|
||||||
|
|
||||||
@@ -99,7 +645,7 @@
|
|||||||
|
|
||||||
#### excel
|
#### excel
|
||||||
|
|
||||||
1. Get相关方法重新Set后不再覆盖原有设置,影响方法如下`Set(Get)PageMargins`,`Set(Get)CellHyperLink`,`Set(Get)PageLayout`,`Set(Get)CalcOptions`,`Set(Get)DefaultFont`,`Set(Get)SheetViewOptions`
|
1. Get 相关方法重新 Set 后不再覆盖原有设置,影响方法如下`Set(Get)PageMargins`,`Set(Get)CellHyperLink`,`Set(Get)PageLayout`,`Set(Get)CalcOptions`,`Set(Get)DefaultFont`,`Set(Get)SheetViewOptions`
|
||||||
|
|
||||||
## 2023-2-23
|
## 2023-2-23
|
||||||
|
|
||||||
@@ -136,7 +682,7 @@
|
|||||||
1. 新增`LoadFromMem`, `SavaToMem`
|
1. 新增`LoadFromMem`, `SavaToMem`
|
||||||
2. 新增重载方法`NewSheet`
|
2. 新增重载方法`NewSheet`
|
||||||
3. 新增`SetCalcOptions`
|
3. 新增`SetCalcOptions`
|
||||||
4. 修复删除sheet报错问题
|
4. 修复删除 sheet 报错问题
|
||||||
|
|
||||||
## 2023-2-13
|
## 2023-2-13
|
||||||
|
|
||||||
@@ -172,7 +718,7 @@
|
|||||||
|
|
||||||
#### word
|
#### word
|
||||||
|
|
||||||
1. 修复获取段落样式ID失败问题
|
1. 修复获取段落样式 ID 失败问题
|
||||||
2. 修复文本框添加图片失败问题
|
2. 修复文本框添加图片失败问题
|
||||||
|
|
||||||
#### excel
|
#### excel
|
||||||
@@ -229,8 +775,8 @@
|
|||||||
|
|
||||||
#### word
|
#### word
|
||||||
|
|
||||||
1. 新增ExecInnerTSl
|
1. 新增 ExecInnerTSl
|
||||||
2. 新增修改chart图(数据)
|
2. 新增修改 chart 图(数据)
|
||||||
3. 修复`TNumbering::AddStyleByInnerXml`错误
|
3. 修复`TNumbering::AddStyleByInnerXml`错误
|
||||||
4. 完善帮助文档
|
4. 完善帮助文档
|
||||||
|
|
||||||
@@ -248,11 +794,11 @@
|
|||||||
|
|
||||||
#### word
|
#### word
|
||||||
|
|
||||||
1. 修复chart图兼容性问题
|
1. 修复 chart 图兼容性问题
|
||||||
|
|
||||||
### V1.0.6
|
### V1.0.6
|
||||||
|
|
||||||
中文自动转换API由`class(xlsxXml).CodePage('中文');`调整为`TOfficeApi().CodePage('中文');`
|
中文自动转换 API 由`class(xlsxXml).CodePage('中文');`调整为`TOfficeApi().CodePage('中文');`
|
||||||
|
|
||||||
## 2023-1-5
|
## 2023-1-5
|
||||||
|
|
||||||
@@ -262,15 +808,15 @@
|
|||||||
|
|
||||||
#### word
|
#### word
|
||||||
|
|
||||||
1. 修复 Properties执行报错
|
1. 修复 Properties 执行报错
|
||||||
2. 修复格式刷
|
2. 修复格式刷
|
||||||
|
|
||||||
#### excel
|
#### excel
|
||||||
|
|
||||||
1. 移除API `JoinCellName`
|
1. 移除 API `JoinCellName`
|
||||||
2. 修改`RGBToHSL`与`HSLToRGB`返回值
|
2. 修改`RGBToHSL`与`HSLToRGB`返回值
|
||||||
3. 修复获取超链接`GetCellHyperLink`失败问题
|
3. 修复获取超链接`GetCellHyperLink`失败问题
|
||||||
4. 修复一个对象新建文件,打开文件之后引发的xlsx文件错误问题
|
4. 修复一个对象新建文件,打开文件之后引发的 xlsx 文件错误问题
|
||||||
5. 修复`GetCoreProps`,`GetAppProps`失败问题
|
5. 修复`GetCoreProps`,`GetAppProps`失败问题
|
||||||
|
|
||||||
## 2022-12-30
|
## 2022-12-30
|
||||||
@@ -290,4 +836,4 @@
|
|||||||
5. 修复`SetRowVisible`,`GetRowVisible`,`SetSheetVisible`问题
|
5. 修复`SetRowVisible`,`GetRowVisible`,`SetSheetVisible`问题
|
||||||
|
|
||||||
如何设置字符集(中文支持)?
|
如何设置字符集(中文支持)?
|
||||||
★用户的脚本可能是UFT8格式,或可能是GBK码格式,系统提供API自动设置当前字符集环境:`class(xlsxXml).CodePage('中文');` 在文件头设置该代码后,系统会自动检测当前的环境字符集
|
★ 用户的脚本可能是 UFT8 格式,或可能是 GBK 码格式,系统提供 API 自动设置当前字符集环境:`class(xlsxXml).CodePage('中文');` 在文件头设置该代码后,系统会自动检测当前的环境字符集
|
||||||
|
|||||||
Reference in New Issue
Block a user