release 1.0

This commit is contained in:
csh
2022-12-21 15:38:46 +08:00
parent 83b8ff6d09
commit 0597f9b2a4
75 changed files with 16155 additions and 4780 deletions
File diff suppressed because it is too large Load Diff
+420
View File
@@ -0,0 +1,420 @@
Type TSDocxFile = Class
///Version: V1.0 2022-09-20
///适用于 Microsoft Word docx格式文件
///纯TSL模块实现
///Word(docx)文件读写接口
///缺省构造函数
Function Create(); overload;
Begin
init();
End;
///构造函数,打开已经存在的docx文件
///alias: string,文件目录别名
///fname: string,文件名
Function Create(alias, fname); overload;
Begin
init();
OpenFile(alias, fname);
End;
Function Destory();
Begin
End;
Function init();
Begin
zipfile_ := new ZipFile();
xml_ := new xlsxXml();
End;
///打开docx文件
///alias: string,文件目录别名
///fname: string,文件名
///返回:[err, errmsg]
Function OpenFile(alias, fname);
Begin
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
[err, errmsg] := zipfile_.Open(alias, fname);
if err=0 then Begin
document_ := new docxDocument(zipfile_, xml_);
End;
return array(err, errmsg);
End;
///新建docx文件
///返回:[err, info]
Function NewFile();
Begin
path := GetPath();
if path[1] = '/' then
defaultFileName := path + '/funcext/TSOffice/template/default.docx';
else
defaultFileName := path + '\\funcext\\TSOffice\\template\\default.docx';
return OpenFile('', defaultFileName);
End;
///保存文件
///返回: [err, info]
Function Save();
Begin
return zipfile_.Save();
End;
///另存为
///alias: string,文件目录别名
///fname: string,文件名
///返回: [err, info]
Function SaveAs(alias, fname);
Begin
return zipfile_.Save(alias, fname);
End;
///真实文件名
///返回:string
Function FileName();
Begin
return zipfile_.FileName();
End;
///word文档所有段落
///返回:TParagraph对象数组
Function Paragraphs();
Begin
return document_.Body().Paragraphs();
End;
///添加新段落
///paragraph: TParagraph对象
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加段落
///[styleId]: 样式IDinteger或string
///返回TParagraph对象
Function AddParagraph(paragraph, posOpt, styleId);
Begin
return document_.Body().AddParagraph(paragraph, posOpt, styleId);
End;
///添加标题
///title: string
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加段落
///level: int 标题级别(0-9
///返回TParagraph对象
Function AddHeading(title, posOpt, level);
Begin
styleName := level = 0 ? 'Title' : 'Heading ' $ level;
style := StyleObject().GetStyle(styleName);
if not ifObj(style) and ifInt(level) and level >= 0 and level <= 9 then
style := StyleObject().AddDefaultStyle(GetPath(), styleName);
return document_.Body().AddHeading(title, posOpt, ifObj(style) ? style.StyleId : nil);
End;
///插入分页符
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加段落
///返回TParagraph对象
Function AddPageBreak(posOpt);
Begin
return document_.Body().AddBreak(posOpt, 'page');
End;
///插入换行符
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加段落
///返回TParagraph对象
Function AddLineBreak(posOpt);
Begin
return document_.Body().AddBreak(posOpt, '');
End;
///插入分栏符
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加段落
///返回TParagraph对象
Function AddColumnBreak(posOpt);
Begin
return document_.Body().AddBreak(posOpt, 'column');
End;
///删除指定段落
///posOpt: 段落位置,0 DOCX文件开头;-1 文件尾;N 第N段;posOpt段落
///返回:true
Function DelParagraph(posOpt);
Begin
return document_.Body().DelParagraph(posOpt);
End;
///word文档所有内容的文本串
///返回:string
Function Text();
Begin
return document_.Body().Text();
End;
///word文档所有内容的文本串数组,包含段落信息
///返回:array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r))
Function TextArray();
Begin
return document_.Body().TextArray();
End;
///返回:Boby对象
Function Body();
Begin
return document_.Body();
End;
///word文档所有表格个数
///返回:int
Function TablesCount();
Begin
return document_.Body().TablesCount();
End;
///word文档指定表格
///n: int 第n个表格
///返回:TTable对象
Function GetTable(n);
Begin
return document_.Body().GetTable(n);
End;
///创建数据表
///data: table,数据表
///[IncludeHeader: bool] 是否包括表头,默认FALSE
///[IncludeIndex: bool] 是否自动添加索引号,默认FALSE
///返回: TTable对象
Function CreateTable(data, IncludeHeader, IncludeIndex);
Begin
return document_.Body().CreateTable(data, IncludeHeader, IncludeIndex);
End;
///插入数据表
///tbl: TTable对象
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加表格
///返回: TTable对象
Function InsertTable(tbl, posOpt);
Begin
return document_.Body().InsertTable(tbl, posOpt);
End;
///返回CoreProperties对象
Function Properties();
Begin
core := TOfficeObj('TCoreProperties');
core.node_ := zipfile_.Get('docProps/core.xml').FirstChildElement('cp:coreProperties');
return core;
End;
///返回TDocSection集合
Function Sections();overload;
Begin
return document_.Body().Sections();
End;
///提供对节和页面设置设置的访问
///还提供对页眉和页脚的访问
///indexinteger 章节索引
///返回:TDocSection对象
Function Sections(index);overload;
Begin
return document_.Body().Sections(index);
End;
///添加章节
///sessionTDocSection对象
///posOpt: 位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加章节
///返回:TDocSection对象
Function AddSection(session, posOpt);overload;
Begin
return document_.Body().AddSection(session, posOpt);
End;
///插入图片
///picture: TPicture对象
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
///返回:TPicture对象
Function AddPicture(picture, posOpt);
Begin
return document_.Body().AddPicture(picture, posOpt);
End;
///插入图表
///chart:TChart对象
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图表
///返回: TChart对象
Function AddChart(chart, posOpt);
Begin
o := new TDocxChart(self, chart);
p := TOfficeObj('TParagraph');
p.Format.rPr.Lang := 'zh-CN';
p := AddParagraph(p, posOpt, nil);
chart.ChartNode := p.node_;
p.Node.InsertEndChild(o.GetInnerXml());
return chart;
End;
///文档中全部的Chart图
///返回:TChart对象数组
Function GetCharts();overload;
Begin
r := array();
uri := 'w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart';
ps := Paragraphs();
for i:=0 to length(ps)-1 do Begin
node := class(xlsxXml).GetNode(ps[i].node_, uri);
if ifObj(node) then Begin
chart := TOfficeObj('TChart');
chart.Init(self, ps[i].node_, node);
r[length(r)] := chart;
End;
End;
return r;
End;
///文档中全部的批注信息
///返回:DocComments对象
Function Comments();
Begin
return document_.Body().Comments();
End;
///创建新的批注对象
///返回:TDocComment对象
Function NewComment(author, txt);
Begin
file := 'word/comments.xml';
files := zipfile_.Files();
isexist := vselect thisrowindex from files where ['FileName']=file end;
if ifnil(isexist) then Begin
zipfile_.Add(file, '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:comments xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpsCustomData="http://www.wps.cn/officeDocument/2013/wpsCustomData" mc:Ignorable="w14 w15 wp14"></w:comments>');
rels := 'word/_rels/document.xml.rels';
xmlfile := zipfile_.Get(rels);
[rId, target] := class(xlsxXml).FindRelationshipRid(xmlfile, '');
rId ++;
class(xlsxXml).AddRelationshipRid(xmlfile, 'comments.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', 'rId' $ rId);
contentType := zipfile_.Get('[Content_Types].xml');
class(xlsxXml).AddOverrideContentType(contentType, '/word/comments.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml');
End
xmlfile := zipfile_.Get(file);
id := 0;
node := xmlfile.FirstChildElement('w:comments').FirstChildElement('w:comment');
while ifObj(node) do Begin
wId := node.GetAttribute('w:id');
if strtoint(wId) >= id then
id := strtoint(wId) + 1;
node := node.NextElement('w:comment');
End;
c := TOfficeObj('TDocComment');
c.p.Run.T := txt;
c.Author := author;
c.ID := id;
xmlfile.FirstChildElement('w:comments').InsertEndChild(c.Marshal());
return c;
End;
///格式刷:复制段落格式(包括字体格式)
///fromParagraph:源段落
Function CopyFormat(fromParagraph);
Begin
selectPrargraph_ := fromParagraph;
End;
///格式刷:将源段落格式(包括字体格式),刷到目标格式
///toParagraph:目标段落
Function PasteFormat(toParagraph);
Begin
pPr := ifObj(selectPrargraph_) ? selectPrargraph_.node_.FirstChildElement('w:pPr') : nil;
if not ifObj(pPr) then Begin //格式为空,清除目标段落所有格式
toParagraph.ClearFormat();//清除段落格式、字体格式
return;
End;
rPr := pPr.node_.FirstChildElement('w:rPr');
//复制段落格式
pPr2 := toParagraph.node_.FirstChildElement('w:pPr');
if ifObj(pPr2) then
pPr2.DeleteChildren();
else
pPr2 := toParagraph.node_.InsertFirstChild('element', 'w:pPr');
arr := pPr.Marshal();
class(xlsxXml).UpdateNode(pPr2, arr[0]['attributes'], arr[0]['children']);
//复制字体格式
if ifObj(rPr) then
toParagraph.SetFormat(rPr, true);
else Begin //清除字体格式
runs := toParagraph.GetRuns();
for i:=0 to length(runs)-1 do
runs[i].ClearFormat();
End;
End;
///添加目录
///[posOpt: 段落位置],在posOpt之后新添加目录(否则在首页添加)
///UpperHeadingLevel:标题最高级别
///LowerHeadingLevel:标题最低级别
/// 使用 UpperHeadingLevel 属性可设置起始标题级别(最高)。例如,若要设置 TOC 域语法 {TOC \o "1-3"},可将 LowerHeadingLevel 属性设为 3,并将 UpperHeadingLevel 属性设为 1。
///因为word、wps、openoffice等软件对于页码的计算各不相同,本功能不直接设置页码,需要用相关客户端软件打开文件后,更新目录域。
Function AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
Begin
content := new TTableContent(self);
content.SetDefaultFormat(); //缺省目录格式
node := posOpt;
if ifObj(posOpt) and not (posOpt is Class(XmlNode)) then
node := posOpt.Node();
content.Add(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;
End;
///获取全部标题列表
///UpperHeadingLevel:标题最高级别
///LowerHeadingLevel:标题最低级别
///返回:array((("Level":level,"Paragraph":"object","Text":title));
Function GetHeadingList(UpperHeadingLevel, LowerHeadingLevel);
Begin
return document_.Body().GetHeadingListImpl(self, UpperHeadingLevel, LowerHeadingLevel, nil, true);
End;
///返回Document对象
Function Document();
Begin
return document_;
End;
///返回:TDocxStyles对象
Function StyleObject();
Begin
if not ifObj(styleObj_) then
styleObj_ := new TDocxStyles(self);
return styleObj_;
End;
///返回:TNumbering对象
Function NumberingObject();
Begin
if not ifObj(numberingObj_) then
numberingObj_ := new TNumbering(self);
return numberingObj_;
End;
Function ZipObject();
Begin
return zipfile_;
End;
Function GetPath();
Begin
return ExtractFileDir(ExtractFileDir(PluginPath()));
End;
private
zipfile_; //压缩文件对象
document_; //Document对象
xml_; //xlsxXml对象
styleObj_;
numberingObj_;
selectPrargraph_;//被选中的段落
End;
+218 -239
View File
@@ -28,50 +28,33 @@ Type TSExcelFile = Class
Function init();
Begin
zipfile_ := new ZipFile();
xml_ := new xlsxXml();
End;
///打开excel文件
///alias: string,文件目录别名
///fname: string,文件名
///返回[err, errmsg]
///返回: [err, errmsg]
Function OpenFile(alias, fname);
Begin
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
[err, errmsg] := zipfile_.Open(alias, fname);
if err=0 then Begin
workbook_ := new xlsxWorkBook(zipfile_, xml_);
workbook_ := new xlsxWorkBook(zipfile_);
workbook_.Load();
End;
return array(err, errmsg);
End;
///新建excel文件
///返回[err, info]
///返回: [err, info]
Function NewFile();
Begin
path := ExtractFileDir(ExtractFileDir(PluginPath()));
{$IFNDEF Win32}
defaultFileName := path + '\\funcext\\TSOffice\\default.xlsx';
{$ELSE}
defaultFileName := path + '/funcext/TSOffice/default.xlsx';
{$ENDIF}
[err, errinfo] := OpenFile('', defaultFileName);
if not err then return array(err, errinfo);
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
zipfile_.Add(xml_.GetFileName('rels'), xml_.XmlHeader() + xml_.GetTemplate('rels'));
zipfile_.Add(xml_.GetFileName('docProps_app'), xml_.XmlHeader() + xml_.GetTemplate('docProps_app'));
zipfile_.Add(xml_.GetFileName('docProps_core'), xml_.XmlHeader() + xml_.GetTemplate('docProps_core'));
zipfile_.Add(xml_.GetFileName('workbook_rels'), xml_.XmlHeader() + xml_.GetTemplate('workbook_rels'));
zipfile_.Add(xml_.GetFileName('theme1'), xml_.XmlHeader() + xml_.GetTemplate('theme1'));
zipfile_.Add(xml_.GetFileName('sheet1'), xml_.XmlHeader() + xml_.GetTemplate('sheet1'));
zipfile_.Add(xml_.GetFileName('styles'), xml_.XmlHeader() + xml_.GetTemplate('styles'));
zipfile_.Add(xml_.GetFileName('workbook'), xml_.XmlHeader() + xml_.GetTemplate('workbook'));
zipfile_.Add(xml_.GetFileName('Content_Types'), xml_.XmlHeader() + xml_.GetTemplate('Content_Types'));
workbook_ := new xlsxWorkBook(zipfile_, xml_);
workbook_.Load();
return array(0, 'ok');
if path[1] = '/' then
defaultFileName := path + '\\funcext\\TSOffice\\template\\default.xlsx';
else
defaultFileName := path + '/funcext/TSOffice/template/default.xlsx';
return OpenFile('', defaultFileName);
End;
///保存文件
@@ -91,14 +74,14 @@ Type TSExcelFile = Class
End;
///真实文件名
///返回string
///返回: string
Function FileName();
Begin
return zipfile_.FileName();
End;
///获取工作表列表
///返回: arry('Sheet1','Sheet2')
///返回: array('Sheet1','Sheet2')
Function GetSheets();
Begin
return workbook_.GetSheets();
@@ -111,21 +94,22 @@ Type TSExcelFile = Class
return workbook_.GetSheetsCount();
End;
///获取工作表名
///index: int,工作表索引
///返回: [err, sheetname:string]
Function GetSheetName(index);
Begin
return workbook_.GetSheets()[index];
End;
///设置工作表名
///sourceName: string, 原工作表名
///destName: string目标工作表名
///返回[err, errinfo]
///destName: string,目标工作表名
///返回: [err, errinfo]
Function SetSheetName(sourceName, destName);
Begin
return workbook_.SetSheetName(sourceName, destName);
return workbook_.SetSheetName(sourceName, destName);
End;
///获取工作表名
///index: int,工作表索引
///返回: string
Function GetSheetName(index);
Begin
name := workbook_.GetSheets()[index];
return ifString(name) ? name : '';
End;
///创建新sheet
@@ -146,22 +130,20 @@ Type TSExcelFile = Class
///获取总列数
///sheet: string,工作表名称
///返回: [err, TotalCols:int]
///返回: int
Function TotalCols(sheet);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return array(0, o.TotalCols());
return array(-1, '');
if ifObj(o) then return o.TotalCols();
End;
///获取总行数
///sheet: string,工作表名称
///返回: [err, TotalRows:int]
///返回: int
Function TotalRows(sheet);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return array(0, o.TotalRows());
return array(-1, '');
if ifObj(o) then return o.TotalRows();
End;
///获取单元格的值
@@ -172,7 +154,7 @@ Type TSExcelFile = Class
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.GetCellValue(axis);
return array(-1, '');
return class(ErrorMessage).Fail();
End;
///设置单元格的值
@@ -185,12 +167,10 @@ Type TSExcelFile = Class
/// 属性t:单元格数据类型,不设置的话,数据类型为val的数据类型;
/// t ->'s' 共享字符串、'b' bool 类型、'e' 错误类型、'inlineStr' 内联字符串类型、nil 数字类型、'str' 公式类型)
/// 属性s:单元格样式
///返回: [err, info]
Function SetCellValue(sheet, axis, val, opt);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return array(0, o.SetCellValue(axis, val, opt));
return array(-1, '');
if ifObj(o) then return o.SetCellValue(axis, val, opt);
End;
///获取富文本格式
@@ -201,50 +181,44 @@ Type TSExcelFile = Class
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.GetCellValue(axis, 'RichText');
return array(-1, '');
return class(ErrorMessage).Fail();
End;
///设置富文本格式
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
///richtext: stringxml串或富文本对象TSOffice('TRichText')
///返回: [err, info]
///richtext: stringxml串或富文本对象TSOfficeObj('TRichText')
Function SetCellRichText(sheet, axis, richtext);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then Begin
if ifObj(o) then begin
if ifObj(richtext) then
richtext := class(xlsxXml).Dom2Xml(richtext.Marshal());
return array(0, o.SetCellValue(axis, richtext, array('t':'s'), 'RichText'));
End;
return array(-1, 'The Sheet is not exist.');
xml := class(xlsxXml).Dom2Xml(richtext.Marshal());
return o.SetCellValue(axis, xml, array('t':'s'), 'RichText');
end
End;
///清空单元格
///sheet: string,工作表名称
///[TopLeft: string],左上角坐标,可选参数
///[BottomRight: string],右下角坐标,可选参数,
///[topLeft: string],左上角坐标,可选参数
///[bottomRight: string],右下角坐标,可选参数,
/// 用法1ClearCell(); //Clear整个sheet
/// 用法2ClearCell('A2'); //Clear 'A2'单元格
/// 用法3ClearCell('A5', 'D8'); //Clear矩形区间所有单元格
///返回: [err, info]
Function ClearCell(sheet, TopLeft, BottomRight);
Function ClearCell(sheet, topLeft, bottomRight);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return array(0, o.ClearCell(TopLeft, BottomRight));
return array(-1, '');
if ifObj(o) then o.ClearCell(topLeft, bottomRight);
End;
///设置公式
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
///formula: string,公式
///返回: [err, info]
Function SetCellFormula(sheet, axis, formula);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.SetCellFormula(axis, formula);
return array(-1, '');
if ifObj(o) then o.SetCellFormula(axis, formula);
End;
///获取公式
@@ -255,25 +229,24 @@ Type TSExcelFile = Class
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.GetCellFormula(axis);
return array(-1, '');
return class(ErrorMessage).Fail();
End;
///按行赋值
///sheet: string,工作表名称
///axis: string,起始坐标,如: "A4"
///slice: array(),一维数组array(1,2,3,2,1,"hello")
///返回: [err, info]
Function SetSheetRow(sheet, axis, slice);
Begin
[err, col, row] := CellNameToCoordinates(axis);
if err then
return array(err, col);
for i:=0 to length(slice)-1 do Begin
[err, cell] := CoordinatesToCellName(col + i, row);
//println('{}->{}',cell,slice[i]);
SetCellValue(sheet, cell, slice[i]);
End;
return array(0, 'ok');
if not err then
begin
for i:=0 to length(slice)-1 do
begin
[err, cell] := CoordinatesToCellName(col + i, row);
SetCellValue(sheet, cell, slice[i]);
end
end
End;
///插入数据表
@@ -298,9 +271,7 @@ Type TSExcelFile = Class
if IncludeIndex then Begin
fields := array("Index") union fields;
End;
[err, info] := SetSheetRow(sheet, axis, fields);
if err then
return array(err, info);
SetSheetRow(sheet, axis, fields);
rowNum ++;
End;
if IncludeIndex then Begin
@@ -317,8 +288,7 @@ Type TSExcelFile = Class
if err then
return array(err, cell);
t := sselect * from data where thisrowindex = i End;
//PrintLn("cell={},data={}->{}",cell, data[i],t);
[err, info] := SetSheetRow(sheet, cell, t);
SetSheetRow(sheet, cell, t);
if err then
return array(err, info);
End;
@@ -327,20 +297,18 @@ Type TSExcelFile = Class
///读取数据表
///sheet: string,工作表名称
///TopLeft: string,左上角坐标,如: "A4"
///BottomRight: string,右下角坐标,如: "B8",为空获取从TopLeft开始的整张表
///返回: [err, data:table]
Function GetTable(sheet, TopLeft, BottomRight);
///topLeft: string,左上角坐标,如: "A4"
///bottomRight: string,右下角坐标,如: "B8",为空获取从topLeft开始的整张表
///返回: table
Function GetTable(sheet, topLeft, bottomRight);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return array(0, o.Import(TopLeft, BottomRight));
return array(-1, '');
if ifObj(o) then return o.Import(topLeft, bottomRight);
End;
///插入列,在指定列前插入空白列
///sheet: string,工作表名称
///col: string 列名,如: "D"
///返回: [err, info]
Function InsertCol(sheet, col);
Begin
return workbook_.InsertCol(sheet, col);
@@ -349,7 +317,6 @@ Type TSExcelFile = Class
///插入行,在指定行前插入空白行
///sheet: string,工作表名称
///row: int
///返回: [err, info]
Function InsertRow(sheet, row);
Begin
return workbook_.InsertRow(sheet, row);
@@ -358,7 +325,6 @@ Type TSExcelFile = Class
///删除列
///sheet: string,工作表名称
///col: string,如: "D"
///返回: [err, info]
Function RemoveCol(sheet, col);
Begin
return workbook_.RemoveCol(sheet, col);
@@ -367,7 +333,6 @@ Type TSExcelFile = Class
///删除行
///sheet: string,工作表名称
///row: int
///返回: [err, info]
Function RemoveRow(sheet, row);
Begin
return workbook_.RemoveRow(sheet, row);
@@ -376,8 +341,7 @@ Type TSExcelFile = Class
///设置行高度
///sheet: string,工作表
///row: int,行
///height: double
///返回: [err, info]
///height: double,行高[0-409]
Function SetRowHeight(sheet, row, height);
Begin
return workbook_.SetRowHeight(sheet, row, height);
@@ -386,7 +350,7 @@ Type TSExcelFile = Class
///获取行高度
///sheet: string,工作表
///row: int,行
///返回: [err, info]
///返回: double
Function GetRowHeight(sheet, row);
Begin
return workbook_.GetRowHeight(sheet, row);
@@ -396,8 +360,7 @@ Type TSExcelFile = Class
///sheet: string,工作表
///startcol: string,开始列,如: "A"
///endcol: string,结束列,如: "D"
///width: double
///返回: [err, info]
///width: double,列宽[0-255]
Function SetColWidth(sheet, startCol, endCol, width);
Begin
return workbook_.SetColWidth(sheet, startCol, endCol, width);
@@ -405,8 +368,8 @@ Type TSExcelFile = Class
///获取列宽度
///sheet: string,工作表
///col: int,列
///返回: [err, info]
///col: string,列
///返回: double
Function GetColWidth(sheet, col);
Begin
return workbook_.GetColWidth(sheet, col);
@@ -414,32 +377,29 @@ Type TSExcelFile = Class
///设置工作表默认列宽
///sheet: string,工作表
///widthdouble
///返回: [err, info]
///width: double
Function SetSheetDefaultColWidth(sheet, width);
Begin
return workbook_.SetSheetDefaultColWidth(sheet, width);
End
End;
///获取工作表默认列宽
///sheet: string,工作表
///返回: [err, width]
///返回: double
Function GetSheetDefaultColWidth(sheet);
Begin
return workbook_.GetSheetDefaultColWidth(sheet);
End
End;
///添加批注
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
///Author:string
///comment: string
///返回: [err, info]
Function AddComment(sheet, axis, Author, comment);
Begin
o := getOj(sheet, 'xlsxComment');
if not ifObj(o) then return array(1, 'The sheet is not exist.');
return o.AddComment(axis, Author, comment);
if ifObj(o) then o.AddComment(axis, Author, comment);
End;
///添加图表
@@ -540,57 +500,49 @@ Type TSExcelFile = Class
Function NewStyle(style);
Begin
styleObj := new xlsxStyles('', self);
return array(0, styleObj.GetStyleId(style));
End
return styleObj.GetStyleId(style);
End;
///设置单元格样式
///sheet: string,工作表名称
///TopLeft: string,左上角坐标
///BottomRight: string,右下角坐标
///topLeft: string,左上角坐标
///bottomRight: string,右下角坐标
///styleid: string,样式Id
///返回: [err, info]
Function SetCellStyle(sheet, TopLeft, BottomRight, styleid);
Function SetCellStyle(sheet, topLeft, bottomRight, styleid);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return array(0, o.SetCellStyle(TopLeft, BottomRight, styleid));
return array(-1, '');
if ifObj(o) then return o.SetCellStyle(topLeft, bottomRight, styleid);
End;
///获取单元格样式Id,获取到的Id可以在复制单元格样式时,作为调用 SetCellValue、或SetCellStyle 函数的参数使用。
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
///返回: [err, datastyle: int]
///返回: styleId: string
Function GetCellStyle(sheet, axis);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return array(0, o.GetCellStyle(axis));
return array(-1, 'The sheet is not exist.');
return workbook_.GetCellStyle(sheet, axis);
End;
///设置工作表页眉页脚
///sheetstring,工作表名称
///headerFooter: xlsxHeaderFooter对象
///返回:[err, info]
///sheet: string,工作表名称
///headerFooter: THeaderFooter对象
Function SetSheetHeaderFooter(sheet, headerFooter);
Begin
o := getOj(sheet, 'xlsxHeaderFooter');
if not ifObj(o) then return array(0, 'HeaderFooter对象不存在');
o.SetHeaderFooter(headerFooter);
return array(1, '');
End
if ifObj(o) then o.SetHeaderFooter(headerFooter);
End;
///设置工作表可见性
///sheet: string, 工作表名称
///visible: bool
///返回:[err, info]
///visible: boolean
Function SetSheetVisible(sheet, visible);
Begin
return workbook_.SetSheetVisible(sheet, visible);
End
End;
///获取工作表可见性
///sheet: string,工作表名称
///返回: [err, visibility: bool]
///visibility: boolean
Function GetSheetVisible(sheet);
Begin
return workbook_.GetSheetVisible(sheet);
@@ -599,35 +551,33 @@ Type TSExcelFile = Class
///设置行可见性
///sheet: string,工作表
///row: int,行
///visible: bool
///返回: [err, info]
///visible: boolean
Function SetRowVisible(sheet, row, visible)
Begin
return workbook_.SetRowVisible(sheet, row, visible);
End
End;
///获取工作表行可见性
///sheet: string,工作表名称
///row: int, 行
///返回: [err, visible:int]
///返回: [err, visible:boolean]
Function GetRowVisble(sheet, row);
Begin
return workbook_.GetRowVisble(sheet, row);
End
End;
///设置列可见性
///sheet: string,工作表
///col: string,列,如:'A'
///visible: bool
///返回: [err, info]
///visible: boolean
Function SetColVisible(sheet, col, visible)
Begin
[err, col] := ColumnNameToNumber(col);
if err then return array(-1, col);
if err then return "Col error.";
return workbook_.SetColVisible(sheet, col, visible);
End
End;
///获取工作表列可见性
///获取列可见性
///sheet: string,工作表名称
///col: string,列
///返回: [err, visible:int]
@@ -636,36 +586,31 @@ Type TSExcelFile = Class
[err, col] := ColumnNameToNumber(col);
if err then return array(-1, col);
return workbook_.GetColVisble(sheet, col);
End
End;
///设置工作表页边距
///sheet: string,工作表名称
///margins: TMargins 对象
///返回: [err, info]
Function SetPageMargins(sheet, margins);
Begin
o := getOj(sheet, 'xlsxMargins');
if not ifObj(o) then return array(0, 'The sheet is not exist');
o.SetPageMargins(margins);
return array(0, '');
if ifObj(o) then o.SetPageMargins(margins);
End;
///获取工作表页边距
///sheet: string,工作表名称
///返回: [err, info]
///无错误时返回TMargins对象
///返回: TMargins对象
Function GetPageMargins(sheet);
Begin
o := getOj(sheet, 'xlsxMargins');
if not ifObj(o) then return array(0, 'The sheet is not exist');
return o.GetPageMargins();
if ifObj(o) then return o.GetPageMargins();
return "sheet error";
End;
///合并单元格
///sheet: string,工作表名称
///hcell: string,左上角坐标
///vcell: string,右下角坐标
///返回: [err, info]
Function MergeCell(sheet, hcell, vcell);
Begin
return workbook_.MergeCell(sheet, hcell, vcell);
@@ -685,7 +630,7 @@ Type TSExcelFile = Class
///sheet: string,工作表名称
///viewIndex: int,视图索引
///sheet: objectTSheetView对象
///返回: [err, info]
///返回: [err, TSheetView]
Function SetSheetViewOptions(sheet, viewIndex, sheetView);
Begin
o := getOj(sheet, 'xlsxSheetView');
@@ -696,7 +641,7 @@ Type TSExcelFile = Class
///获取工作表视图属性
///sheet: string,工作表名称
///viewindex: int,视图索引,viewIndex 可以是负数,如果是这样,则向后计数(-1 代表最后一个视图)
///返回: [err, SheetView]
///返回: [err, TSheetView]
Function GetSheetViewOptions(sheet, viewIndex);
Begin
o := getOj(sheet, 'xlsxSheetView');
@@ -704,99 +649,54 @@ Type TSExcelFile = Class
return o.GetSheetViewOptions(viewIndex);
End;
///设置工作表页面布局
// TODO printerSettings1.bin?
///设置工作表页面设置
///sheet: string,工作表名称
///pageLayout: pageLayout对象,属性:
/// BlackAndWhite bool //BlackAndWhite specified print black and white.
/// FirstPageNumber int //FirstPageNumber specified the first printed page number. If no value is specified, then 'automatic' is assumed.
/// PageLayoutOrientation string //PageLayoutOrientation defines the orientation of page layout for a worksheet.
/// PageLayoutPaperSize int //PageLayoutPaperSize defines the paper size of the worksheet.
/// FitToHeight int //FitToHeight specified the number of vertical pages to fit on.
/// FitToWidth int //FitToWidth specified the number of horizontal pages to fit on.
/// PageLayoutScale int //PageLayoutScale defines the print scaling. This attribute is restricted to values ranging from 10 (10%) to 400 (400%). This setting is overridden when fitToWidth and/or fitToHeight are in use.
///返回: [err, info]
///pageLayout: TPageLayout对象,属性:
Function SetPageLayout(sheet, pageLayout);
Begin
o := getOj(sheet, 'xlsxPageLayout');
if not ifObj(o) then return array(1, 'The sheet is not exist');
return o.SetPageLayout(sheet, pageLayout);
if ifObj(o) then return o.SetPageLayout(sheet, pageLayout);
End;
///获取工作表页面布局
///获取工作表页面设置
///sheet: string,工作表名称
///返回: [err, option:pageLayout对象]
///返回: TPageLayout对象
Function GetPageLayout(sheet);
Begin
o := getOj(sheet, 'xlsxPageLayout');
if not ifObj(o) then return array(1, 'The sheet is not exist');
return o.GetPageLayout();
End;
///设置工作簿应用程序属性
///appProps: TAppProperty对象,属性:
/// Application string
/// ScaleCrop bool
/// DocSecurity int
/// Company string
/// LinksUpToDate bool
/// HyperlinksChanged bool
/// AppVersion string
///返回: [err, info]
Function SetAppProps(appProps);
Begin
o := getOj('', 'xlsxAppProperty');
if not ifObj(o) then return array(1, 'AppProperty error!');
return o.SetAppProps(appProps);
End;
///获取应用程序属性
///返回: [err, props:TAppProperty对象]
Function GetAppProps();
Begin
o := getOj('', 'xlsxAppProperty');
if not ifObj(o) then return array(1, 'AppProperty error!');
return o.GetAppProps();
if ifObj(o) then return o.GetPageLayout();
return "error sheet";
End;
///sheet: string,工作表名称
///返回: [err, info]
Function SetDefaultSheet(sheet);
Begin
return workbook_.SetDefaultSheet(sheet);
End
End;
///返回:[err, sheet]
///获取默认工作表
///返回: string,工作表名称
Function GetDefaultSheet();
Begin
return workbook_.GetDefaultSheet();
End
///设置工作表背景图片
///pictrue: 图片对象
///返回: [err, info]
Function SetSheetBackground(sheet, pictrue);
Begin
o := getOj(sheet, 'xlsxImage');
if not ifObj(o) then return array(1, 'The sheet is not exist.');
return o.SetSheetBackground(sheet);
End;
///设置超链接
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
///hyplinkTHyperLink对象
///返回: [err, info]
///hyplink: THyperLink对象
Function SetCellHyperLink(sheet, axis, hyperlink);
Begin
o := getOj(sheet, 'xlsxHyperLink');
if not ifObj(o) then return array(1, 'The sheet is not exist.');
return o.SetCellHyperLink(axis, hyperlink);
if ifObj(o) then return o.SetCellHyperLink(axis, hyperlink);
End;
// TODO 返回的结果有点问题
///获取超链接
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
///返回: [err, hyperlink: THyperLink对象]
///返回: THyperLink对象
Function GetCellHyperLink(sheet, axis);
Begin
o := getOj(sheet, 'xlsxHyperLink');
@@ -804,16 +704,113 @@ Type TSExcelFile = Class
return o.GetCellHyperLink(axis);
End;
///设置工作表背景图片
///picture: TPicture图片对象
Function SetSheetBackground(sheet, picture);
Begin
o := getOj(sheet, 'xlsxImage');
if ifObj(o) then return o.SetSheetBackground(picture);
End;
///添加图片
///sheet: string, 工作表名称
///topLeft: string, 图片插入左上角单元格
///bottomRight: string, 图片插入右下角单元格
///picture: TPicture 图片对象
///format: TPictureFormat 图片设置对象
Function AddPicture(sheet, topLeft, bottomRight, picture, format);
Begin
o := getOj(sheet, 'xlsxImage');
if ifObj(o) then return o.AddPicture(topLeft, bottomRight, picture, format);
End;
///删除图片
///sheet: 工作表名称
///topLeft: string, 图片插入左上角单元格
///bottomRight: string, 图片插入右下角单元格
Function DeletePicture(sheet, topLeft, bottomRight);
Begin
o := getOj(sheet, 'xlsxImage');
if ifObj(o) then return o.DeletePicture(topLeft, bottomRight);
End;
///创建表格
///sheet: string,工作表名称
///topLeft: string, 左上角单元格
///bottomRight: string, 右下角单元格
///tableStyle: 表格选项类 TTableStyle
///[includeHeader: bool] 是否包括表头,默认FALSE
Function AddTable(sheet, topLeft, bottomRight, tableStyle, includeHeader);
Begin
o := getOj(sheet, 'xlsxTable');
if ifObj(o) then return o.AddTable(topLeft, bottomRight, tableStyle, includeHeader);
End;
///指定行前插入分页符
///sheet: string,工作表名称
///row: int,行号
Function InsertPageBreak(sheet, row);
Begin
return workbook_.InsertPageBreak(sheet, row);
End;
///删除指定行分页符
///sheet: string,工作表名称
///row: int,行号
Function RemovePageBreak(sheet, row);
Begin
return workbook_.RemovePageBreak(sheet, row);
End;
///添加形状
///sheet: string,工作表名称
///topLeft: string, 左上角单元格
///bottomRight: string, 右下角单元格
///shapeType: string, 形状类型
///format: 形状设置,TShapeFormat类
Function AddShape(sheet, topLeft, bottomRight, shapeType, format);
Begin
o := getOj(sheet, 'xlsxShape');
if ifObj(o) then return o.AddShape(topLeft, bottomRight, shapeType, format);
End;
///设置工作簿的核心属性
///coreProps: TCoreProperty对象
Function SetCoreProps(coreProps);
Begin
o := getOj('', 'xlsxDocProps');
if ifObj(o) then return o.SetCoreProps(coreProps);
End;
///获取工作簿的核心属性
///返回: TCoreProperty对象
Function GetCoreProps();
Begin
o := getOj('', 'xlsxDocProps');
if ifObj(o) then return o.GetCoreProps();
End;
///设置工作簿应用程序属性
///appProps: TAppProperty对象,属性:
Function SetAppProps(appProps);
Begin
o := getOj('', 'xlsxDocProps');
if ifObj(o) then return o.SetAppProps(appProps);
End;
///获取应用程序属性
///返回: TAppProperty对象
Function GetAppProps();
Begin
o := getOj('', 'xlsxDocProps');
return o.GetAppProps();
End;
Function WorkBook();
Begin
return workbook_;
End;
Function XmlObj();
Begin
return xml_;
End;
Function Zip();
Begin
return zipfile_;
@@ -843,40 +840,22 @@ private
o := class(xlsxSheetView).NewObject(sheetname, self);
'xlsxPageLayout':
o := class(xlsxPageLayout).NewObject(sheetname, self);
'xlsxAppProperty':
return class(xlsxAppProperty).NewObject(self);
'xlsxDocProps':
return class(xlsxDocProps).NewObject(self);
'xlsxImage':
o := class(xlsxImage).NewObject(sheetname, self);
'xlsxHyperLink':
o := class(xlsxHyperLink).NewObject(sheetname, self);
'xlsxShape':
o := class(xlsxShape).NewObject(sheetname, self);
'xlsxTable':
o := class(xlsxTable).NewObject(sheetname, self);
End;
if ifObj(o) then objMgr_[k] := o;
return o;
End;
{
TODO// 需要移除,待完成
///设置工作表默认行高
///sheet: string,工作表
///heightdouble
///返回: [err, info]
Function SetSheetDefaultRowHeight(sheet, height);
Begin
return workbook_.SetSheetDefaultRowHeight(sheet, height);
End
///获取工作表默认行高
///sheet: string,工作表
///返回: [err, height]
Function GetSheetDefaultRowHeight(sheet);
Begin
return workbook_.GetSheetDefaultRowHeight(sheet);
End
}
zipfile_; //压缩文件对象
workbook_; //WorkBook对象
xml_; //xlsxXml对象
objMgr_; //各种对象缓存、管理
End;
+30
View File
@@ -0,0 +1,30 @@
Type ErrorMessage = class
class Function Fail();
Begin
return array(-1, '');
End;
class Function Ok();
Begin
return array(0, 'ok');
End;
class Function SheetExist(sheetName)
Begin
sheetName := ifString(sheetName) ?: '';
return array(2, sheetName + ' already exists.');
End;
class Function SheetNotExist(sheetName)
Begin
sheetName := ifString(sheetName) ?: '';
return array(3, sheetName + ' does not exist.');
End;
class Function DeleteFailure();
Begin
return array(4, 'Can not delete the last sheet.');
End
End;
+165 -30
View File
@@ -1,13 +1,30 @@
Type NodeInfo = class
public
Function Create(name);
Function Create(p, name);
Begin
Parent := p;
NodeName := name;
ExtAttr := array();
ExtNodes := array();
ReplaceArr := array();
End
Function Root(); virtual;
Begin
return RootObj;
End
Function Update();
Begin
if ifObj(RootObj) then Begin
arr := Marshal();
if length(arr['attributes']) or length(arr['children']) then Begin
class(xlsxXml).UpdateNode(RootObj, arr['attributes'], arr['children']);
End;
End;
End;
Function HandleAttrs(); virtual;
Begin
End
@@ -36,7 +53,7 @@ public
return length(ExtAttr);
End
// arr := array('sz': 15, 'style': 'line');
// arr := array(('Size', 'sz', 15), ('Style', 'style', 'line'));
Function AddAttr(arr); // 添加属性
Begin
if not istable(arr) then return;
@@ -46,26 +63,33 @@ public
Function Marshal();
Begin
children := getChildrenEx();
GetChildrenEx(); //优化为变量,减少数据COPY2022-12-10
child_arr := array();
len := 0;
for i:=0 to length(children)-1 do
for i:=0 to length(children_)-1 do
begin
node_type := children[i]['nodeType'];
obj := children[i]['obj'];
node_type := children_[i]['nodeType'];
obj := children_[i]['obj'];
if ifnil(obj) then continue;
find := select thisrowindex as "rowindex_", * from child_arr where ['name'] = children[i]['name'] end;
if not ifnil(obj) and not ifObj(obj) and istable(find) and ifstring(children[i]['attrEx']) and children[i]['attrEx'] <> '' then
//find := select thisrowindex as "rowindex_", * from child_arr where ['name'] = children_[i]['name'] end; //优化为循环,性能提高15-20%2022-12-20
find := array();
for j:=0 to length(child_arr)-1 do Begin
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
if not ifarray(find[0]['attributes']) then find[0]['attributes'] := array();
key := children[i]['attrEx'];
key := children_[i]['attrEx'];
find[0]['attributes'] union= array(key : obj);
child_arr[find[0]['rowindex_']]['attributes'] := find[0]['attributes'];
continue;
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/>
begin
end
@@ -86,7 +110,7 @@ public
end
else
begin
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);
end
@@ -101,12 +125,13 @@ public
end
attrs_arr := GetAttrs();
valid_arr := array();
for k, v in attrs_arr do
tmp_arr['attributes'] := array();
for i:=0 to length(attrs_arr)-1 do
begin
if not ifnil(v) then valid_arr[k] := v;
if not ifnil(attrs_arr[i, 2]) then Begin
tmp_arr['attributes'][ attrs_arr[i, 1] ] := attrs_arr[i, 2];
End;
end
tmp_arr['attributes'] := valid_arr;
return tmp_arr;
End
@@ -114,32 +139,142 @@ public
Begin
if not ifarray(nodeArr) then return 0;
if not ifstring(nodeArr['name']) then return 0;
arr := array(
arr := array((
'name': nodeArr['name'],
'obj': nodeArr['obj'],
'attrEx': nodeArr['attrEx'],
'nodeType': nodeArr['nodeType'],
);
));
ExtNodes union= arr;
return 1;
End
private
Function getChildrenEx();
Function Value(name);
Begin
r := GetChildren();
a := array();
for i:=0 to length(r)-1 do Begin
if ifarray(r[i]['obj']) then Begin
a union= r[i]['obj'];
End
uri := ifObj(Parent) ? NodeName : '';
p := Parent;
rootNode := Root();
while ifObj(p) do Begin
if ifObj(p.Parent) then
uri := p.NodeName + (uri ? '/' : '') + uri;
rootNode := p.Root();
p := p.Parent;
End;
attrs := GetAttrsEx();
lName := lowerCase(name);
r := sselect * from attrs where lName = lowerCase([0]) end;
if istable(r) then Begin
node := class(xlsxXml).GetNode(rootNode, uri);
if not ifObj(node) then return nil;
return node.GetAttribute(r[1]);
End;
children := GetChildren();
r := select * from children where lName = lowerCase(['field']) end;
if istable(r) then Begin
r := r[0];
uri := (uri='' ? '' : uri + '/') + r['name'];
node := class(xlsxXml).GetNode(rootNode, uri);
if not ifObj(node) then return nil;
if r['nodeType'] = 'empty' then
return true;
if r['nodeType'] = 'pcdata' then //返回文本串
return node.GetText();
if ifObj(r['obj']) then //对象,返回XML串
return node.Data();
key := r['attrName'] ? r['attrName'] : r['attrEx'] ? r['attrEx'] : 'val';
if r['nodeType'] = 'empty_string' then
begin
value := node.GetAttribute(key);
if not value then return true;
return value;
end
return node.GetAttribute(key);//返回属性
End;
return nil;
End;
Function Replace(hash, bChild);
Begin
if istable(hash) then Begin
ReplaceArr := hash;
replaceNodeName();
if bChild then Begin
r := GetChildren();
for i:=0 to length(r)-1 do Begin
if ifObj(r[i]['obj']) then
r[i]['obj'].Replace(hash, bChild);
End;
End;
End;
End
Function GetChildrenEx();
Begin
if not ifarray(children_) then Begin
children_ := getChildren();
if not istable(ReplaceArr) then Begin
for i:=0 to length(children_)-1 do Begin
if ifarray(children_[i]['obj']) then Begin
if istable(children_[i]['obj']) then
hasArr := 1;
else
children_[i]['obj'] := nil;
End;
End;
End;
if hasArr or istable(ReplaceArr) then Begin
a := array();
for i:=0 to length(children_)-1 do Begin
if istable(ReplaceArr) then
children_[i]['name'] := ReplaceName(children_[i]['name']);
if istable(children_[i]['obj']) then Begin
a union= children_[i]['obj'];
End
else
a[ length(a) ] := children_[i];
end;
children_ := a;
End;
End;
End;
Function GetAttrsEx();
Begin
return GetAttrs();//暂时没有发现需要更新属性前缀的情况
if not istable(ReplaceArr) then return GetAttrs();
attr := GetAttrs();
for i:=0 to length(attr)-1 do
attr[i][1] := ReplaceName(attr[i][1]);
return attr;
End
private
Function replaceNodeName();
Begin
for k, v in ReplaceArr do
begin
NodeName := ReplaceStr(NodeName, k, v);
end
End
Function ReplaceName(name);
Begin
for k,v in ReplaceArr do Begin
if k='' then
name := v + name;
else
a[ length(a) ] := r[i];
end;
return a;
name := ReplaceStr(name, k, v);
End;
return name;
End;
public
NodeName;
ExtAttr;
ExtNodes;
Parent;
ReplaceArr;
RootObj;
children_;
End
+302
View File
@@ -0,0 +1,302 @@
Type TSChart = Class
///缺省构造函数
Function Create(chartData); overload;
Begin
chartData_ := chartData;
End;
Function GetDefaultXml();
Begin
return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<c:chartSpace xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
<c:date1904 val="0"></c:date1904>
<c:lang val="zh-CN"></c:lang>
<c:roundedCorners val="0"></c:roundedCorners>
<mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<mc:Choice Requires="c14" xmlns:c14="http://schemas.microsoft.com/office/drawing/2007/8/2/chart">
<c14:style val="102" />
</mc:Choice>
<mc:Fallback>
<c:style val="2" />
</mc:Fallback>
</mc:AlternateContent>
<c:chart>
<c:title>
<c:tx>
<c:rich>
<a:bodyPr anchorCtr="false" rot="0" spcFirstLastPara="false"></a:bodyPr>
<a:lstStyle />
<a:p>
<a:pPr>
<a:defRPr b="false" baseline="0" i="false" kern="1200" spc="0" strike="noStrike" sz="1400" u="none">
<a:solidFill>
<a:schemeClr val="tx1">
<a:lumMod val="65000"></a:lumMod>
<a:lumOff val="35000"></a:lumOff>
</a:schemeClr>
</a:solidFill>
<a:latin typeface="+mn-lt"></a:latin>
<a:ea typeface="+mn-ea"></a:ea>
<a:cs typeface="+mn-cs"></a:cs>
</a:defRPr>
</a:pPr>
<a:r>
<a:rPr altLang="en-US" b="false" baseline="0" i="false" kern="0" lang="en-US" spc="0"></a:rPr>
<a:t>Chart</a:t>
</a:r>
<a:endParaRPr lang="en-US" altLang="en-US" b="0" i="0" kern="0" spc="0" baseline="0" />
</a:p>
</c:rich>
</c:tx>
<c:layout />
<c:overlay val="0"></c:overlay>
</c:title>
<c:autoTitleDeleted val="0" />
<c:view3D />
<c:plotArea/>
<c:legend>
<c:legendPos val="b"></c:legendPos>
<c:layout />
<c:overlay val="0" />
<c:txPr>
<a:bodyPr rot="0" spcFirstLastPara="0" vertOverflow="ellipsis" vert="horz" wrap="square" anchor="ctr" anchorCtr="1" />
<a:lstStyle />
<a:p>
<a:pPr>
<a:defRPr lang="zh-CN" sz="1000" b="0" i="0" u="none" strike="noStrike" kern="1200" baseline="0">
<a:solidFill>
<a:schemeClr val="tx1" />
</a:solidFill>
<a:latin typeface="+mn-lt" />
<a:ea typeface="+mn-ea" />
<a:cs typeface="+mn-cs" />
</a:defRPr>
</a:pPr>
</a:p>
</c:txPr>
</c:legend>
<c:plotVisOnly val="0"></c:plotVisOnly>
<c:dispBlanksAs val="zero"></c:dispBlanksAs>
<c:showDLblsOverMax val="0"></c:showDLblsOverMax>
</c:chart>
<c:spPr>
<a:solidFill>
<a:schemeClr val="bg1"></a:schemeClr>
</a:solidFill>
<a:ln algn="ctr" cap="flat" cmpd="sng" w="9525">
<a:solidFill>
<a:schemeClr val="tx1">
<a:lumMod val="15000"></a:lumMod>
<a:lumOff val="85000"></a:lumOff>
</a:schemeClr>
</a:solidFill>
</a:ln>
</c:spPr>
</c:chartSpace>';
End;
Function IsWord();virtual;
Begin
return false;
End;
Function Apply(xmlObj);
Begin
chartData_.Serialize(IsWord()); //初始化图表数据
task := array(('c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t', 'pcdata', chartData_.Title),
('c:chartSpace/c:chart/c:dispBlanksAs', 'val', chartData_.ShowBlanksAs),
('c:chartSpace/c:chart/c:legend', 'Del', ifnil(chartData_.Legend)),
('c:chartSpace/c:chart/c:plotArea', 'unmarshal', chartData_.plotArea.Marshal()),
('c:chartSpace/c:chart/c:view3D', 'unmarshal', getview3D().Marshal())
);
for i:=0 to length(task)-1 do Begin
class(xlsxXml).SetNodeValue(xmlObj, task[i]);
End;
if ifObj(chartData_.Legend) then Begin
node := class(xlsxXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:legend');
if ifObj(node) then Begin
arr := chartData_.Legend.Marshal();
class(xlsxXml).UpdateNode(node, arr['attributes'], arr['children']);
End;
End;
chartData_.ChartNode := class(xlsxXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea');
if chartData_.DataTable then
chartData_.ShowDataTable(true);
End;
protected
Function getview3D();
Begin
view3D := TOfficeObj('TView3D');
chartView3DRotX := array(
'area': 0,
'areastacked': 0,
'areapercentstacked': 0,
'area3d': 15,
'area3dstacked': 15,
'area3dpercentstacked': 15,
'bar': 0,
'barstacked': 0,
'barpercentstacked': 0,
'bar3dclustered': 15,
'bar3dstacked': 15,
'bar3dpercentstacked': 15,
'bar3dconeclustered': 15,
'bar3dconestacked': 15,
'bar3dconepercentstacked': 15,
'bar3dpyramidclustered': 15,
'bar3dpyramidstacked': 15,
'bar3dpyramidpercentstacked': 15,
'bar3dcylinderclustered': 15,
'bar3dcylinderstacked': 15,
'bar3dcylinderpercentstacked': 15,
'col': 0,
'colstacked': 0,
'colpercentstacked': 0,
'col3d': 15,
'col3dclustered': 15,
'col3dstacked': 15,
'col3dpercentstacked': 15,
'col3dcone': 15,
'col3dconeclustered': 15,
'col3dconestacked': 15,
'col3dconepercentstacked': 15,
'col3dpyramid': 15,
'col3dpyramidclustered': 15,
'col3dpyramidstacked': 15,
'col3dpyramidpercentstacked': 15,
'col3dcylinder': 15,
'col3dcylinderclustered': 15,
'col3dcylinderstacked': 15,
'col3dcylinderpercentstacked': 15,
'doughnut': 0,
'line': 0,
'pie': 0,
'pie3d': 30,
'pieofpiechart': 0,
'barofpiechart': 0,
'radar': 0,
'scatter': 0,
'surface3d': 15,
'wireframesurface3d': 15,
'contour': 90,
'wireframecontour': 90);
chartView3DRotY := array(
'area': 0,
'areastacked': 0,
'areapercentstacked': 0,
'area3d': 20,
'area3dstacked': 20,
'area3dpercentstacked': 20,
'bar': 0,
'barstacked': 0,
'barpercentstacked': 0,
'bar3dclustered': 20,
'bar3dstacked': 20,
'bar3dpercentstacked': 20,
'bar3dconeclustered': 20,
'bar3dconestacked': 20,
'bar3dconepercentstacked': 20,
'bar3dpyramidclustered': 20,
'bar3dpyramidstacked': 20,
'bar3dpyramidpercentstacked': 20,
'bar3dcylinderclustered': 20,
'bar3dcylinderstacked': 20,
'bar3dcylinderpercentstacked': 20,
'col': 0,
'colstacked': 0,
'colpercentstacked': 0,
'col3d': 20,
'col3dclustered': 20,
'col3dstacked': 20,
'col3dpercentstacked': 20,
'col3dcone': 20,
'col3dconeclustered': 20,
'col3dconestacked': 20,
'col3dconepercentstacked': 20,
'col3dpyramid': 20,
'col3dpyramidclustered': 20,
'col3dpyramidstacked': 20,
'col3dpyramidpercentstacked': 20,
'col3dcylinder': 20,
'col3dcylinderclustered': 20,
'col3dcylinderstacked': 20,
'col3dcylinderpercentstacked': 20,
'doughnut': 0,
'line': 0,
'pie': 0,
'pie3d': 0,
'pieofpiechart': 0,
'barofpiechart': 0,
'radar': 0,
'scatter': 0,
'surface3d': 20,
'wireframesurface3d': 20,
'contour': 0,
'wireframecontour': 0);
chartView3DPerspective := array(
'contour': 0,
'wireframecontour': 0);
chartView3DRAngAx := array(
'area': 0,
'areastacked': 0,
'areapercentstacked': 0,
'area3d': 1,
'area3dstacked': 1,
'area3dpercentstacked': 1,
'bar': 0,
'barstacked': 0,
'barpercentstacked': 0,
'bar3dclustered': 1,
'bar3dstacked': 1,
'bar3dpercentstacked': 1,
'bar3dconeclustered': 1,
'bar3dconestacked': 1,
'bar3dconepercentstacked': 1,
'bar3dpyramidclustered': 1,
'bar3dpyramidstacked': 1,
'bar3dpyramidpercentstacked': 1,
'bar3dcylinderclustered': 1,
'bar3dcylinderstacked': 1,
'bar3dcylinderpercentstacked': 1,
'col': 0,
'colstacked': 0,
'colpercentstacked': 0,
'col3d': 1,
'col3dclustered': 1,
'col3dstacked': 1,
'col3dpercentstacked': 1,
'col3dcone': 1,
'col3dconeclustered': 1,
'col3dconestacked': 1,
'col3dconepercentstacked': 1,
'col3dpyramid': 1,
'col3dpyramidclustered': 1,
'col3dpyramidstacked': 1,
'col3dpyramidpercentstacked': 1,
'col3dcylinder': 1,
'col3dcylinderclustered': 1,
'col3dcylinderstacked': 1,
'col3dcylinderpercentstacked': 1,
'doughnut': 0,
'line': 0,
'pie': 0,
'pie3d': 0,
'pieofpiechart': 0,
'barofpiechart': 0,
'radar': 0,
'scatter': 0,
'surface3d': 0,
'wireframesurface3d': 0,
'contour': 0,
'bubble': 0,
'bubble3d': 0);
view3D.RotX := chartView3DRotX[chartData_.Type];
view3D.RotY := chartView3DRotY[chartData_.Type];
view3D.Perspective := chartView3DPerspective[chartData_.Type];
view3D.RAngAx := chartView3DRAngAx[chartData_.Type];
return view3D;
End;
chartData_;
type_;
End;
+11 -9
View File
@@ -2,16 +2,17 @@ Type TSImage = Class
Function Create(stream); overload;
Begin
content_ := stream;
imageDef := array(('Png', 0, (0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a)),
('Jfif',6,'JFIF'),
('Exif',6,'Exif'),
('Gif',0,'GIF87a'),
('Gif',0,'GIF89a'),
('Tiff',0,('M','M',0x00,'*')),
('Tiff',0,('I', 'I', '*', 0x00)),
('Bmp',0,'BM'));
imageDef := array(('Png', 0, (0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a),'png'),
('Jfif',6,'JFIF','Jfif'),
('Exif',6,'Exif','Exif'),
('Gif',0,'GIF87a','gif'),
('Gif',0,'GIF89a','gif'),
('Tiff',0,('M','M',0x00,'*'),'tiff'),
('Tiff',0,('I', 'I', '*', 0x00),'tiff'),
('Bmp',0,'BM','bmp'));
ind := getImageDef(stream, imageDef);
if ind >= 0 then Begin
ExtFileName := imageDef[ind][3];
case imageDef[ind][0] of
'Gif':
[px_width, px_height, horz_dpi, vert_dpi] := gif_dimensions(stream);
@@ -21,7 +22,7 @@ Type TSImage = Class
[px_width, px_height, horz_dpi, vert_dpi] := tiff_dimensions(stream, imageDef[ind][2]);
End;
End;
println('width={},height={}',px_width, px_height);
//println('width={},height={}',px_width, px_height);
end;
Function Width();
@@ -216,4 +217,5 @@ println('off={}, tag={},type={},value_count={},value_off={},val={}',off, tag_cod
px_height:integer;
horz_dpi:integer;
vert_dpi:integer;
ExtFileName:string;
End;
File diff suppressed because one or more lines are too long
+51
View File
@@ -0,0 +1,51 @@
Type TDocxChart = Class(TSChart)
///缺省构造函数
Function Create(docx, chartData); overload;
Begin
class(TSChart).Create(chartData);
//chartN.xml
chartId_ := 1 + vselect countof( ['FileName'] ) from docx.ZipObject().Files() where AnsiStartsText('word/charts/chart', ['FileName']) end;
chartFile := 'word/charts/chart' $ chartId_ $ '.xml';
docx.ZipObject().Add(chartFile, GetDefaultXml());
xmlObj := docx.ZipObject().Get(chartFile);
Apply(xmlObj);
//Relationship
relsObj := docx.ZipObject().Get('word/_rels/document.xml.rels');
[rId_, target] := class(xlsxXml).FindRelationshipRid(relsObj, '');
rId_ ++;
class(xlsxXml).AddRelationshipRid(relsObj, '/' + chartFile, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_);
//Content_Types
contentType := docx.ZipObject().Get('[Content_Types].xml');
class(xlsxXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
End;
Function GetInnerXml();
Begin
ETU := 360045;//1cm单位
return fmt('<w:r>
<w:drawing>
<wp:inline>
<wp:extent cx="{}" cy="{}"/>
<wp:effectExtent l="0" t="0" r="19050" b="19050"/>
<wp:docPr id="{}" name="{}"/>
<wp:cNvGraphicFramePr />
<a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main">
<a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/chart">
<c:chart xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId{}" xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart"/>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:r>', integer(chartData_.Width * ETU), integer(chartData_.Height * ETU), chartId_, chartData_.Name, rId_);
End;
Function IsWord();override;
Begin
return true;
End;
chartId_;
rId_;
End;
+193
View File
@@ -0,0 +1,193 @@
Type TDocxStyles = Class
//段落格式
Function Create(docx);
Begin
docx_ := docx;
stylesXml_ := docx.ZipObject().Get('word/styles.xml');
idMap_ := array();
nameMap_ := array();
maxStyleId_ := 1;
if ifObj(stylesXml_) then Begin
stylesNode := stylesXml_.FirstChildElement('w:styles');
if ifObj(stylesNode) then Begin
node := stylesNode.FirstChildElement('w:style');
while ifObj(node) do Begin
o := TOfficeObj('TDocxStyle');
o.Init(node);
id := StrToIntDef(o.StyleId, 0);
if id > 0 and maxStyleId_ <= id then
maxStyleId_ := id + 1;
_addStyle(o);
node := node.NextElement('w:style');
End;
pNode := class(xlsxXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault');
if ifObj(pNode) then
defaultPpr_ := Class(xlsxXml).ReadPprFormat(pNode);
rNode := class(xlsxXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault');
if ifObj(rNode) then
defaultRpr_ := Class(xlsxXml).ReadRprFormat(rNode);
End;
End;
End;
///缺省样式
///styleType:样式类型(paragraph、character、table
///返回:TDocxStyle对象
Function Default(styleType);
Begin
for k, obj in idMap_ do Begin
if obj.wType_ = styleType then Begin
v := obj.node_.GetAttribute('w:default');
if v <> '1' then
return obj;
End;
End
return nil;
End;
///返回指定名称的TDocxStyle
///name:样式名称
///返回:TDocxStyle对象
Function GetStyle(name);
Begin
return nameMap_[ lowercase(name) ];
End;
///返回指定StyleId名称的TDocxStyle
///idStyleID号(数字ID号或名称字符串)
///返回:TDocxStyle对象
Function GetStyleById(id);
Begin
return idMap_[ id ];
End;
///返回全部LatentStyles对象列表
///返回:TDocxStyle对象列表
Function LatentStyles();
Begin
r := array();
node := stylesXml_.FirstChildElement('w:styles');
if ifObj(node) then
node := node.FirstChildElement('w:latentStyles');
if ifObj(node) then Begin
node := node.FirstChildElement('w:lsdException');
while ifObj(node) do Begin
o := TOfficeObj('TDocxStyle');
o.Init(node);
o.name_ := node.GetAttribute('w:name');
r[ length(r) ] := o;
node := node.NextElement('w:lsdException');
End;
End;
return r;
End;
///返回全部Styles对象列表
///返回:TDocxStyle对象列表
Function Styles();
Begin
return idMap_;
End;
///插入新的段落样式
///styleId:样式ID,可以是自定义名称
///xmlStrInnerXml串
///返回:TDocxStyle对象
Function AddStyleByInnerXml(styleId, xmlStr);
Begin
if ifstring(styleId) and styleId <> '' then Begin
style := GetStyle(styleId);
if ifObj(style) then
return style;
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr);
node.SetAttribute('w:styleId', styleId);
End
else Begin
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(xmlStr);
node.SetAttribute('w:styleId', maxStyleId_++);
End;
o := TOfficeObj('TDocxStyle');
o.Init(node);
_addStyle(o);
return o;
End;
///插入新的段落样式
///oTDocxStyle对象
///StyleId:样式ID,可以是自定义名称
///返回:TDocxStyle对象
Function AddStyle(o, StyleId);
Begin
if ifObj(o) then Begin
if ifString(StyleId) and StyleId <> '' and not ifObj(idMap_[ StyleId ]) then
o.StyleId := StyleId;
else
o.StyleId := maxStyleId_++;
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(o.Marshal());
obj := TOfficeObj('TDocxStyle');
obj.Init(node);
_addStyle(obj);
return obj;
End;
return nil;
End;
///插入新的LatentStyle段落样式
///oTDocxStyle对象
///返回:TDocxStyle对象
Function AddLatentStyle(o);
Begin
if ifObj(o) then Begin
latentStyles := stylesXml_.FirstChildElement('w:styles').InsertEndChild('w:latentStyles');
node := latentStyles.InsertEndChild('lsdException');
node.UnMarshal(o);
latentStyles.SetAttribute('w:count', length(LatentStyles()));
return node;
End;
return nil;
End;
///插入缺省的段落样式(Title、Heading1-9
///返回:TDocxStyle对象
Function AddDefaultStyle(path, Name);
Begin
styleId := AnsiReplaceText(Name, ' ', '');
charId := StyleId + 'Char';
if path[1] = '/' then Begin
styleFname := path + '/funcext/TSOffice/template/wStyle' + styleId + '.xml';
cStyleFname := path + '/funcext/TSOffice/template/wStyle/' + charId + '.xml';
End
else Begin
styleFname := path + '\\funcext\\TSOffice\\template\\wStyle\\' + styleId + '.xml';
cStyleFname := path + '\\funcext\\TSOffice\\template\\wStyle\\' + charId + '.xml';
End;
if not ReadFile(rwraw(), '', styleFname, 0, 100 * 1024, xmlData) then
return nil;
o := AddStyleByInnerXml(styleId, xmlData);
charStyle := idMap_[charId];
if not ifObj(charStyle) then Begin
if ReadFile(rwraw(), '', cStyleFname, 0, 100 * 1024, xmlData) then Begin
AddStyleByInnerXml(charId, xmlData);
End;
End;
return o;
End;
Function _addStyle(o);
Begin
idMap_[ o.StyleId ] := o;
nameMap_[ lowercase(o.Name) ] := o;
End;
defaultPpr_;
defaultRpr_;
private
docx_;
stylesXml_;
idMap_;
nameMap_;
maxStyleId_:integer;
End;
+235
View File
@@ -0,0 +1,235 @@
Type TNumbering = Class
//项目编号
Function Create(docx);
Begin
docx_ := docx;
numberingXml_ := docx.ZipObject().Get('word/numbering.xml');
if not ifObj(numberingXml_) then Begin
path := docx.GetPath();
if path[1] = '/' then
fName := path + '/funcext/TSOffice/template/template/numbering/numbering.xml';
else
fName := path + '\\funcext\\TSOffice\\template\\numbering\\numbering.xml';
if ReadFile(rwraw(), '', fName, 0, 100 * 1024, xmlData) then Begin
docx.ZipObject().Add('word/numbering.xml', xmlData);
rels := 'word/_rels/document.xml.rels';
relsObj := docx.ZipObject().Get(rels);
[rId, target] := class(xlsxXml).FindRelationshipRid(relsObj, '');
rId ++;
class(xlsxXml).AddRelationshipRid(relsObj, 'numbering.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering', 'rId' $ rId);
contentType := docx.ZipObject().Get('[Content_Types].xml');
class(xlsxXml).AddOverrideContentType(contentType, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml');
numberingXml_ := docx.ZipObject().Get('word/numbering.xml');
End;
End;
maxAbstractNumId_ := 0;
maxNumId_ := 1;
numStyleObjs_ := array();
numIdMap_ := array();
bullet_ := array();
hash_ := array();
bulletDefine_ := array("ef82b2","ef81b5","ef83bc","ef81b6","ef81ac","ef8398","ef81ae");//缺省项目符号文字内容(utf8 -> hex16
if ifObj(numberingXml_) then Begin
numbering := numberingXml_.FirstChildElement('w:numbering');
if ifObj(numbering) then Begin
node := numbering.FirstChildElement('w:abstractNum');
numNode := numbering.FirstChildElement('w:num');
End;
while ifObj(node) do Begin
o := TOfficeObj('TNumStyle');
o.Init(node);
nsid := o.Value('nsid');
if nsid then
hash_[nsid] := 1;
tmpl := o.Value('tmpl');
if tmpl then
hash_[tmpl] := 1;
id := StrToIntDef(o.abstractNumId, 0);
if id >= 0 and maxAbstractNumId_ <= id then
maxAbstractNumId_ := id + 1;
_addStyle(o);
lastAbstractNumStyle_ := node;
node := node.NextElement('w:abstractNum');
End;
while ifObj(numNode) do Begin
idStr := numNode.GetAttribute('w:numId');
id := StrToIntDef(idStr, 0);
if id > 0 and maxNumId_ <= id then
maxNumId_ := id + 1;
abstractNumIdNode := numNode.FirstChildElement('w:abstractNumId');
if ifObj(abstractNumIdNode) then
numIdMap_[idStr] := abstractNumIdNode.GetAttribute('w:val');
numNode := numNode.NextElement('w:num');
End;
End;
End;
///新生成numId
///levelType:字符串,bullet、singleLevel、multilevel
///fmt:项目格式,取值范围:bullet:0-6singleLevel(decimal、chineseCounting)multileveldecimal
///返回:numId
Function NumberId(levelType, fmt);
Begin
style := NumberStyle(levelType, fmt);
if not ifObj(style) then
return -1;
num := TOfficeObj('TNumber');
num.numId := maxNumId_++;
num.abstractNumId := style.Id;
numberingXml_.FirstChildElement('w:numbering').InsertEndChild(num.Marshal());
numIdMap_[''$num.numId] := num.abstractNumId;
return num.numId;
End;
///根据numId获取TNumStyle对象(已存在)
///返回:TNumStyle对象
Function NumberStyle(numId);overload;
Begin
abstractNumId := numIdMap_[numId];
if abstractNumId then Begin
return numStyleObjs_[abstractNumId];
End;
return nil;
End;
//获取TNumStyle对象,如果不存在插入系统缺省
Function NumberStyle(levelType, fmt);overload;
Begin
if levelType = 'bullet' then Begin
if fmt < 0 or fmt > 6 then return nil;
k := bulletDefine_[fmt];
o := bullet_[k];
if ifObj(o) then
return o;
//不存在,插入缺省项目编号
return AddDefaultStyle('bullet' $ fmt);
End;
if lowercase(levelType) = 'singlelevel' and lowercase(fmt) = 'decimal' then Begin
if ifObj(singleNumLevel_) then
return singleNumLevel_;
return AddDefaultStyle('singleNumLevel-decimal');
End;
if lowercase(levelType) = 'singlelevel' and lowercase(fmt) in array('chinese','chinesecounting','cn','china') then Begin
if ifObj(singleCNLevel_) then
return singleCNLevel_;
return AddDefaultStyle('singlelevel-chineseCounting');
End;
if lowercase(levelType) = 'multilevel' and lowercase(fmt) = 'decimal' then Begin
if ifObj(multiNumLevel_) then
return multiNumLevel_;
return AddDefaultStyle('multilevel-decimal');
End;
return nil;
End;
///返回:TNumStyle全部对象列表array('id1':obj1,'id2':obj2);
Function Numberings();
Begin
return numStyleObjs_;
End;
///新添加项目样式
///xmlStrxml字符串
///返回:TNumStyle对象
Function AddStyleByInnerXml(xmlStr);
Begin
if ifObj(lastAbstractNumStyle_) then
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, xmlStr);
else
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(xmlStr);
node.SetAttribute('w:abstractNumId', maxAbstractNumId_++);
lastAbstractNumStyle_ := node;
o := TOfficeObj('TNumStyle');
o.Init(node);
_addStyle(o);
_setNsId(o);
return o;
End;
///新添加项目样式
///oTNumStyle对象
///返回:TNumStyle对象
Function AddStyle(o);
Begin
if ifObj(o) then Begin
o.abstractNumId := maxAbstractNumId_++;
if ifObj(lastAbstractNumStyle_) then
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, o.Marshal());
else
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(o.Marshal());
lastAbstractNumStyle_ := node;
o := TOfficeObj('TNumStyle');
o.Init(node);
_addStyle(o);
_setNsId(o);
return o;
End;
return nil;
End;
//系统默认支持的项目编号样式
Function AddDefaultStyle(Name);
Begin
path := docx_.GetPath();
if path[1] = '/' then Begin
styleFname := path + '/funcext/TSOffice/template/numbering/' + name + '.xml';
End
else Begin
styleFname := path + '\\funcext\\TSOffice\\template\\numbering\\' + name + '.xml';
End;
if not ReadFile(rwraw(), '', styleFname, 0, 100 * 1024, xmlData) then
return nil;
return AddStyleByInnerXml(xmlData);
End;
//map项目对象
Function _addStyle(o);
Begin
if o.multiLevelType = 'singleLevel' and o.numFmt = 'bullet' then Begin
lvlText := o.lvl.Value('lvlText');
if lvlText then Begin
str := encoderadixstr(lvlText,"", 0x40000000+16);
bullet_[str] := o;
End;
End
else if not ifObj(singleNumLevel_) and o.multiLevelType = 'singleLevel' and o.numFmt = 'decimal' then
singleNumLevel_ := o;
else if not ifObj(singleCNLevel_) and o.multiLevelType = 'singleLevel' and o.numFmt = 'chineseCounting' then
singleCNLevel_ := o;
else if not ifObj(multiNumLevel_) and o.multiLevelType = 'multilevel' and o.numFmt = 'decimal' then
multiNumLevel_ := o;
numStyleObjs_[o.abstractNumId] := o;
End;
//生成nsid随机数->转16进制
Function _setNsId(o);
Begin
v := RandomRange(1000000000,2000000000);
id := xlsx_call('tohex',v);
if hash_[id] then
return _setNsId(o);
hash_[id] := 1;
o.nsid := id;
o.tmpl := id;
arr := o.Marshal();
class(xlsxXml).UpdateNode(o.node_, arr['attributes'], arr['children']);
End;
private
docx_;
numberingXml_;
maxAbstractNumId_:integer;
maxNumId_:integer;
lastAbstractNumStyle_;
numStyleObjs_;
singleNumLevel_;
singleCNLevel_;
multiNumLevel_;
bulletDefine_;
bullet_;
numIdMap_;
hash_;
End;
+309
View File
@@ -0,0 +1,309 @@
Type TTableContent = class
//目录
Function Create(docx);overload;
Begin
Create(docx, nil);
End;
Function Create(docx, node);overload;
Begin
node_ := node;
docx_ := docx;
impl_ := TOfficeObj('TTableContentImpl');
//_CheckNodes('endnotes.xml');
//_CheckNodes('footnotes.xml');
//contentType := docx.ZipObject().Get('[Content_Types].xml');
//class(xlsxXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf');
End;
Function SetDefaultFormat();
Begin
defultFont := impl_.stdPr.rPr;
defultFont.rFont.cstheme := 'minorBidi';
defultFont.rFont.eastAsia := '宋体';
defultFont.rFont.hAnsi := '宋体';
defultFont.rFont.ascii := '宋体';
//defultFont.kern := 2;
defultFont.Size := 21;
defultFont.SzCs := 24;
defultFont.Lang := 'en-US';
defultFont.bidi := 'ar-SA';
defultFont.eastAsia := 'zh-CN';
defultFormat := impl_.stdPr;
defultFormat.ID := integer(time()*24*3600);
defultFormat.Color := 'DBDBDB';
defultFormat.docPartObj.docPartGallery := 'Table of Contents';
defultFormat.docPartObj.docPartUnique := 1;
//impl_.stdEndPr.rPr.Size := 20;
//impl_.stdEndPr.rPr.SzCs := 20;
impl_.stdEndPr.rPr.Bold := true;
End;
///应用目录样式
Function Apply(); override;
Begin
arr := impl_.Marshal();
class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']);
End;
///添加目录条目
///UpperHeadingLevel:标题最高级别
///LowerHeadingLevel:标题最低级别
/// 使用 UpperHeadingLevel 属性可设置起始标题级别(最高)。例如,若要设置 TOC 域语法 {TOC \o "1-3"},可将 LowerHeadingLevel 属性设为 3,并将 UpperHeadingLevel 属性设为 1。
Function Add(posOpt, UpperHeadingLevel, LowerHeadingLevel);
Begin
///目录
mParagraph := TOfficeObj('TParagraph');
mParagraph.pPr.LineSpacingRule := 'auto';
mParagraph.pPr.LineSpacing := 240;
mParagraph.pPr.AfterLines := 0;
mParagraph.pPr.SpaceAfter := 0;
mParagraph.pPr.BeforeLines := 0;
mParagraph.pPr.SpaceBefore := 0;
mParagraph.pPr.Alignment := 'center';
mParagraph.pPr.FirstLineChars := 0;
mParagraph.pPr.FirstLineIndent := 0;
mParagraph.pPr.RightChars := 0;
mParagraph.pPr.RightIndent := 0;
mParagraph.pPr.LeftChars := 0;
mParagraph.pPr.LeftIndent := 0;
mParagraph.Run.T := '目录';
mParagraph.Run.rPr.Name := '宋体';
mParagraph.Run.rPr.Size := 21;
mParagraph.Run.rPr.Bold := true;
_AddStdContent(mParagraph);
goback := TOfficeObj('TParagraph');
id := docx_.Document().GetBookMarkID();
goback.MarkStart.Name := '_GoBack';
goback.MarkStart.ID := id;
goback.MarkEnd.ID := id;
_AddStdContent(goback);
//缺省目录,需要word或wps打开后,更新目录
_AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
//自定义页码计算与word、wps有差异,不推荐使用
//_AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
End;
Function _AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
Begin
p := _AddItem(UpperHeadingLevel, LowerHeadingLevel, UpperHeadingLevel - 1, true);
_AddStdContent(p);
p2 := TOfficeObj('TParagraph');
//p2.Format.SpaceAfter := 0;
run := p2.AddRun();
run.rPr.Bold := true;
run.rPr.noProof := true;
run.fldCharType := 'end';
_AddStdContent(p2);
End;
Function _AddItem(UpperHeadingLevel, LowerHeadingLevel, level, first);
Begin
p := TOfficeObj('TParagraph');
//标题段落属性
p.Format.StyleId := _GetStyle(level);
//p.Format.SpaceAfter := 0;
p.Format.rPr.noProof := true;
tab := TOfficeObj('TTabStop');
tab.Val := 'right';
tab.leader := 'dot';
tab.Position := 8640;
p.Format.Tabs.Add(0, tab);
if first then Begin
//fldCharType
r1 := p.AddRun();
r1.fldCharType := 'begin';
r1.Dirty := 'true';
//instrText
r2 := p.AddRun();
r2.instrTextSpace := 'preserve';
r2.instrText := 'TOC \\o \"' $ UpperHeadingLevel $ '-' $ LowerHeadingLevel $ '\" \\h \\u ';
//fldCharType
r3 := p.AddRun();
r3.fldCharType := 'separate';
End;
return p;
End;
Function _AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
Begin
///获取标题列表 array((("Level":level,"Paragraph":"object","Text":title,"numId":,"ilvl":,"numArr":));
numMap := array();
r := docx_.Document().Body().GetHeadingListImpl(docx_, posOpt, UpperHeadingLevel, LowerHeadingLevel, numMap, true);
for i:=0 to length(r)-1 do Begin
p := _AddItem(UpperHeadingLevel, LowerHeadingLevel, r[i]['Level'], i = 0 ? true: false);
//fldCharType
r4 := p.AddRun();
r4.fldCharType := 'begin';
//instrText
bookmarke := _GetBookMarkId(r[i]['Paragraph']);
r5 := p.AddRun();
r5.instrTextSpace := 'preserve';
r5.instrText := ' HYPERLINK \\l ' $ bookmarke $ ' ';
//fldCharType
r6 := p.AddRun();
r6.fldCharType := 'separate';
//目录条目文字内容
r7 := p.AddRun();
r7.Font.Name := '宋体';
numStr := ''; //数字项目编号
if r[i]['numId'] then Begin
style := docx_.NumberingObject().NumberStyle(r[i]['numId']);//支持数字、字符串StyleId
if ifObj(style) then
numStr := style.GetText(r[i]['ilvl'], r[i]['numArr']);
End
r7.T := numStr + r[i]['Text'];
//Tab
r8 := p.AddRun();
r8.Tab := true;
//fldCharType
r9 := p.AddRun();
r9.fldCharType := 'begin';
//instrText
r10 := p.AddRun();
r10.instrTextSpace := 'preserve';
r10.instrText := ' PAGEREF ' $ bookmarke $ ' \\h ';
//fldCharType
r11 := p.AddRun();
r11.fldCharType := 'separate';
//页码
r12 := p.AddRun();
r12.T := '' $ r[i]['pageNo'];
//fldCharType
r13 := p.AddRun();
r13.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);
End;
End;
///更新目录
Function UpdatePageNumbers();
Begin
End;
Function Marshal();
Begin
return impl_.Marshal();
End;
Property Format read readFormat;
Function readFormat();
Begin
return impl_.stdPr;
End;
Property EndFormat read readEndFormat;
Function readEndFormat();
Begin
return impl_.stdEndPr;
End;
Property Font read readFont;
Function readFont();
Begin
return impl_.stdPr.rPr;
End;
Function _AddStdContent(o);
Begin
impl_.SdtContent.NewChildNode( array("field":"", "name":"w:p", "obj":o, "attrEx":"", "nodeType":"") );
End;
Function _GetStyle(level);
Begin
styleName := 'Tinysoft目录 ' $ (level + 1);
style := docx_.StyleObject().GetStyle(styleName);
if not ifObj(style) then Begin
style := TOfficeObj('TDocxStyle');
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;
return style.StyleId;
End;
Function _GetBookMarkId(p);
Begin
node := p.node_.FirstChildElement('w:bookmarkStart');
if ifObj(node) then
return node.GetAttribute('w:name');
bookMarkID := docx_.Document().GetBookMarkID();
return p.AddBookMark();
End;
Function _CheckNodes(name);
Begin
z := docx_.ZipObject();
xml := z.Get('word/' + name);
if not ifObj(xml) then Begin
path := docx_.GetPath();
if path[1] = '/' then Begin
fName := path + '/funcext/TSOffice/template/' + name;
End
else Begin
fName := path + '\\funcext\\TSOffice\\template\\' + name;
End;
if not ReadFile(rwraw(), '', fName, 0, 100 * 1024, xmlData) then
return;
z.Add('word/' + name, xmlData);
rels := 'word/_rels/document.xml.rels';
relsObj := z.Get(rels);
[rId, target] := class(xlsxXml).FindRelationshipRid(relsObj, '');
rId ++;
if name = 'endnotes.xml' then Begin
class(xlsxXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes', 'rId' $ rId);
contentType := z.Get('[Content_Types].xml');
class(xlsxXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml');
End
else if name = 'footnotes.xml' then Begin
class(xlsxXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes', 'rId' $ rId);
contentType := z.Get('[Content_Types].xml');
class(xlsxXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml');
End;
End;
End;
docx_;
node_;
impl_;
End;
@@ -0,0 +1,53 @@
Type docxDocument = Class
/// word/document.xml对象
///缺省构造函数
Function Create(z,xml); overload;
Begin
zipfile_ := z;
xml_ := xml;
document_ := zipfile_.Get('word/document.xml');
root_ := document_.FirstChildElement('w:document');
bodyNode_ := root_.FirstChildElement('w:body');
body_ := TOfficeObj('TwBody');
body_.InitNode(bodyNode_);
body_.zipfile_ := z;
body_.document_ := self;
bookmarkid_ := -1;
End;
Function Body();
Begin
return body_;
End;
Function GetBookMarkID();
Begin
if bookmarkid_ < 0 then Begin
bookmarkid_ := 0;
p := body_.node_.FirstChildElement('w:p');
while ifObj(p) do Begin
markStart := p.FirstChildElement('w:bookmarkStart');
if ifObj(markStart) then Begin
id := markStart.GetAttribute('w:id');
if ifstring(id) then Begin
iVal := strtoint(id);
if bookmarkid_ <= iVal then
bookmarkid_ := iVal + 1;
End;
End;
p := p.NextElement('w:p');
End;
End
else
bookmarkid_++;
return bookmarkid_;
End;
private
xml_;
root_;//w:document
bodyNode_;//w:body
body_;
document_;
bookmarkid_;
End;
Binary file not shown.
+36
View File
@@ -0,0 +1,36 @@
*如何读取属性值?
对象的Value()函数可以获取属性值,例如:
★读取段落对象文字大小:
size := paragraph.Font.Value('Size');
★读取段落对象StyleID(段落格式ID):
styleId := paragraph.Format.Value('StyleId');
★读取段落对象numId(数字编号ID):
numId := paragraph.Format.NumPr.Value('numId');
*如何修改属性值?
Apply()函数可以修改属性值,例如:
★修改段落对象文字大小:
paragraph.Font.Size := 32;
paragraph.Apply();
*如何设置段落的项目编号?
★推荐先获取文档中已有的项目符号numId;再设置新段落的项目编号:
numId := oldParagraph.Format.NumPr.Value('numId'); //获取已有段落项目编号ID
newParagraph.Format.NumPr.ID := numID; //设置新段落numID
newParagraph.Format.NumPr.Level := numID; //设置项目编号级别
newParagraph.Apply();
★docx.Numberings()可以获取文档中已有的TNumberId对象列表,但编程的角度理解项目编码样式比较麻烦。
★docx.NumberingObject()TNumbering对象),可以用户自己插入项目编码(innerXml串或自定义TNumberId对象)。
★系统默认提供的样式:
numId := docx.NumberingObject().NumberId('SingleLevel', 'decimal'); //数字型一级样式[如:1、]
numId := docx.NumberingObject().NumberId('SingleLevel', 'chinese'); //中文型一级样式[如:一、]
numId := docx.NumberingObject().NumberId('multilevel', 'decimal'); //数字型多级样式[如:1.1.1]
numId := docx.NumberingObject().NumberId('bullet', index); //项目编号,index取值0-6
*如何设置段落的样式?
★推荐先获取文档中已有的段落样式;再设置新段落的样式:
styleId := oldParagraph.Format.Value('StyleId'); //获取已有段落StyleId
newParagraph.Format.StyleId := StyleId; //设置新段落StyleId
newParagraph.Apply();
★docx.StyleObject()TDocxStyles对象),可以用户自己插入段落样式(innerXml串或自定义TDocxStyle对象)。
@@ -0,0 +1,17 @@
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="72D8F0C1" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0C1" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="bullet" />
<w:lvlText w:val="" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="420" w:hanging="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,17 @@
<w:abstractNum w:abstractNumId="1">
<w:nsid w:val="72D8F0C2" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0C2" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="bullet" />
<w:lvlText w:val="" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="420" w:hanging="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,17 @@
<w:abstractNum w:abstractNumId="2">
<w:nsid w:val="72D8F0C3" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0C3" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="bullet" />
<w:lvlText w:val="" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="420" w:hanging="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,17 @@
<w:abstractNum w:abstractNumId="3">
<w:nsid w:val="72D8F0C4" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0C4" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="bullet" />
<w:lvlText w:val="" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="420" w:hanging="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,17 @@
<w:abstractNum w:abstractNumId="4">
<w:nsid w:val="72D8F0C5" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0C5" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="bullet" />
<w:lvlText w:val="" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="420" w:hanging="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,17 @@
<w:abstractNum w:abstractNumId="5">
<w:nsid w:val="72D8F0C6" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0C6" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="bullet" />
<w:lvlText w:val="" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="420" w:hanging="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,17 @@
<w:abstractNum w:abstractNumId="6">
<w:nsid w:val="72D8F0C7" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0C7" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="bullet" />
<w:lvlText w:val="" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="420" w:hanging="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,113 @@
<w:abstractNum w:abstractNumId="7" w15:restartNumberingAfterBreak="0">
<w:nsid w:val="72D8F0C9" />
<w:multiLevelType w:val="multilevel" />
<w:tmpl w:val="72D8F0C9" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="425" w:hanging="425" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="1" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="567" w:hanging="567" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="宋体" w:hAnsi="宋体" w:eastAsia="宋体" w:cs="宋体" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="2" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2.%3." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="709" w:hanging="709" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="3" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2.%3.%4." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="850" w:hanging="850" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="4" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2.%3.%4.%5." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="991" w:hanging="991" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="5" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2.%3.%4.%5.%6." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="1134" w:hanging="1134" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="6" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="1275" w:hanging="1275" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="7" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="1418" w:hanging="1418" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="8" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8.%9." />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="1558" w:hanging="1558" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,271 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:numbering xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:cx="http://schemas.microsoft.com/office/drawing/2014/chartex" xmlns:cx1="http://schemas.microsoft.com/office/drawing/2015/9/8/chartex" xmlns:cx2="http://schemas.microsoft.com/office/drawing/2015/10/21/chartex" xmlns:cx3="http://schemas.microsoft.com/office/drawing/2016/5/9/chartex" xmlns:cx4="http://schemas.microsoft.com/office/drawing/2016/5/10/chartex" xmlns:cx5="http://schemas.microsoft.com/office/drawing/2016/5/11/chartex" xmlns:cx6="http://schemas.microsoft.com/office/drawing/2016/5/12/chartex" xmlns:cx7="http://schemas.microsoft.com/office/drawing/2016/5/13/chartex" xmlns:cx8="http://schemas.microsoft.com/office/drawing/2016/5/14/chartex" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:aink="http://schemas.microsoft.com/office/drawing/2016/ink" xmlns:am3d="http://schemas.microsoft.com/office/drawing/2017/model3d" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:oel="http://schemas.microsoft.com/office/2019/extlst" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cex="http://schemas.microsoft.com/office/word/2018/wordml/cex" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16="http://schemas.microsoft.com/office/word/2018/wordml" xmlns:w16sdtdh="http://schemas.microsoft.com/office/word/2020/wordml/sdtdatahash" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" mc:Ignorable="w14 w15 w16se w16cid w16 w16cex w16sdtdh wp14">
<w:abstractNum w:abstractNumId="0">
<w:nsid w:val="72D8F0C1"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0C1"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="1">
<w:nsid w:val="72D8F0C2"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0C2"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="2">
<w:nsid w:val="72D8F0C3"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0C3"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="3">
<w:nsid w:val="72D8F0C4"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0C4"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="4">
<w:nsid w:val="72D8F0C5"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0C5"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="5">
<w:nsid w:val="72D8F0C6"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0C6"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="6">
<w:nsid w:val="72D8F0C7"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0C7"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="bullet"/>
<w:lvlText w:val=""/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="420" w:hanging="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default" w:ascii="Wingdings" w:hAnsi="Wingdings"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="7" w15:restartNumberingAfterBreak="0">
<w:nsid w:val="72D8F0C9"/>
<w:multiLevelType w:val="multilevel"/>
<w:tmpl w:val="72D8F0C9"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="425" w:hanging="425"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="1" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="850" w:hanging="453"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="2" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2.%3."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="1508" w:hanging="708"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="3" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2.%3.%4."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="2053" w:hanging="853"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="4" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2.%3.%4.%5."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="2495" w:hanging="895"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="5" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2.%3.%4.%5.%6."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="3136" w:hanging="1136"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="6" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="3673" w:hanging="1273"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="7" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="4218" w:hanging="1418"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
<w:lvl w:ilvl="8" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8.%9."/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="4648" w:hanging="1448"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="default"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="8" w15:restartNumberingAfterBreak="0">
<w:nsid w:val="72D8F0CA"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0CA"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="chineseCounting"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val="%1、"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="0" w:firstLine="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
<w:abstractNum w:abstractNumId="9" w15:restartNumberingAfterBreak="0">
<w:nsid w:val="72D8F0CB"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="72D8F0CB"/>
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1"/>
<w:numFmt w:val="decimal"/>
<w:suff w:val="nothing"/>
<w:lvlText w:val="%1、"/>
<w:lvlJc w:val="left"/>
<w:pPr>
<w:ind w:left="0" w:firstLine="420"/>
</w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
</w:lvl>
</w:abstractNum>
</w:numbering>
@@ -0,0 +1,18 @@
<w:abstractNum w:abstractNumId="8" w15:restartNumberingAfterBreak="0">
<w:nsid w:val="72D8F0CA" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0CA" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="chineseCounting" />
<w:suff w:val="nothing" />
<w:lvlText w:val="%1、" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="0" w:firstLine="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia" />
</w:rPr>
</w:lvl>
</w:abstractNum>
@@ -0,0 +1,18 @@
<w:abstractNum w:abstractNumId="9" w15:restartNumberingAfterBreak="0">
<w:nsid w:val="72D8F0CB" />
<w:multiLevelType w:val="singleLevel" />
<w:tmpl w:val="72D8F0CB" />
<w:lvl w:ilvl="0" w:tentative="0">
<w:start w:val="1" />
<w:numFmt w:val="decimal" />
<w:suff w:val="nothing" />
<w:lvlText w:val="%1、" />
<w:lvlJc w:val="left" />
<w:pPr>
<w:ind w:left="0" w:firstLine="420" />
</w:pPr>
<w:rPr>
<w:rFonts w:hint="eastAsia" />
</w:rPr>
</w:lvl>
</w:abstractNum>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

@@ -0,0 +1,23 @@
<w:style w:type="paragraph" w:styleId="Heading1">
<w:name w:val="heading 1" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading1Char" />
<w:uiPriority w:val="9" />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="480" w:after="0" />
<w:outlineLvl w:val="0" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:color w:val="365F91" w:themeColor="accent1" w:themeShade="BF" />
<w:sz w:val="28" />
<w:szCs w:val="28" />
</w:rPr>
</w:style>
@@ -0,0 +1,15 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading1Char">
<w:name w:val="Heading 1 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading1" />
<w:uiPriority w:val="9" />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:color w:val="365F91" w:themeColor="accent1" w:themeShade="BF" />
<w:sz w:val="28" />
<w:szCs w:val="28" />
</w:rPr>
</w:style>
@@ -0,0 +1,24 @@
<w:style w:type="paragraph" w:styleId="Heading2">
<w:name w:val="heading 2" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading2Char" />
<w:uiPriority w:val="9" />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="1" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:color w:val="4F81BD" w:themeColor="accent1" />
<w:sz w:val="26" />
<w:szCs w:val="26" />
</w:rPr>
</w:style>
@@ -0,0 +1,15 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading2Char">
<w:name w:val="Heading 2 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading2" />
<w:uiPriority w:val="9" />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:color w:val="4F81BD" w:themeColor="accent1" />
<w:sz w:val="26" />
<w:szCs w:val="26" />
</w:rPr>
</w:style>
@@ -0,0 +1,22 @@
<w:style w:type="paragraph" w:styleId="Heading3">
<w:name w:val="heading 3" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading3Char" />
<w:uiPriority w:val="9" />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="2" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:color w:val="4F81BD" w:themeColor="accent1" />
</w:rPr>
</w:style>
@@ -0,0 +1,13 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading3Char">
<w:name w:val="Heading 3 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading3" />
<w:uiPriority w:val="9" />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:color w:val="4F81BD" w:themeColor="accent1" />
</w:rPr>
</w:style>
@@ -0,0 +1,25 @@
<w:style w:type="paragraph" w:styleId="Heading4">
<w:name w:val="heading 4" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading4Char" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="3" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:i />
<w:iCs />
<w:color w:val="4F81BD" w:themeColor="accent1" />
</w:rPr>
</w:style>
@@ -0,0 +1,16 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading4Char">
<w:name w:val="Heading 4 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading4" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:b />
<w:bCs />
<w:i />
<w:iCs />
<w:color w:val="4F81BD" w:themeColor="accent1" />
</w:rPr>
</w:style>
@@ -0,0 +1,21 @@
<w:style w:type="paragraph" w:styleId="Heading5">
<w:name w:val="heading 5" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading5Char" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="4" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:color w:val="243F60" w:themeColor="accent1" w:themeShade="7F" />
</w:rPr>
</w:style>
@@ -0,0 +1,12 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading5Char">
<w:name w:val="Heading 5 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading5" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:color w:val="243F60" w:themeColor="accent1" w:themeShade="7F" />
</w:rPr>
</w:style>
@@ -0,0 +1,23 @@
<w:style w:type="paragraph" w:styleId="Heading6">
<w:name w:val="heading 6" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading6Char" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="5" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:i />
<w:iCs />
<w:color w:val="243F60" w:themeColor="accent1" w:themeShade="7F" />
</w:rPr>
</w:style>
@@ -0,0 +1,14 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading6Char">
<w:name w:val="Heading 6 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading6" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:i />
<w:iCs />
<w:color w:val="243F60" w:themeColor="accent1" w:themeShade="7F" />
</w:rPr>
</w:style>
@@ -0,0 +1,23 @@
<w:style w:type="paragraph" w:styleId="Heading7">
<w:name w:val="heading 7" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading7Char" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="6" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:i />
<w:iCs />
<w:color w:val="404040" w:themeColor="text1" w:themeTint="BF" />
</w:rPr>
</w:style>
@@ -0,0 +1,14 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading7Char">
<w:name w:val="Heading 7 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading7" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:i />
<w:iCs />
<w:color w:val="404040" w:themeColor="text1" w:themeTint="BF" />
</w:rPr>
</w:style>
@@ -0,0 +1,23 @@
<w:style w:type="paragraph" w:styleId="Heading8">
<w:name w:val="heading 8" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading8Char" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="7" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:color w:val="4F81BD" w:themeColor="accent1" />
<w:sz w:val="20" />
<w:szCs w:val="20" />
</w:rPr>
</w:style>
@@ -0,0 +1,14 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading8Char">
<w:name w:val="Heading 8 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading8" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:color w:val="4F81BD" w:themeColor="accent1" />
<w:sz w:val="20" />
<w:szCs w:val="20" />
</w:rPr>
</w:style>
@@ -0,0 +1,25 @@
<w:style w:type="paragraph" w:styleId="Heading9">
<w:name w:val="heading 9" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="Heading9Char" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:unhideWhenUsed />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:keepNext />
<w:keepLines />
<w:spacing w:before="200" w:after="0" />
<w:outlineLvl w:val="8" />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:i />
<w:iCs />
<w:color w:val="404040" w:themeColor="text1" w:themeTint="BF" />
<w:sz w:val="20" />
<w:szCs w:val="20" />
</w:rPr>
</w:style>
@@ -0,0 +1,16 @@
<w:style w:type="character" w:customStyle="1" w:styleId="Heading9Char">
<w:name w:val="Heading 9 Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Heading9" />
<w:uiPriority w:val="9" />
<w:semiHidden />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:i />
<w:iCs />
<w:color w:val="404040" w:themeColor="text1" w:themeTint="BF" />
<w:sz w:val="20" />
<w:szCs w:val="20" />
</w:rPr>
</w:style>
@@ -0,0 +1,24 @@
<w:style w:type="paragraph" w:styleId="Title">
<w:name w:val="Title" />
<w:basedOn w:val="Normal" />
<w:next w:val="Normal" />
<w:link w:val="TitleChar" />
<w:uiPriority w:val="10" />
<w:qFormat />
<w:rsid w:val="00FC693F" />
<w:pPr>
<w:pBdr>
<w:bottom w:val="single" w:sz="8" w:space="4" w:color="4F81BD" w:themeColor="accent1" />
</w:pBdr>
<w:spacing w:after="300" w:line="240" w:lineRule="auto" />
<w:contextualSpacing />
</w:pPr>
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:color w:val="17365D" w:themeColor="text2" w:themeShade="BF" />
<w:spacing w:val="5" />
<w:kern w:val="28" />
<w:sz w:val="52" />
<w:szCs w:val="52" />
</w:rPr>
</w:style>
@@ -0,0 +1,15 @@
<w:style w:type="character" w:customStyle="1" w:styleId="TitleChar">
<w:name w:val="Title Char" />
<w:basedOn w:val="DefaultParagraphFont" />
<w:link w:val="Title" />
<w:uiPriority w:val="10" />
<w:rsid w:val="00FC693F" />
<w:rPr>
<w:rFonts w:asciiTheme="majorHAnsi" w:eastAsiaTheme="majorEastAsia" w:hAnsiTheme="majorHAnsi" w:cstheme="majorBidi" />
<w:color w:val="17365D" w:themeColor="text2" w:themeShade="BF" />
<w:spacing w:val="5" />
<w:kern w:val="28" />
<w:sz w:val="52" />
<w:szCs w:val="52" />
</w:rPr>
</w:style>
@@ -1,50 +0,0 @@
Type xlsxAppProperty = Class
Function Create(file); overload;
Begin
file_ := file;
End;
Function SetAppProps(appProps);
Begin
app_xml := file_.WorkBook().GetXmlFileObj('docProps/app.xml');
node := app_xml.FirstChildElement('Properties');
if not ifObj(node) then return array(1, "node::Properties can't be found");
children_arr := appProps.Marshal()['children'];
for i:=0 to length(children_arr)-1 do
Begin
if children_arr[i]['name'] in array('ScaleCrop', 'LinksUpToDate', 'SharedDoc', 'HyperlinksChanged') then
Begin
children_arr[i]['children'][0]['value'] := children_arr[i]['children'][0]['value'] ? "true" : "false";
End
delete_node := node.FirstChildElement(children_arr[i]['name']);
node.InsertAfterChild(delete_node, children_arr[i]);
node.DeleteChild(delete_node);
End
return array(0, '');
End;
Function GetAppProps();
Begin
app_xml := file_.WorkBook().GetXmlFileObj('docProps/app.xml');
node := app_xml.FirstChildElement('Properties');
marshal := node.Marshal()[0]['children'];
reindex(marshal, marshal[:,'name']);
app_props := TOfficeObj('TAppProperty');
app_props.Application := marshal['Application']['children'][0]['value'];
app_props.DocSecurity := marshal['DocSecurity']['children'][0]['value'];
app_props.ScaleCrop := marshal['DocSecurity']['children'][0]['value'] = "false" ? 0 : 1;
app_props.Company := marshal['Company']['children'][0]['value'];
app_props.LinksUpToDate := marshal['LinksUpToDate']['children'][0]['value'] = "false" ? 0 : 1;
app_props.SharedDoc := marshal['SharedDoc']['children'][0]['value'] = "false" ? 0 : 1;
app_props.AppVersion := marshal['AppVersion']['children'][0]['value'];
return array(0, app_props);
End
class Function NewObject(file);
Begin
return new xlsxAppProperty(file);
End;
private
file_; //TSExcelFile对象
End;
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -12,7 +12,7 @@ Type xlsxComment = Class
commentId_ := excel_.WorkBook().GetFilesCount('xl/comments') + 1;
commentFileName_ := '../comments' + inttostr(commentId_) + '.xml';
xlCommentFileName := 'xl/comments' + inttostr(commentId_) + '.xml';
excel_.Zip().Add(xlCommentFileName, excel_.XmlObj().XmlHeader() + '<comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"></comments>');
excel_.Zip().Add(xlCommentFileName, class(xlsxXml).XmlHeader() + '<comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"></comments>');
excel_.WorkBook().AddRelationshipRid(relsfile, commentFileName_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', rId_);
rid ++;
drawingVML_ := '../drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
@@ -33,8 +33,9 @@ xmlns:v="urn:schemas-microsoft-com:vml">
</v:shapetype>
</xml>');
excel_.WorkBook().AddRelationshipRid(relsfile, drawingVML_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', 'rId' + inttostr(rid));
excel_.WorkBook().AddContentType('application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml', '/' + xlCommentFileName);
excel_.WorkBook().AddContentVml();
content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types'));
class(xlsxXml).AddOverrideContentType(content_xml, '/' + xlCommentFileName, 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml');
class(xlsxXml).AddDefaultContentType(content_xml, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing');
sheetXml := excel_.WorkBook().GetSheetXmlfile(sheetName_).FirstChildElement('worksheet');
legacy := sheetXml.FirstChildElement('legacyDrawing');
@@ -78,7 +79,7 @@ xmlns:v="urn:schemas-microsoft-com:vml">
commentXmlFile_.FirstChildElement('comments').FirstChildElement('authors').InsertEndChild('element', 'author', author);//添加作者
authors_[author] := authorId;
End;
if not ifstring(comment) then return array(1, 'comment is not a string');
if not ifstring(comment) then return 'comment is not a string';
comments := TOfficeObj('TComments');
comments.Ref := cell;
comments.AuthorId := authorId;
@@ -129,7 +130,7 @@ xmlns:v="urn:schemas-microsoft-com:vml">
//xmlObj.Print;
End;
End;
return array(0, 'ok');
return 'ok';
End;
Function getComment(cell);
@@ -0,0 +1,49 @@
Type xlsxDocProps = Class
Function Create(file); overload;
Begin
excel_ := file;
End;
Function SetAppProps(appProps);
Begin
app_xml := excel_.WorkBook().GetXmlFileObj('docProps/app.xml');
node := app_xml.FirstChildElement('Properties');
if not ifObj(node) then return "node::Properties can't be found";
marshal := appProps.Marshal();
class(xlsxXml).UpdateNode(node, marshal['attributes'], marshal['children']);
End;
Function GetAppProps();
Begin
app_xml := excel_.WorkBook().GetXmlFileObj('docProps/app.xml');
node := app_xml.FirstChildElement('Properties');
app_props := TOfficeObj('TAppProperty');
app_props.RootObj := node;
return app_props;
End
Function SetCoreProps(appProps);
Begin
core_xml := excel_.WorkBook().GetXmlFileObj('docProps/core.xml');
node := core_xml.FirstChildElement('cp:coreProperties');
marshal := appProps.Marshal();
class(xlsxXml).UpdateNode(node, marshal['attributes'], marshal['children']);
End
Function GetCoreProps();
Begin
core_xml := excel_.WorkBook().GetXmlFileObj('docProps/core.xml');
node := core_xml.FirstChildElement('cp:coreProperties');
core_props := TOfficeObj('TCoreProperty');
core_props.RootObj := node;
return core_props;
End
class Function NewObject(file);
Begin
return new xlsxDocProps(file);
End;
private
excel_; //TSExcelFile对象
End;
@@ -22,11 +22,15 @@ Type xlsxHeaderFooter = Class
header_node := node.FirstChildElement('headerFooter');
if ifObj(header_node) then
node.DeleteChild(header_node);
node.InsertEndChild(headerFooter.Marshal());
page_node := node.FirstChildElement('pageMargins');
if ifObj(page_node) then
node.InsertAfterChild(page_node, headerFooter.Marshal());
else
node.InsertEndChild(headerFooter.Marshal());
End
private
sheet_; //XmlSheet对象
file_; //TSExcelFile对象
xmlFile_; //sheet对应的xml对象
End;
End;
+18 -24
View File
@@ -17,8 +17,16 @@ Type xlsxHyperLink = Class
work_node := xmlFile_.FirstChildElement('worksheet');
hyperlinks := work_node.FirstChildElement('hyperlinks');
if not ifObj(hyperlinks) then begin
phone_node := work_node.FirstChildElement('phoneticPr');
hyperlinks := work_node.InsertAfterChild(phone_node, 'element', 'hyperlinks');
arr := array('phoneticPr', 'mergeCells', 'sheetData');
for i:=0 to length(arr)-1 do
begin
insert_node := work_node.FirstChildElement(arr[i]);
if ifObj(insert_node) then
begin
hyperlinks := work_node.InsertAfterChild(insert_node, 'element', 'hyperlinks');
break;
end
end
end;
node := hyperlinks.FirstChildElement('hyperlink');
while ifObj(node) do begin
@@ -48,38 +56,24 @@ Type xlsxHyperLink = Class
End
marshal['attributes'] := attrs;
hyperlinks.InsertEndChild(marshal);
return array(0,'ok');
End;
Function GetCellHyperLink(axis);
Begin
data := array();
hyperlinks := xmlFile_.FirstChildElement('worksheet').FirstChildElement('hyperlinks');
if not ifObj(hyperlinks) then return array(-1, 'Node::hyperlinks is not exist.');
if not ifObj(hyperlinks) then return "The cell has no hyperlink";
node := hyperlinks.FirstChildElement('hyperlink');
link := TOfficeObj('THyperLink');
while ifObj(node) do begin
marshal := node.marshal()[0];
attrs := marshal['attributes'];
if attrs['ref'] = axis then
ref := node.GetAttribute('ref');
if ref = axis then
begin
link := TOfficeObj('THyperLink');
link.LinkType := ifnil(attrs['location']) ? "External" : "Location";
if not ifnil(attrs['location']) then
link.LinkUrl := attrs['location'];
else Begin
rid := attrs['r:id'];
file := 'xl/worksheets/_rels/' + ExtractFileName(LowerCase(sheetName_)) + '.xml.rels';
xmlfile := file_.WorkBook().GetXmlFileObj(file);
relnode := class(xlsxXml).FindRelationship(xmlfile, rid);
if ifObj(relnode) then link.LinkUrl := relnode.GetAttribute('Target');
End
link.Display := attrs['display'];
link.Tooltip := attrs['tooltip'];
return array(0, link);
end;
link.RootObj := node;
break;
end
node := node.NextElement();
end;
return array(-2, "The cell has no hyperlink.");
return link;
End;
private
+149 -25
View File
@@ -4,9 +4,9 @@ Type xlsxImage = Class
Begin
excel_ := excel;
sheetName_ := sheet;
[rid_, imageFileName_, sheetFileName_, xmlRelsFile_] := excel_.WorkBook().GetRelationshipRid(sheet, '../media/image');
zipfile_ := excel.Zip();
End;
class Function NewObject(sheet, excel);
Begin
excel_ := excel;
@@ -15,34 +15,158 @@ Type xlsxImage = Class
return new xlsxImage(sheet, excel);
End;
Function SetSheetBackground(pictrue);
Function SetSheetBackground(picture);
Begin
//if not ifBinary(picture.Image) or length(picture.Image) = 0 then
// raise "Invalid Image Data.";
if imageFileName_ = '' then
Begin
rid_++;
imageId := excel_.WorkBook().GetFilesCount('xl/media/') + 1;
imageName := "../media/image" + inttostr(imageId);
type := 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image';
excel_.WorkBook().AddRelationshipRid(xmlRelsFile_, imageName, type, 'rId' + inttostr(rid_));
End
if not ifBinary(picture.Image) or length(picture.Image) = 0 then
return "Invalid Image Data.";
image_file := getImageFileName(picture);
rels_xmlfile := excel_.WorkBook().GetSheetRelsFile(sheetName_);
prefix := ReplaceStr(image_file, 'xl/', '../');
[rid, target] := class(xlsxXml).FindRelationshipRid(rels_xmlfile, prefix);
if target = '' then
begin
rid ++;
class(xlsxXml).AddRelationshipRid(rels_xmlfile, prefix, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid);
end
content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types'));
class(xlsxXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg');
sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_);
node := sheet_xml.FirstChildElement('worksheet');
picture_node := node.FirstChildElement('picture');
if ifObj(picture_node) then
Begin
node.DeleteChild(picture_node);
End
node := node.InsertEndChild('element', 'picture');
node.SetAttribute('r:id', 'rId' + inttostr(rId_));
if not ifObj(picture_node) then
begin
prev_node := class(xlsxXml).GetWorkSheetPrevNode(node, 'picture');
if ifObj(prev_node) then picture_node := node.InsertAfterChild(prev_node, 'element', 'picture');
else picture_node := node.InsertEndChild('element', 'picture');
end
picture_node.SetAttribute('r:id', 'rId' + inttostr(rid));
End
private
Function AddPicture(topLeft, bottomRight, picture, format);
Begin
if not ifBinary(picture.Image) or length(picture.Image) = 0 then
return "Invalid Image Data.";
[err1, col1, row1] := excel_.CellNameToCoordinates(topLeft);
[err2, col2, row2] := excel_.CellNameToCoordinates(bottomRight);
if err1 or err2 then return 'Invalid params.';
image_target := ReplaceStr(getImageFileName(picture), 'xl/', '../');
drawing_id := excel_.WorkBook().GetSheetDrawing(sheetName_);
drawing_rels := excel_.WorkBook().GetDrawingRelsFile(drawing_id);
[rid, target] := class(xlsxXml).FindRelationshipRid(drawing_rels, image_target);
if target = '' then
begin
rid++;
class(xlsxXml).AddRelationshipRid(drawing_rels, image_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid);
end
content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types'));
class(xlsxXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg');
sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_);
node := sheet_xml.FirstChildElement('worksheet');
drawing_node := node.FirstChildElement('drawing');
if not ifObj(drawing_node) then
begin
prev_node := class(xlsxXml).GetWorkSheetPrevNode(node, 'drawing');
if ifObj(prev_node) then drawing_node := node.InsertAfterChild(prev_node, 'element', 'drawing');
else drawing_node := node.InsertEndChild('element', 'drawing');
end
sheet_rels := excel_.WorkBook().GetSheetRelsFile(sheetName_);
drawing_file_name := '../drawings/drawing' + inttostr(drawing_id) + '.xml';
[id, target] := class(xlsxXml).FindRelationshipRid(sheet_rels, drawing_file_name);
drawing_node.SetAttribute('r:id', 'rId' + inttostr(id));
// drawingN.xml
drawing_xml := excel_.WorkBook().GetXmlFileObj('xl/drawings/drawing' $ drawing_id $ ".xml");
if not ifObj(format) then format := TOfficeObj('TPictureFormat');
o := TOfficeObj('TtwoCellAnchor');
o.EditAs := 'oneCell';
o.XFrom.Col := col1;
o.XFrom.ColOff := format.BegColOff;
o.XFrom.Row := row1;
o.XFrom.RowOff := format.BegRowOff;
o.XTo.Col := col2;
o.XTo.ColOff := format.EndColOff;
o.XTo.Row := row2;
o.XTo.RowOff := format.EndRowOff;
o.Pic.NodeName := 'xdr:pic';
o.Pic.NvPicPr.NodeName := 'xdr:nvPicPr';
o.Pic.NvPicPr.CNvPr.Name := picture.Name ? picture.Name : '';
o.Pic.NvPicPr.CNvPr.ID := class(xlsxXml).GetcNvPrID(drawing_xml);
o.Pic.NvPicPr.CNvPr.Descr := picture.Descr ? : '';
o.Pic.NvPicPr.CNvPr.ExtLst.Ext.Uri := '';
o.Pic.NvPicPr.CNvPr.ExtLst.Ext.Xmlns16 := 'http://schemas.microsoft.com/office/drawing/2014/main';
o.Pic.NvPicPr.CNvPr.Replace(array("pic:": "xdr:"));
o.Pic.NvPicPr.CNvPicPr.PicLocks := "1";
o.Pic.BlipFill.NodeName := 'xdr:blipFill';
o.Pic.BlipFill.Blip.Xmlns := "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
o.Pic.BlipFill.Blip.Embed := 'rId' + inttostr(rid);
o.Pic.BlipFill.Stretch.FillRect := true;
o.Pic.SpPr.XFrm.Off.X := 0;
o.Pic.SpPr.XFrm.Off.Y := 0;
o.Pic.SpPr.XFrm.Ext.Cx := 0;
o.Pic.SpPr.XFrm.Ext.CY := 0;
o.Pic.SpPr.NodeName := 'xdr:spPr';
o.Pic.SpPr.PrstGeom.Prst := "rect";
o.Pic.SpPr.PrstGeom.AvLst := true;
drawing_xml.FirstChildElement('xdr:wsDr').InsertEndChild(o.Marshal());
End
Function DeletePicture(topLeft, bottomRight);
Begin
[err1, col1, row1] := excel_.CellNameToCoordinates(topLeft);
[err2, col2, row2] := excel_.CellNameToCoordinates(bottomRight);
if err1 or err2 then return 'Invalid params.';
drawing_id := excel_.WorkBook().GetSheetDrawing(sheetName_);
drawing_xml := excel_.WorkBook().GetXmlFileObj('xl/drawings/drawing' $ drawing_id $ ".xml");
if not ifObj(drawing_xml) then return 'drawing xml is not exist.';
wsDr_node := drawing_xml.FirstChildElement('xdr:wsDr');
node := wsDr_node.FirstChildElement('xdr:twoCellAnchor');
while ifObj(node) do
begin
from_node := node.FirstChildElement('xdr:from');
to_node := node.FirstChildElement('xdr:to');
from_col := strtoint(from_node.FirstChildElement('xdr:col').GetText());
from_row := strtoint(from_node.FirstChildElement('xdr:row').GetText());
to_col := strtoint(to_node.FirstChildElement('xdr:col').GetText());
to_row := strtoint(to_node.FirstChildElement('xdr:row').GetText());
if (col1 <= from_col and row1 <= from_row) and (col2 + 1 > to_col and row2 + 1 > to_row) then
prev := node;
node := node.NextElement();
if ifObj(prev) then wsDr_node.DeleteChild(prev);
end
End
private
Function getImageFileName(picture);
Begin
image_files := sselect ['FileName'] from zipfile_.Files() where AnsiStartsText('xl/media/image', ['FileName']) end;
image_file := '';
for i:=0 to length(image_files)-1 do
begin
if zipfile_.Diff(image_files[i], picture.Image) = 0 then
begin
image_file := image_files[i];
break;
end
end
if image_file = '' then
begin
image_count := length(image_files) + 1;
image_file := 'xl/media/image' $ image_count $ '.jpeg';
zipfile_.Add(image_file, picture.Image);
end
return image_file;
End
private
sheetName_:string; //sheet名称
sheetFileName_; //xl/worksheets/sheetN.xml
excel_;//TSExcelFile对象
xmlRelsFile_;
imageFileName_;
rid_;
zipfile_;
End;
+5 -9
View File
@@ -11,22 +11,18 @@ Type xlsxMargins = Class
marshal := margins.Marshal();
work_node := xmlFile_.FirstChild('worksheet');
node := work_node.FirstChild('pageMargins');
work_node.DeleteChild(node);
prev_node := work_node.FirstChild('phoneticPr');
if ifObj(node) then work_node.DeleteChild(node);
sheet_node := work_node.FirstChild('sheetData');
phone_node := work_node.FirstChild('phoneticPr');
prev_node := ifObj(phone_node) ? phone_node : sheet_node;
work_node.InsertAfterChild(prev_node, marshal);
End;
Function GetPageMargins();
Begin
node := xmlFile_.FirstChild('worksheet').FirstChild('pageMargins');
marshal := node.Marshal()[0];
margins := TOfficeObj('tmargins');
margins.Bottom := marshal['attributes']['bottom'];
margins.Footer := marshal['attributes']['footer'];
margins.Header := marshal['attributes']['header'];
margins.Left := marshal['attributes']['left'];
margins.Right := marshal['attributes']['right'];
margins.Top := marshal['attributes']['top'];
margins.RootObj := node;
return margins;
End
+14 -29
View File
@@ -8,45 +8,30 @@ Type xlsxPageLayout = Class
Function SetPageLayout(sheet, pageLayout);
Begin
if ifint(pageLayout.FirstPageNumber) then pageLayout.UseFirstPageNumber := True;
marshal := pageLayout.Marshal();
work_node := xmlFile_.FirstChild('worksheet');
node := work_node.FirstChild('pageSetUp');
if ifObj(node) then work_node.DeleteChild(node);
workbook_xml := file_.WorkBook().GetXmlFileObj('xl/workbook.xml');
workbook := workbook_xml.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
if not ifObj(workbook) then return array(1, 'workbook error!');
while ifObj(workbook) do
Begin
sheet_name := workbook.GetAttribute('name');
if sheet_name = sheet then
Begin
rid := workbook.GetAttribute('r:id');
break;
End
workbook := workbook.NextElement();
End
if not ifnil(marshal['attributes']['firstPageNumber']) then marshal['attributes']['useFirstPageNumber'] := 1;
marshal['attributes']['r:id'] := rid;
work_node.InsertEndChild(marshal);
return array(0, '');
arr := array('sheetData', 'mergeCells', 'phoneticPr', 'pageMargins');
for i:=length(arr)-1 to 0 do
begin
node := work_node.FirstChild(arr[i]);
if ifObj(node) then
begin
work_node.InsertAfterChild(node, marshal);
flag := 1;
end
end
if not flag then
work_node.InsertEndChild(marshal);
End;
Function GetPageLayout();
Begin
node := xmlFile_.FirstChild('worksheet').FirstChild('pageSetUp');
if not ifObj(node) then return array(1, '<node>: pageSetUp not found');
marshal := node.Marshal()[0];
page_layout := TOfficeObj('TPageLayout');
page_layout.Scale := marshal['attributes']['scale'];
page_layout.FitToWidth := marshal['attributes']['fitToWidth'];
page_layout.FitToHeight := marshal['attributes']['fitToHeight'];
page_layout.PaperSize := marshal['attributes']['paperSize'];
page_layout.Orientation := marshal['attributes']['orientation'];
page_layout.BlackAndWhite := marshal['attributes']['blackAndWhite'];
page_layout.FirstPageNumber := marshal['attributes']['firstPageNumber'];
page_layout.CellError := marshal['attributes']['errors'];
page_layout.CellComments := marshal['attributes']['cellComments'];
page_layout.Draft := marshal['attributes']['draft'];
page_layout.RootObj := node;
return page_layout;
End
+127
View File
@@ -0,0 +1,127 @@
Type xlsxShape = Class
///缺省构造函数
Function Create(sheet,excel); overload;
Begin
excel_ := excel;
sheetName_ := sheet;
zipfile_ := excel.Zip();
drawing_id := excel_.WorkBook().GetSheetDrawing(sheetName_);
sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_);
node := sheet_xml.FirstChildElement('worksheet');
drawing_node := node.FirstChildElement('drawing');
if not ifObj(drawing_node) then
drawing_node := node.InsertEndChild('element', 'drawing');
drawing_node.SetAttribute('r:id', 'rId' $ drawing_id);
// drawingN.xml
drawingXmlObj_ := excel_.WorkBook().GetXmlFileObj('xl/drawings/drawing' $ drawing_id $ ".xml");
End;
class Function NewObject(sheet, excel);
Begin
excel_ := excel;
o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在
if not ifObj(o) then return 0;
return new xlsxShape(sheet, excel);
End;
Function AddShape(topLeft, bottomRight, shapeType, format);
Begin
[err1, col1, row1] := excel_.CellNameToCoordinates(topLeft);
[err2, col2, row2] := excel_.CellNameToCoordinates(bottomRight);
if err1 or err2 then return 'Invalid params.';
o := TOfficeObj('TtwoCellAnchor');
o.XFrom.Col := col1;
o.XFrom.ColOff := format.BegColOff ? format.BegColOff : 0;
o.XFrom.Row := row1;
o.XFrom.RowOff := format.BegRowOff ? format.BegRowOff : 0;
o.XTo.Col := col2;
o.XTo.ColOff := format.EndColOff ? format.EndColOff : 0;
o.XTo.Row := row2;
o.XTo.RowOff := format.EndRowOff ? format.EndRowOff : 0;
o.Pic.NodeName := 'xdr:sp';
o.Pic.Macro := '';
o.Pic.Textlink := '';
setSpNvSpPr(o.Pic.NvPicPr, shapeType);
setSpSpPr(o.Pic.SpPr, shapeType);
setSpStyle(o.Pic.Style);
setSpTxBody(o.Pic.TxBody, format);
node := drawingXmlObj_.FirstChildElement('xdr:wsDr').InsertEndChild(o.Marshal());
End;
private
Function getShapeInfo();
Begin
return array(
'rect': ('name': '矩形'),
'roundRect': ('name': '矩形: 圆角'),
'mathMinus': ('name': '减号'),
'ellipse': ('name': '椭圆'),
);
End
Function setSpNvSpPr(obj, shapeType);
Begin
obj.NodeName := 'xdr:nvSpPr';
obj.CNvPr.ID := class(xlsxXml).GetcNvPrID(drawingXmlObj_);
obj.CNvPr.Name := (getShapeInfo()[shapeType]['name'] ?: '') $ ' ' $ obj.CNvPr.ID;
obj.CNvPr.ExtLst.Ext.Uri := '';
obj.CNvPr.ExtLst.Ext.Xmlns16 := 'http://schemas.microsoft.com/office/drawing/2014/main';
obj.CNvPr.Replace(array("pic:": "xdr:"));
obj.CNvSpPr := true;
End
Function setSpSpPr(obj, shapeType);
Begin
obj.XFrm.Off.X := 0;
obj.XFrm.Off.Y := 0;
obj.XFrm.Ext.Cx := 0;
obj.XFrm.Ext.CY := 0;
obj.PrstGeom.Prst := shapeType;
obj.PrstGeom.AvLst := true;
obj.NodeName := 'xdr:spPr';
End
Function setSpStyle(obj);
Begin
obj.LnRef.Idx := 2;
obj.LnRef.SchemeClr.Val := 'accent1';
obj.LnRef.SchemeClr.Shade := '50000';
obj.FillRef.Idx := 1;
obj.FillRef.SchemeClr.Val := 'accent1';
obj.EffectRef.Idx := 0;
obj.EffectRef.SchemeClr.Val := 'accent1';
obj.FontRef.Idx := 'minor';
obj.FontRef.SchemeClr.Val := 'lt1';
End
Function setSpTxBody(obj, format);
Begin
obj.BodyPr.VertOverflow := 'clip';
obj.BodyPr.HorzOverflow := 'clip';
obj.BodyPr.RtlCol := 0;
obj.BodyPr.Anchor := 't';
if istable(format.ExtNodes) then
begin
obj.ExtNodes := format.ExtNodes ?: array();
end
else begin
obj.P.PPr.Algn := 'l';
obj.P.EndParaRPr.Lang := 'zh-CN';
obj.P.EndParaRPr.AltLang := 'en-US';
obj.P.EndParaRPr.SZ := '1100';
end
End
private
sheetName_:string; //sheet名称
excel_;//TSExcelFile对象
zipfile_;
drawingXmlObj_;
End;
+14 -27
View File
@@ -17,44 +17,31 @@ Type xlsxStyles = Class
processNumFmtId(node, 'numFmts', style.NumberFormat);
numfmt_id := insertNode(node, 'numFmts', style.NumberFormat);
// 整理插入节点内容
child_arr := array();
alignment_marshal := style.Alignment.Marshal();
if istable(alignment_marshal['children']) or istable(alignment_marshal['attributes']) then
begin
alignment_flag := 1;
child_arr union= array(alignment_marshal);
end
protection_marshal := style.Protection.Marshal();
if istable(protection_marshal['children']) or istable(protection_marshal['attributes']) then
begin
protection_flag := 1;
child_arr union= array(protection_marshal);
end
attr_arr := array(
'numFmtId': style.NumberFormat.NumFmtId ? : "0",
'fontId': font_id,
'fillId': fill_id,
'borderId': border_id,
'xfId': 0,
);
if font_id <> '0' then attr_arr['applyFont'] := '1';
if border_id <> '0' then attr_arr['applyBorder'] := '1';
if numfmt_id <> '0' then attr_arr['applyNumberFormat'] := '1';
if fill_id <> '0' then attr_arr['applyFill'] := '1';
if alignment_flag then attr_arr['applyAlignment'] := '1';
if protection_flag then attr_arr['applyProtection'] := '1';
xf := TOfficeObj('TXf');
xf.NumFmtId := style.NumberFormat.NumFmtId ? : 0;
xf.FontId := font_id;
xf.FillId := fill_id;
xf.BorderId := border_id;
xf.XfId := 0;
xf.ApplyFont := font_id <> '0' ? 1 : nil;
xf.ApplyFill := fill_id <> '0' ? 1 : nil;
xf.ApplyBorder := border_id <> '0' ? 1 : nil;
xf.ApplyAlignment := alignment_flag ?: nil;
xf.ApplyProtection := protection_flag ?: nil;
xf.Alignment := style.Alignment;
xf.Protection := style.Protection;
arr := array('name': 'xf', 'type': 'element',
'attributes': attr_arr,
'children': child_arr,
);
node := node.FirstChildElement('cellXfs');
count := node.GetAttribute('count');
node.InsertEndChild(arr);
node.InsertEndChild(xf.Marshal());
node.SetAttribute('count', strtoint(count) + 1);
//node.print;
return count;
End
+117
View File
@@ -0,0 +1,117 @@
Type xlsxTable = Class
///缺省构造函数
Function Create(sheet, excel); overload;
Begin
excel_ := excel;
sheetName_ := sheet;
zipfile_ := excel.Zip();
End;
class Function NewObject(sheet, excel);
Begin
excel_ := excel;
o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在
if not ifObj(o) then return 0;
return new xlsxTable(sheet, excel);
End;
Function AddTable(topLeft, bottomRight, format, includeHeader);
Begin
[rid, table_id, table_name] := addTableXmlFileAndRelation();
table := TOfficeObj('TExcelTable');
table.Xmlns := 'http://schemas.openxmlformats.org/spreadsheetml/2006/main';
table.Mc := 'http://schemas.openxmlformats.org/markup-compatibility/2006';
table.Ignorable := 'xr xr3';
table.Xr := 'http://schemas.microsoft.com/office/spreadsheetml/2014/revision';
table.Xr3 := 'http://schemas.microsoft.com/office/spreadsheetml/2016/revision3';
table.Id := table_id;
table.Name := '表' $ table_id;
table.DisplayName := format.TableName ? format.TableName : table.Name;
table.Ref := topLeft $ ':' $ bottomRight;
table.HeaderRowCount := format.HeaderRowCount ? '1' : nil;
table.TotalsRowShown := format.TotalsRowShown ? '1' : '0';
table.AutoFilter := table.Ref;
format.TableName := nil;
format.HeaderRowCount := nil;
format.TotalsRowShown := nil;
// <tableColumns />
[err1, col1, row1] := excel_.CellNameToCoordinates(topLeft);
[err2, col2, row2] := excel_.CellNameToCoordinates(bottomRight);
table_str := getTableColumnsXmlString(col1, col2, row1, includeHeader);
table_xml := excel_.WorkBook().GetXmlFileObj(table_name);
table_node := table_xml.FirstChild('table');
marshal := table.Marshal();
class(xlsxXml).UpdateNode(table_node, marshal['attributes'], marshal['children']);
table_node.InsertEndChild(table_str);
table_node.InsertEndChild(format.Marshal());
//sheetN.xml
sheet_xml := excel_.WorkBook().GetSheetXmlFile(sheetName_);
worksheet_node := sheet_xml.FirstChildElement('worksheet');
table_part := worksheet_node.FirstChildElement('tableParts');
if not ifObj(table_part) then
begin
table_part := worksheet_node.InsertEndChild('element', 'tableParts');
count := 1;
end
else begin
count := inttostr(table_part.GetAttribute('count')) + 1;
end
node := table_part.InsertEndChild('element', 'tablePart');
node.SetAttribute('r:id', 'rId' $ rid);
table_part.SetAttribute('count', count);
End
private
Function getTableColumnsXmlString(begCol, endCol, row, includeHeader);
Begin
table_str := '<tableColumns count="' $ (endCol - begCol + 1) $ '">';
id := 1;
col_index := 1;
if not includeHeader then
begin
excel_.InsertRow(sheetName_, row);
end
for i:=begCol to endCol do
begin
[err, cell] := excel_.CoordinatesToCellName(i, row, false);
if includeHeader then
name := excel_.GetCellValue(sheetName_, cell)[1];
else begin
name := "列" $ col_index++;
excel_.SetCellValue(sheetName_, cell, name);
end
table_str += fmt('<tableColumn id="{}" name="{}" />', id++, name);
end
table_str += "</tableColumns>";
return table_str;
End
Function addTableXmlFileAndRelation();
Begin
sheet_rels_file := excel_.WorkBook().GetSheetRelsFile(sheetName_);
[rid, target] := class(xlsxXml).FindRelationshipRid(sheet_rels_file, '');
rid ++;
table_id := excel_.WorkBook().GetFilesCount('xl/tables/') + 1;
table_name := 'xl/tables/table' + inttostr(table_id) + '.xml';
table_target := '../tables/table' + inttostr(table_id) + '.xml';
excel_.zip().Add(table_name, class(xlsxXml).XmlHeader() + "<table />");
class(xlsxXml).AddRelationshipRid(sheet_rels_file, table_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/table', 'rId' $ rid);
content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types'));
class(xlsxXml).AddOverrideContentType(content_xml, '/' + table_name, 'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml');
return array(rid, table_id, table_name);
End
private
sheetName_:string; //sheet名称
excel_;//TSExcelFile对象
zipfile_;
tableXmlFile_;
End;
File diff suppressed because it is too large Load Diff