This commit is contained in:
csh 2023-01-12 16:05:44 +08:00
parent e2db550f99
commit ce521a6a69
18 changed files with 204 additions and 206 deletions

View File

@ -1,127 +0,0 @@
docx := new TSDocxFile();
//_test_readParagraphs(docx);
_test_newfile(docx);
//_test_addtable(docx);
//_test_Properties(docx);
//_test_picture(docx);
Function _test_picture(docx);
Begin
[err, errmsg] := docx.NewFile();
if err then
return echo 'Open Fail:', errmsg, '\n';
picture := TOfficeObj('TPicture');
picture.Descr := 'Hans Tan\'s Picture test';
readfile(rwbinary(), '', 'F:\\temp\\VS2010Ultim\\Setup\\banner.bmp', 0, 1024*1024, data);
picture.Image := data;
p := docx.AddPicture(picture, -1);
v := docx.SaveAs('', 'f:\\temp\\p.docx');
println('Save={}', v);
End;
Function _test_Properties(docx);
Begin
f := 'F:\\temp\\test.docx';
[err, errmsg] := docx.OpenFile('', f);
if err then return
echo 'Open Fail:', errmsg, '\n';
core := docx.Properties();
core.Author := 'Hans Tan';
core.Modified := now();
docx.SaveAs('', 'f:\\temp\\core.docx');
End;
Function _test_addtable(docx);
Begin
[err, errmsg] := docx.NewFile();
if err then return
echo 'Open Fail:', errmsg, '\n';
data := array(("Name":"Small","Apple":2,"Orange":3,"Pear":3),
("Name":"Normal","Apple":5,"Orange":2,"Pear":4),
("Name":"Large","Apple":6,"Orange":7,"Pear":8));
tbl := docx.CreateTable(data, true, true);
//tbl.TblPr.Style := 1;
tbl := docx.InsertTable(tbl, -1);
v := docx.SaveAs('', 'f:\\temp\\t.docx');
println('Save={}', v);
End;
Function _test_newfile(docx);
Begin
[err, errmsg] := docx.NewFile();
if err then return
echo 'Open Fail:', errmsg, '\n';
paragraph := TOfficeObj('TParagraph');
paragraph.Run.Text := 'This is the 1 Line.';
p := docx.AddParagraph(paragraph, -1);
p := docx.AddLineBreak(p);
p := docx.AddLineBreak(p);
paragraph.Run.Text := 'This is the 2 Line.';
p := docx.AddParagraph(paragraph, -1);
p := docx.AddPageBreak(p);
paragraph.Run.Text := 'This is the 3 Line.';
p := docx.AddParagraph(paragraph, -1);
p := docx.AddColumnBreak(p);
paragraph.Run.Text := '';
p := docx.AddParagraph(paragraph, -1);
p.SetText('This is the 4 Line\nline5\nline6\nline7.');
v := docx.SaveAs('', 'f:\\temp\\new.docx');
println('Save={}', v);
End;
Function _test_readParagraphs(docx);
Begin
f := 'F:\\temp\\test.docx';
[err, errmsg] := docx.OpenFile('', f);
if err then return
echo 'Open Fail:', errmsg, '\n';
paragraph := TOfficeObj('TParagraph');
paragraph.Run.Text := 'New paragraph';
v := docx.AddParagraph(paragraph, 0);
paragraphs := docx.Paragraphs();
println("AddParagraph={}", v);
paragraphs[9].SetText('1、修改文字
2、第2段
3、第3段
4、第4段。');
paragraphs := docx.Paragraphs();
for i:=0 to length(paragraphs)-1 do Begin
println('Name={}, Text={}', paragraphs[i].Name(), paragraphs[i].Text());
End;
tcnt := docx.TablesCount();
println('\n\nTableCount={}',tcnt);
for i := 0 to tcnt-1 do Begin
table := docx.GetTable(i);
for j := 0 to table.Rows()-1 do Begin
for k := 0 to table.Cols()-1 do Begin
cell := table.Cell(j, k);
if ifObj(cell) then Begin
println('row={}, col={}, text={}', j, k, cell.Text());
continue;
End;
println('row={}, col={}, Cell=nil', j, k);
End;
End;
End;
println('all text={}, textArray={}', docx.Text(), docx.TextArray());
docx.SaveAs('', 'f:\\temp\\p.docx');
End;

View File

@ -59,6 +59,9 @@ _14_TDocxChart(docx);
///TOfficeApi ///TOfficeApi
_15_TOfficeApi(docx); _15_TOfficeApi(docx);
///ExecInnerTSL
_16_Template(docx);
///附注 ///附注
_Annotation(docx); _Annotation(docx);
@ -68,7 +71,7 @@ _Faq(docx);
///目录 ///目录
docx.AddTableContent(paragraphTitle, 1, 3); docx.AddTableContent(paragraphTitle, 1, 3);
v := docx.SaveAs('', UTF8ToAnsi('DocxFile使用帮助.docx')); v := docx.SaveAs('', TOfficeApi().CurCodePageToGBK('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);
@ -801,12 +804,32 @@ Begin
_AddTitle(docx, 'TOfficeApi', 1); _AddTitle(docx, 'TOfficeApi', 1);
_AddTitle(docx, 'TOfficeApi接口', 2); _AddTitle(docx, 'TOfficeApi接口', 2);
conf := _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TSUtils\\TOffice.tsf', 'TOffice'); conf := _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TSUtils\\TOfficeApi.tsf', 'TOffice');
_AddFunctionHelpInfo(docx, '' $ paragraph $ '.1.', conf, 3); _AddFunctionHelpInfo(docx, '' $ paragraph $ '.1.', conf, 3);
println(' >>OK\n'); println(' >>OK\n');
End; End;
Function _16_Template(docx);
Begin
paragraph := sysparams['Test'];
_PrintMsg('报告模板ExecInnerTSL');
_AddTitle(docx, 'ExecInnerTSL', 1);
//添加段落
p := TOfficeObj('TParagraph');
p.Run.SetText( '系统提供docx.ExecInnerTSL()接口,用户可以制作自定义的报告模板,参考文档:' + 'funcext\\TSOffice\\template\\template.docx。');
p.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
p.Format.LeftIndent := 440;//段落左边距
p.Font.Name := '宋体';
p.Font.Color := 'FF0000';
p.Font.Bold := true;
p.Font.Size := 29;
p1 := docx.AddParagraph(p, -1, nil);
println(' >>OK\n');
End;
Function _AddTitle(docx, subject, level); Function _AddTitle(docx, subject, level);
Begin Begin
leftIndent := array((0,0), (425,425), (453,850), (708,1508)); leftIndent := array((0,0), (425,425), (453,850), (708,1508));

Binary file not shown.

Binary file not shown.

View File

@ -1,4 +1,4 @@
// Version 1.0.8 // Version 1.0.9
Function TOfficeObj(n); Function TOfficeObj(n);
Begin Begin
@ -1124,7 +1124,7 @@ type TChartImpl=class(NodeInfo)
,("field":"xmlObj","name":"xmlObj","obj":xmlObj,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"xmlObj","name":"xmlObj","obj":xmlObj,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
,("field":"Rid","name":"Rid","obj":Rid,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"Rid","name":"Rid","obj":Rid,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
,("field":"pNode","name":"pNode","obj":pNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"pNode","name":"pNode","obj":pNode,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
,("field":"DisableExcel","name":"DisableExcel","obj":DisableExcel,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"DisableExcel","name":"DisableExcel","obj":DisableExcel,"attrEx":"","nodeType":"","attrName":"", "desc":"是否内嵌excel数据文件默认嵌入。", "class":"")
,("field":"Excel","name":"Excel","obj":Excel,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"Excel","name":"Excel","obj":Excel,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
,("field":"chartFileName","name":"chartFileName","obj":chartFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"chartFileName","name":"chartFileName","obj":chartFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
,("field":"excelFileName","name":"excelFileName","obj":excelFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"") ,("field":"excelFileName","name":"excelFileName","obj":excelFileName,"attrEx":"","nodeType":"","attrName":"", "desc":"disable", "class":"")
@ -2193,7 +2193,8 @@ type TdLbls=class(NodeInfo)
Function GetChildren(); override; Function GetChildren(); override;
Begin Begin
HandleChildren(); HandleChildren();
return array(("field":"ShowLegendKey","name":"c:showLegendKey","obj":ShowLegendKey,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"") return array(("field":"Del","name":"c:delete","obj":Del,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
,("field":"ShowLegendKey","name":"c:showLegendKey","obj":ShowLegendKey,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
,("field":"ShowVal","name":"c:showVal","obj":ShowVal,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"") ,("field":"ShowVal","name":"c:showVal","obj":ShowVal,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
,("field":"ShowCatName","name":"c:showCatName","obj":ShowCatName,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"") ,("field":"ShowCatName","name":"c:showCatName","obj":ShowCatName,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
,("field":"ShowSerName","name":"c:showSerName","obj":ShowSerName,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"") ,("field":"ShowSerName","name":"c:showSerName","obj":ShowSerName,"attrEx":"","nodeType":"","attrName":"", "desc":"", "class":"")
@ -2206,6 +2207,7 @@ type TdLbls=class(NodeInfo)
//Attributes //Attributes
//Nodes //Nodes
Del;
ShowLegendKey; ShowLegendKey;
ShowVal; ShowVal;
ShowCatName; ShowCatName;
@ -9177,10 +9179,10 @@ Type TPicture = Class(DocObject, TPictureImpl)
node := class(TSXml).GetNode(node_,'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip'); node := class(TSXml).GetNode(node_,'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic/pic:blipFill/a:blip');
if ifObj(node) then if ifObj(node) then
rid := node.GetAttribute('r:embed'); rid := node.GetAttribute('r:embed');
xml := document.ZipObject().Get('word/_rels/document.xml.rels'); xml := document.Zip().Get('word/_rels/document.xml.rels');
picFileName := class(TSXml).FindRelationshipTarget(xml, rid); picFileName := class(TSXml).FindRelationshipTarget(xml, rid);
if ifstring(picFileName) then Begin if ifstring(picFileName) then Begin
pic := document.ZipObject().Get('word/' + picFileName); pic := document.Zip().Get('word/' + picFileName);
if ifObj(pic) then if ifObj(pic) then
pic.Data := Image; pic.Data := Image;
End; End;
@ -9258,13 +9260,14 @@ Type TChart = Class(TChartImpl)
pNode := node; pNode := node;
if not ifObj(cNode) then if not ifObj(cNode) then
return; return;
IsWord_ := docx.IsWord();
rId := cNode.GetAttribute('r:id'); rId := cNode.GetAttribute('r:id');
relsObj := docx.ZipObject().Get('word/_rels/document.xml.rels'); relsObj := docx.Zip().Get('word/_rels/document.xml.rels');
Target := class(TSXml).FindRelationshipTarget(relsObj, rId); Target := class(TSXml).FindRelationshipTarget(relsObj, rId);
if ifNil(Target) then if ifNil(Target) then
return; return;
chartFileName := getChartFileName(Target); chartFileName := getChartFileName(Target);
xmlObj := docx.ZipObject().Get(chartFileName); xmlObj := docx.Zip().Get(chartFileName);
if not ifObj(xmlObj) then if not ifObj(xmlObj) then
return; return;
plotAreaNode := class(TSXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea'); plotAreaNode := class(TSXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea');
@ -9389,7 +9392,6 @@ Type TChart = Class(TChartImpl)
return; return;
if ifstring(Title) and Title <> '' then if ifstring(Title) and Title <> '' then
UpdateTitle(class(TSXml).CurCodePageToUtf8(Title)); UpdateTitle(class(TSXml).CurCodePageToUtf8(Title));
return;
//不同的图表,数据区较复杂 //不同的图表,数据区较复杂
if not istable(Series) then return; if not istable(Series) then return;
ser := self.C ? 'c:ser' : 'ser'; ser := self.C ? 'c:ser' : 'ser';
@ -9401,26 +9403,116 @@ Type TChart = Class(TChartImpl)
rId := node.GetAttribute('r:id'); rId := node.GetAttribute('r:id');
fName := ExtractFileName(chartFileName); fName := ExtractFileName(chartFileName);
rels := 'word/charts/_rels/' + fName + '.rels'; rels := 'word/charts/_rels/' + fName + '.rels';
relsObj := docx.ZipObject().Get(rels); chartId := leftstr(fName, length(fName) - 4);
chartId := rightstr(chartId, length(chartId) - 5);
relsObj := docx.Zip().Get(rels);
if ifObj(relsObj) then Begin if ifObj(relsObj) then Begin
target := FindRelationshipTarget(relsObj, rId);//../embeddings/Workbook2.xlsx target := class(TSXml).FindRelationshipTarget(relsObj, rId);//../embeddings/Workbook2.xlsx
excelFileName := ReplaceStr(target, '..','word'); excelFileName := ReplaceStr(target, '..','word');
excelObj := docx.ZipObject().Get(excelFileName); excelObj := docx.Zip().Get(excelFileName);
if ifObj(excelObj) then if ifObj(excelObj) then
NewExcelFile(); NewExcelFile();
End; End;
End; End;
//更新数据区
dom := serNode.Marshal();
for i:=0 to length(Series)-1 do Begin for i:=0 to length(Series)-1 do Begin
//<c:tx> if i then
serNode := serNode.InsertAfterChild(serNode, dom[0]);
removeOldSer(serNode);
ser := TOfficeObj('TSer');
ser.IDx := i;
ser.Ord := i;
setTx(ser.Tx.StrRef, Series[i]['Name'], i);
n := serNode.FirstChildElement('c:cat');
if ifObj(n) then Begin
_setCat(ser.Cat, i);
_setVal(ser.Val, i);
End;
n := serNode.FirstChildElement('c:xVal');
if ifObj(n) then Begin
_setCat(ser.XVal, i);
_setVal(ser.YVal, i);
End;
updData := ser.Marshal();
class(TSXml).UpdateNode(serNode, updData['attributes'], updData['children']);
End; End;
//删除多余的<c:ser> //删除多余的<c:ser>
node := serNode.NextElement(ser); node := serNode.NextElement(ser);
while ifObj(node) do Begin while ifObj(node) do Begin
ChartNode.DeleteChild(node); ChartNode.DeleteChild(node);
node := ChartNode.NextElement(ser); node := serNode.NextElement(ser);
End; End;
//修改内嵌的excel文件
AddExcelFile(docx, xmlObj, chartId);
End;
Function removeOldSer(node);
Begin
task := array('c:tx','c:cat','c:val','c:xVal','c:xYal');
for i:=0 to length(task)-1 do begin
n := node.FirstChildElement(task[i]);
if ifObj(n) then
n.DeleteChildren();
End;
End;
Function AddExcelFile(docx, chartXml, chartId);
Begin
//内嵌excel数据文件
if not ifObj(Excel) then
return;
[err, data] := Excel.Zip().Save2Mem();
if err then
return;
rId := 'rId1';
workBook := 'embeddings/Workbook1.xlsx';
fileCnt := 1 + vselect countof( ['FileName'] ) from docx.Zip().Files() where AnsiStartsText('word/embeddings/Workbook', ['FileName']) end;
ctXml := docx.Zip().Get('[Content_Types].xml');
class(TSXml).AddDefaultContentType(ctXml, 'xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
externalDataNode := chartXml.FirstChildElement('c:chartSpace').FirstChildElement('c:externalData');
if not ifObj(externalDataNode) then
chartXml.FirstChildElement('c:chartSpace').InsertEndChild('<c:externalData r:id="rId1"><c:autoUpdate val="0"/></c:externalData>');
else Begin
rId := externalDataNode.GetAttribute('r:id');
End;
rels := 'word/charts/_rels/chart' $ chartId $ '.xml.rels';
relsObj := docx.Zip().Get(rels);
if not ifObj(relsObj) then Begin
rId := 'rId1';
xmlStr := '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Target="../embeddings/Workbook1.xlsx" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package" Id="rId1"/>
</Relationships>';
docx.Zip().Add(rels, xmlStr);
if fileCnt > 1 then Begin
workBook := 'embeddings/Workbook' $ fileCnt $ '.xlsx';
relsObj := docx.Zip().Get(rels);
node := relsObj.FirstChildElement('Relationships').FirstChildElement('Relationship');
node.SetAttribute('Target', '../' + workBook);
End;
End
else Begin
target := class(TSXml).FindRelationshipTarget(relsObj, rId);
if ifNil(target) then Begin
[maxRid, tg, id] := class(TSXml).FindRelationshipRid(relsObj,'');
if fileCnt > 1 then
workBook := 'embeddings/Workbook' $ fileCnt $ '.xlsx';
maxRid ++;
class(TSXml).AddRelationshipRid(relsObj, '../' + workBook, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/package', 'rId' $ maxRid, nil);
End
else
workBook := ReplaceStr(target, '../', '');
End;
xlsx := docx.Zip().Get('word/' + workBook);
if ifObj(xlsx) then
xlsx.Data := data; //更新xlsx文件
else
docx.Zip().Add('word/' + workBook, data); //添加xlsx文件
End; End;
///修改图表标题 ///修改图表标题
@ -9596,7 +9688,7 @@ private
CatAx.Scaling.Max := XAxis.Max; CatAx.Scaling.Max := XAxis.Max;
CatAx.Scaling.Min := XAxis.Min; CatAx.Scaling.Min := XAxis.Min;
CatAx.Scaling.Orientation := XAxis.ReverseOrder ? 'maxMin' : 'minMax'; CatAx.Scaling.Orientation := XAxis.ReverseOrder ? 'maxMin' : 'minMax';
CatAx.Del := XAxis.None; CatAx.Del := 0;//XAxis.None;
CatAx.AxPos := XAxis.ReverseOrder ? 't' : 'b'; CatAx.AxPos := XAxis.ReverseOrder ? 't' : 'b';
CatAx.NumFmt.FormatCode := 'General'; CatAx.NumFmt.FormatCode := 'General';
CatAx.NumFmt.SourceLinked := true; CatAx.NumFmt.SourceLinked := true;
@ -9817,7 +9909,8 @@ private
setMarker(ser.Marker, i); setMarker(ser.Marker, i);
setDpt(ser, i); setDpt(ser, i);
//setDLbls(ser.DLbls); //setDLbls(ser.DLbls);
ser.InvertIfNegative := false; //ser.Dlbls.Del := 1;
//ser.InvertIfNegative := false;
setCat(ser.Cat, i); setCat(ser.Cat, i);
setVal(ser.Val, i); setVal(ser.Val, i);
setXVal(ser.XVal, i); setXVal(ser.XVal, i);

View File

@ -1,4 +1,4 @@
// Version 1.0.8 // Version 1.0.9
Type TSDocxFile = Class Type TSDocxFile = Class
///Version: V1.0 2022-09-20 ///Version: V1.0 2022-09-20
@ -29,7 +29,6 @@ Type TSDocxFile = Class
Begin Begin
DocPrId_ := -1; DocPrId_ := -1;
zipfile_ := new ZipFile(); zipfile_ := new ZipFile();
xml_ := new TSXml();
End; End;
///打开docx文件 ///打开docx文件
@ -41,7 +40,7 @@ Type TSDocxFile = Class
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); [err, errmsg] := zipfile_.Open(alias, fname);
if err=0 then Begin if err=0 then Begin
document_ := new docxDocument(zipfile_, xml_); document_ := new docxDocument(zipfile_);
End; End;
return array(err, errmsg); return array(err, errmsg);
End; End;
@ -415,11 +414,16 @@ Type TSDocxFile = Class
return Body().ExecInnerTSL(self); return Body().ExecInnerTSL(self);
End; End;
Function ZipObject(); Function Zip();//兼容excel
Begin Begin
return zipfile_; return zipfile_;
End; End;
Function IsWord();
Begin
return true;
End;
Function GetPath(); Function GetPath();
Begin Begin
return ExtractFileDir(ExtractFileDir(PluginPath())); return ExtractFileDir(ExtractFileDir(PluginPath()));
@ -456,7 +460,6 @@ private
private private
zipfile_; //压缩文件对象 zipfile_; //压缩文件对象
document_; //Document对象 document_; //Document对象
xml_; //TSXml对象
styleObj_; styleObj_;
numberingObj_; numberingObj_;
DocPrId_; DocPrId_;

View File

@ -1,4 +1,4 @@
// Version 1.0.8 // Version 1.0.9
Type TSExcelFile = Class Type TSExcelFile = Class
///Version: V1.0 2022-08-08 ///Version: V1.0 2022-08-08

View File

@ -74,7 +74,7 @@ public
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 //find := select thisrowindex as "rowindex_", * from child_arr where ['name'] = children_[i]['name'] end; //优化为循环性能提高15-20%2022-12-20
find := array(); find := array();
for j:=0 to length(child_arr)-1 do Begin 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 if child_arr[j]['name'] = children_[i]['name'] then Begin
find[0] := child_arr[j]; find[0] := child_arr[j];
find[0]['rowindex_'] := j; find[0]['rowindex_'] := j;

View File

@ -36,6 +36,30 @@ Type TOffice = Class
return false; return false;
End; End;
///UTF8转当前字符集
Function Utf8ToCurCodePage(str);
Begin
if ifstring(str) and not IsUtf8() then
return UTF8ToAnsi(str);
return str;
End;
///当前字符集转UTF8
Function CurCodePageToUtf8(str);
Begin
if ifstring(str) and not IsUtf8() then
return AnsiToUTF8(str);
return str;
End;
///当前字符集转GBK
Function CurCodePageToGBK(str);
Begin
if ifstring(str) and IsUtf8() then
return UTF8ToAnsi(str);
return str;
End;
///获得当前文档对象:TDocxFile对象 ///获得当前文档对象:TDocxFile对象
Function GetDocument(); Function GetDocument();
Begin Begin

View File

@ -101,8 +101,10 @@ Type TSXml = Class
child := node.FirstChild(); child := node.FirstChild();
else else
child := node.FirstChild(children[i]['name']); child := node.FirstChild(children[i]['name']);
if not ifObj(child) then if not ifObj(child) then Begin
child := node.InsertEndChild(children[i]['type'], children[i]['name']); child := node.InsertEndChild(children[i]);
continue;
End;
if children[i]['type'] = 'pcdata' then if children[i]['type'] = 'pcdata' then
child.SetValue(children[i]['value']); child.SetValue(children[i]['value']);
else else
@ -324,16 +326,12 @@ Type TSXml = Class
class Function Utf8ToCurCodePage(str); class Function Utf8ToCurCodePage(str);
Begin Begin
if ifstring(str) and not class(TSXml).IsUtf8() then return TOfficeApi().Utf8ToCurCodePage(str);
return UTF8ToAnsi(str);
return str;
End; End;
class Function CurCodePageToUtf8(str); class Function CurCodePageToUtf8(str);
Begin Begin
if ifstring(str) and not class(TSXml).IsUtf8() then return TOfficeApi().CurCodePageToUtf8(str);
return AnsiToUTF8(str);
return str;
End; End;
//字体属性 //字体属性

View File

@ -5,24 +5,24 @@ Type TDocxChart = Class(TSChart)
docx_ := docx; docx_ := docx;
class(TSChart).Create(chartData); class(TSChart).Create(chartData);
//chartN.xml //chartN.xml
chartId_ := 1 + vselect countof( ['FileName'] ) from docx.ZipObject().Files() where AnsiStartsText('word/charts/chart', ['FileName']) end; chartId_ := 1 + vselect countof( ['FileName'] ) from docx.Zip().Files() where AnsiStartsText('word/charts/chart', ['FileName']) end;
targetFileName := 'charts/chart' $ chartId_ $ '.xml'; targetFileName := 'charts/chart' $ chartId_ $ '.xml';
chartFile := 'word/' + targetFileName; chartFile := 'word/' + targetFileName;
docx.ZipObject().Add(chartFile, GetDefaultXml()); docx.Zip().Add(chartFile, GetDefaultXml());
xmlObj_ := docx.ZipObject().Get(chartFile); xmlObj_ := docx.Zip().Get(chartFile);
if not chartData_.DisableExcel and istable(chartData.Series) and istable(chartData.Series[0]['Categories']) and istable(chartData.Series[0]['Values']) then Begin if not chartData_.DisableExcel and istable(chartData.Series) and istable(chartData.Series[0]['Categories']) and istable(chartData.Series[0]['Values']) then Begin
//chartData_.NewExcelFile(); chartData_.NewExcelFile();
End; End;
Apply(xmlObj_); Apply(xmlObj_);
addExternalData(); chartData_.AddExcelFile(docx, xmlObj_, chartId_);//添加excel数据文件
//Relationship //Relationship
relsObj := docx.ZipObject().Get('word/_rels/document.xml.rels'); relsObj := docx.Zip().Get('word/_rels/document.xml.rels');
[rId_, target] := class(TSXml).FindRelationshipRid(relsObj, ''); [rId_, target] := class(TSXml).FindRelationshipRid(relsObj, '');
rId_ ++; rId_ ++;
class(TSXml).AddRelationshipRid(relsObj, targetFileName, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_); class(TSXml).AddRelationshipRid(relsObj, targetFileName, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_);
//Content_Types //Content_Types
contentType := docx.ZipObject().Get('[Content_Types].xml'); contentType := docx.Zip().Get('[Content_Types].xml');
class(TSXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'); class(TSXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
End; End;
@ -51,31 +51,6 @@ Type TDocxChart = Class(TSChart)
return true; return true;
End; End;
Function addExternalData();
Begin
//内嵌excel数据文件
if not ifObj(chartData_.Excel) then
return;
[err, data] := chartData_.Excel.Zip().Save2Mem();
if err then
return;
xmlObj_.FirstChildElement('c:chartSpace').InsertEndChild('<c:externalData r:id="rId1"><c:autoUpdate val="0"/></c:externalData>');
rels := 'word/charts/_rels/chart' $ chartId_ $ '.xml.rels';
xmlStr := '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Target="../embeddings/Workbook1.xlsx" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/package" Id="rId1"/>
</Relationships>';
fileCnt := 1 + vselect countof( ['FileName'] ) from docx_.ZipObject().Files() where AnsiStartsText('word/embeddings/Workbook', ['FileName']) end;
workBook := 'embeddings/Workbook' $ fileCnt $ '.xlsx';
docx_.ZipObject().Add(rels, xmlStr);
if fileCnt > 1 then Begin
relsObj := docx_.ZipObject().Get(rels);
node := relsObj.FirstChildElement('Relationships').FirstChildElement('Relationship');
node.SetAttribute('Target', '../' + workBook);
End;
docx_.ZipObject().Add('word/' + workBook, data);
End;
docx_; docx_;
chartId_; chartId_;
rId_; rId_;

View File

@ -3,7 +3,7 @@ Type TDocxStyles = Class
Function Create(docx); Function Create(docx);
Begin Begin
docx_ := docx; docx_ := docx;
stylesXml_ := docx.ZipObject().Get('word/styles.xml'); stylesXml_ := docx.Zip().Get('word/styles.xml');
idMap_ := array(); idMap_ := array();
nameMap_ := array(); nameMap_ := array();
maxStyleId_ := 1; maxStyleId_ := 1;

View File

@ -3,7 +3,7 @@ Type TNumbering = Class
Function Create(docx); Function Create(docx);
Begin Begin
docx_ := docx; docx_ := docx;
numberingXml_ := docx.ZipObject().Get('word/numbering.xml'); numberingXml_ := docx.Zip().Get('word/numbering.xml');
if not ifObj(numberingXml_) then Begin if not ifObj(numberingXml_) then Begin
path := docx.GetPath(); path := docx.GetPath();
if path[1] = '/' then if path[1] = '/' then
@ -11,15 +11,15 @@ Type TNumbering = Class
else else
fName := path + '\\funcext\\TSOffice\\template\\numbering\\numbering.xml'; fName := path + '\\funcext\\TSOffice\\template\\numbering\\numbering.xml';
if ReadFile(rwraw(), '', fName, 0, 100 * 1024, xmlData) then Begin if ReadFile(rwraw(), '', fName, 0, 100 * 1024, xmlData) then Begin
docx.ZipObject().Add('word/numbering.xml', xmlData); docx.Zip().Add('word/numbering.xml', xmlData);
rels := 'word/_rels/document.xml.rels'; rels := 'word/_rels/document.xml.rels';
relsObj := docx.ZipObject().Get(rels); relsObj := docx.Zip().Get(rels);
[rId, target] := class(TSXml).FindRelationshipRid(relsObj, ''); [rId, target] := class(TSXml).FindRelationshipRid(relsObj, '');
rId ++; rId ++;
class(TSXml).AddRelationshipRid(relsObj, 'numbering.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering', 'rId' $ rId); class(TSXml).AddRelationshipRid(relsObj, 'numbering.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering', 'rId' $ rId);
contentType := docx.ZipObject().Get('[Content_Types].xml'); contentType := docx.Zip().Get('[Content_Types].xml');
class(TSXml).AddOverrideContentType(contentType, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml'); class(TSXml).AddOverrideContentType(contentType, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml');
numberingXml_ := docx.ZipObject().Get('word/numbering.xml'); numberingXml_ := docx.Zip().Get('word/numbering.xml');
End; End;
End; End;
maxAbstractNumId_ := 0; maxAbstractNumId_ := 0;
@ -85,7 +85,7 @@ Type TNumbering = Class
///返回TNumStyle对象 ///返回TNumStyle对象
Function NumberStyle(numId);overload; Function NumberStyle(numId);overload;
Begin Begin
abstractNumId := numIdMap_[numId]; abstractNumId := numIdMap_['' $ numId];
if abstractNumId then Begin if abstractNumId then Begin
return numStyleObjs_[abstractNumId]; return numStyleObjs_[abstractNumId];
End; End;
@ -208,8 +208,8 @@ Type TNumbering = Class
//生成nsid随机数->转16进制 //生成nsid随机数->转16进制
Function _setNsId(o); Function _setNsId(o);
Begin Begin
v := RandomRange(1000000000,2000000000); v := Integer(RandomRange(1000000000,2000000000));
id := tohex(v); id := inttohex(v);
if hash_[id] then if hash_[id] then
return _setNsId(o); return _setNsId(o);
hash_[id] := 1; hash_[id] := 1;

View File

@ -12,7 +12,7 @@ Type TTableContent = class
impl_ := TOfficeObj('TTableContentImpl'); impl_ := TOfficeObj('TTableContentImpl');
//_CheckNodes('endnotes.xml'); //_CheckNodes('endnotes.xml');
//_CheckNodes('footnotes.xml'); //_CheckNodes('footnotes.xml');
//contentType := docx.ZipObject().Get('[Content_Types].xml'); //contentType := docx.Zip().Get('[Content_Types].xml');
//class(TSXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf'); //class(TSXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf');
End; End;
@ -273,7 +273,7 @@ Type TTableContent = class
Function _CheckNodes(name); Function _CheckNodes(name);
Begin Begin
z := docx_.ZipObject(); z := docx_.Zip();
xml := z.Get('word/' + name); xml := z.Get('word/' + name);
if not ifObj(xml) then Begin if not ifObj(xml) then Begin
path := docx_.GetPath(); path := docx_.GetPath();

View File

@ -2,10 +2,9 @@ Type docxDocument = Class
/// word/document.xml对象 /// word/document.xml对象
///缺省构造函数 ///缺省构造函数
Function Create(z,xml); overload; Function Create(z); overload;
Begin Begin
zipfile_ := z; zipfile_ := z;
xml_ := xml;
document_ := zipfile_.Get('word/document.xml'); document_ := zipfile_.Get('word/document.xml');
root_ := document_.FirstChildElement('w:document'); root_ := document_.FirstChildElement('w:document');
bodyNode_ := root_.FirstChildElement('w:body'); bodyNode_ := root_.FirstChildElement('w:body');
@ -44,7 +43,6 @@ Type docxDocument = Class
return bookmarkid_; return bookmarkid_;
End; End;
private private
xml_;
root_;//w:document root_;//w:document
bodyNode_;//w:body bodyNode_;//w:body
body_; body_;

Binary file not shown.

View File

@ -1,5 +1,16 @@
# 更新日志 # 更新日志
## 2023-1-12
### V1.0.9
#### word
1. 新增ExecInnerTSl
2. 新增修改chart图数据
3. 修复`TNumbering::AddStyleByInnerXml`错误
4. 完善帮助文档
## 2023-1-11 ## 2023-1-11
### V1.0.8 ### V1.0.8