Compare commits

..
82 Commits
Author SHA1 Message Date
csh 15e2cbe661 整理word内容作为unit 2023-12-07 13:41:06 +08:00
csh 3643be6231 update 2023-08-29 15:05:06 +08:00
csh e2e68efc30 Merge branch 'master' into word 2023-08-29 15:00:42 +08:00
csh ef0dcde062 v1.4.4-patch2 2023-08-29 11:33:57 +08:00
csh ba5f255573 v1.4.4-patch1 2023-08-28 17:54:56 +08:00
csh 79ba3254a0 v1.4.4 2023-08-28 17:17:15 +08:00
csh 81b806c93c v1.4.3-patch2 2023-08-25 16:37:07 +08:00
csh 60847b0636 v1.4.3-patch1 2023-08-25 10:54:54 +08:00
csh 819efc1ee1 v1.4.3 2023-08-22 14:33:57 +08:00
csh 9037124c01 v1.4.2-patch1 2023-08-18 18:05:48 +08:00
csh b59c869ae2 v1.4.2 2023-08-18 16:49:12 +08:00
csh 8d63ecd7b3 v1.4.1 2023-08-11 16:27:15 +08:00
csh f781cd0c0a v1.4.0-patch2 2023-08-10 17:36:28 +08:00
csh 522142b712 v1.4.0-patch1 2023-08-10 15:24:47 +08:00
csh 6eec96d84d v1.4.0 2023-08-10 15:24:30 +08:00
csh 1abc2028fe v1.3.9 2023-08-07 15:52:57 +08:00
csh 1d0b5684cc v1.3.8-patch1 2023-08-02 17:24:10 +08:00
csh 0c73a4c0d1 v1.3.8 2023-08-02 16:32:01 +08:00
csh ced0d6b04c v1.3.7 2023-07-26 14:35:05 +08:00
csh 880e03c41a v1.3.6 2023-07-19 17:47:54 +08:00
csh 2384ca42b5 Merge branch 'master' into word 2023-07-14 10:37:15 +08:00
csh 845c6bb554 v1.3.5 2023-07-14 10:33:49 +08:00
csh f34d03a50f v1.3.4 2023-07-11 15:11:36 +08:00
csh ff6d23090e v1.3.3-patch1 2023-07-04 14:40:50 +08:00
csh f46240850e v1.3.3 2023-07-04 14:16:27 +08:00
csh ce331f4417 v1.3.2 2023-06-26 11:08:48 +08:00
csh c706d2d8d0 v1.3.2 2023-06-20 18:17:39 +08:00
csh 8f6bdd212b update two template 2023-06-13 13:27:59 +08:00
csh 0e21645b2a v1.3.1-patch1 2023-06-05 17:08:00 +08:00
csh d08dea6bc9 update TSTag 2023-05-19 10:41:46 +08:00
csh 10ef45f1a0 add TSTag and wordtemplate 2023-05-17 17:25:21 +08:00
csh c536c4d531 excel gettable中文 2023-05-17 13:57:13 +08:00
csh 4dc02530ba init word_templat 2023-05-16 16:49:34 +08:00
csh 823aa12a98 v1.3.1 2023-05-11 15:08:18 +08:00
csh 77762ce275 v1.3.0 2023-04-18 15:34:45 +08:00
csh df79a459dd v1.2.9 2023-04-04 10:21:28 +08:00
csh e39cd05b1f v1.2.8 2023-03-31 14:57:34 +08:00
csh 08f046ed02 v1.2.7-patch3 2023-03-24 10:15:35 +08:00
csh 35ef5fdbb4 v1.2.7-patch2 2023-03-23 17:57:17 +08:00
csh 8e5d4935f3 v1.2.7-patch1 2023-03-23 15:24:06 +08:00
csh 84be550383 v1.2.7 2023-03-23 11:40:15 +08:00
csh 9c416109f5 v1.2.6-patch2 2023-03-22 19:11:04 +08:00
csh fb3032cf83 v1.2.6-patch1 2023-03-22 17:39:32 +08:00
csh 756e6708d6 v1.2.6 2023-03-22 15:10:15 +08:00
csh 84673ea219 v1.2.5 2023-03-20 10:18:15 +08:00
csh fbec04c5e7 v1.2.4 2023-03-16 18:08:35 +08:00
csh 387c2fbccc v1.2.3-patch2 2023-03-14 17:07:26 +08:00
csh 6dda8f85bc v1.2.3-patch1 2023-03-14 11:41:09 +08:00
csh 7b0756e573 v1.2.3 2023-03-09 18:02:52 +08:00
csh 3d68bf2256 v1.2.2 2023-03-06 15:36:51 +08:00
csh 894303ccef v1.2.1 2023-02-24 14:53:35 +08:00
csh 710077aff4 v1.2.0 2023-02-23 11:10:51 +08:00
csh b8a23ba5a2 v1.1.9-patch1 2023-02-22 18:00:29 +08:00
csh 6721a005ca v1.1.9 2023-02-22 16:03:26 +08:00
csh 89bfc05455 v1.1.8 2023-02-22 10:49:11 +08:00
csh 80783ee8a4 v1.1.7 2023-02-21 17:26:44 +08:00
csh b9955b3b05 v1.1.6-patch2 2023-02-14 15:12:05 +08:00
csh 186287db1c v1.1.6-patch1 2023-02-13 15:18:37 +08:00
csh 780d9ecb6d v1.1.6 2023-02-13 15:10:31 +08:00
csh 3af1d35304 v1.1.5 2023-02-03 14:45:28 +08:00
csh 919c80f1b0 v1.1.4-patch2 2023-02-02 16:25:08 +08:00
csh 47e9ff9a46 v1.1.4-patch 2023-02-02 15:15:25 +08:00
csh bdf358b39b v1.1.4 2023-02-02 14:45:21 +08:00
csh 8276de4e92 v1.1.3-patch 2023-02-01 17:14:24 +08:00
csh 6cbbc3b98c v1.1.3 2023-02-01 15:18:46 +08:00
csh 2037e8c2fe v1.1.2 2023-01-31 17:27:13 +08:00
csh 3146c3c9c5 v1.1.1 2023-01-18 16:49:57 +08:00
csh 331317b6f6 v1.1.0-patch 2023-01-17 16:30:05 +08:00
csh 1873f9bf27 v1.1.0 2023-01-16 14:59:53 +08:00
csh ce521a6a69 v1.0.9 2023-01-12 16:05:44 +08:00
csh e2db550f99 v1.0.8 2023-01-11 14:34:38 +08:00
csh d3e01ef4a5 v1.0.7 2023-01-10 14:14:36 +08:00
csh a4ff2eae83 v1.0.6 2023-01-10 09:59:07 +08:00
csh 9b8b7f79d9 v1.0.5 2023-01-05 15:28:10 +08:00
csh ee77e920b3 v1.0.4 2022-12-30 10:49:51 +08:00
csh 88aa334c7a docxFile使用帮助 2022-12-23 14:31:39 +08:00
csh 735b9ed8ae 更新docx帮助文档 2022-12-23 14:26:13 +08:00
hans f7cf483e62 1.01 2022-12-23 13:38:03 +08:00
hans d8a9d896da update 2022-12-23 13:36:37 +08:00
hans b2c3378972 update 2022-12-23 13:35:23 +08:00
csh 8d6d10d7e9 Merge branch 'master' of https://git.mytsl.cn/tinysoft/OfficePlugin 2022-12-23 11:43:58 +08:00
csh a60a6f9e54 release 1.03 nodeinfo Bug修复 2022-12-23 11:43:40 +08:00
81 changed files with 8574 additions and 3028 deletions
+104 -45
View File
@@ -13,14 +13,10 @@ if err then
return PrintError("NewFile", err, errinfo);
PrintSuccess("NewFile", testing++);
[err, errinfo] := file.SetSheetName('Sheet1', 'ExcelFile');
if err then
return PrintError("SetSheetName", err, errinfo);
file.SetSheetName('Sheet1', 'ExcelFile');
PrintSuccess("SetSheetName", testing++);
[err, errinfo] := file.NewSheet("Functions");
if err then
return PrintError("NewSheet", err, errinfo);
file.NewSheet("Functions");
PrintSuccess("NewSheet", testing++);
file.SetDefaultSheet('ExcelFile');
@@ -60,9 +56,11 @@ style.Border.Top.LineStyle := "double";
style.Border.Top.Color := "FF0000";
style.Alignment.Horizontal := "center";
style.Alignment.Vertical := "center";
style.Fill.Gradient.Shading := 3;
style.Fill.Gradient.Color1 := "FFFFFF";
style.Fill.Gradient.Color2 := "E0EBF5";
style.Fill.Gradient.Degree := 0;
style.Fill.Gradient.Stop1.Position := 0;
style.Fill.Gradient.Stop1.Color := "FFFFFF";
style.Fill.Gradient.Stop2.Position := 1;
style.Fill.Gradient.Stop2.Color := "E0EBF5";
styleId := file.NewStyle(style);
PrintSuccess("NewStyle", testing++);
@@ -129,7 +127,7 @@ Begin
row++;
hyperlink := TOfficeObj('THyperLink');
hyperlink.LinkType := "Location";
hyperlink.LinkType := "location";
hyperlink.LinkUrl := "Functions!" $ c1;
file.SetCellHyperLink("ExcelFile", cell1, hyperlink);
@@ -140,7 +138,7 @@ End
file.SetColWidth('Functions', 'A', 'A', 120);
PrintSuccess('SetColWidth', testing++);
saveName := utf8toansi("d:\\temp\\ExcelFile使用帮助.xlsx");
saveName := utf8toansi("ExcelFile使用帮助.xlsx");
[err, errinfo] := file.SaveAs('', saveName);
if err then
return PrintError("SaveAs", err, errinfo);
@@ -227,9 +225,15 @@ Begin
style.Font.Size := 14;
style.Font.Bold := True;
style.Font.UnderLine := 'singleAccounting';
style.Fill.Gradient.Shading := 16;
style.Fill.Gradient.Color1 := 'A3ECFB';
style.Fill.Gradient.Color2 := '626AD8';
style.Fill.Gradient.Type := 'path';
style.Fill.Gradient.Left := 0.5;
style.Fill.Gradient.Left := 0.5;
style.Fill.Gradient.Left := 0.5;
style.Fill.Gradient.Left := 0.5;
style.Fill.Gradient.Stop1.Position := 0;
style.Fill.Gradient.Stop1.Color := "A3ECFB";
style.Fill.Gradient.Stop2.Position := 1;
style.Fill.Gradient.Stop2.Color := "626AD8";
styleid1 := excel.NewStyle(style);
style := TOfficeObj('TStyle');
@@ -491,9 +495,11 @@ style.NumberFormat.FormatCode := '#,##0.000_ ';
//style.Fill.Pattern.PatternType := 'solid';
//style.Fill.Pattern.ForegroundColor := 'FF6699FF';
//style.Fill.Pattern.BackgroundColor := 'FFFF0000';
style.Fill.Gradient.ThemeColor1 := 0;
style.Fill.Gradient.ThemeColor2 := 4;
style.Fill.Gradient.Shading := 1;
style.Fill.Gradient.Degree := 270;
style.Fill.Gradient.Stop1.Position := 0;
style.Fill.Gradient.Stop1.ThemeColor := 0;
style.Fill.Gradient.Stop2.Position := 1;
style.Fill.Gradient.Stop2.ThemeColor := 4;
style.Protection.Hide := 1;
style.Protection.Lock := 1;
";
@@ -529,6 +535,7 @@ style.Protection.Lock := 1;
('attrName': 'Vertical', 'type': 'string', 'desc': '垂直对齐', 'value': array('nil(默认): 靠下', '"center": 居中', '"top": 靠上', '"justify": 两端对齐', 'distributed: 分散对齐')),
('attrName': 'WrapText', 'type': 'boolean', 'desc': '是否自动换行,默认FALSE', 'value': array()),
('attrName': 'ReadingOrder', 'type': 'int', 'desc': '文字方向', 'value': array('nil(默认): 根据内容', '1: 总是从左到右', '2: 总是从右到左')),
('attrName': 'TextRotation', 'type': 'int', 'desc': '文本方向', 'value': array('[-90:90]')),
),
'Demo': '',
),
@@ -545,7 +552,7 @@ style.Protection.Lock := 1;
('attrName': '', 'type': 'double', 'desc': '{颜色}{Color}和{ThemeColor}只能设置一种', 'value': array()),
('attrName': 'Color', 'type': 'string', 'desc': 'RGB颜色,如"A020F0"', 'value': array()),
('attrName': 'ThemeColor', 'type': 'int', 'desc': '主题颜色', 'value': array()),
('attrName': 'Underline', 'type': 'string', 'desc': '下划线', 'value': array('"double": 双下划线', '"singleAccounting": 会计单下划线', '"doubleAccounting": 会计双下划线')),
('attrName': 'Underline', 'type': 'string', 'desc': '下划线', 'value': array('"none": 无', '"single": 单下划线', '"double": 双下划线', '"singleAccounting": 会计单下划线', '"doubleAccounting": 会计双下划线')),
),
'Demo': '',
),
@@ -599,30 +606,26 @@ style.Protection.Lock := 1;
('ObjName': 'TGradient',
'Desc': ('TGradient有以下属性: '),
'AttrInfo': (
('attrName': '', 'type': '', 'desc': '{颜色1}:渐变的第一种颜色,{Color1}和{ThemeColor1}只能设置一种', 'value': array()),
('attrName': 'Color1', 'type': 'string', 'desc': 'RGB颜色', 'value': array()),
('attrName': 'ThemeColor1', 'type': 'int', 'desc': '主题颜色', 'value': array()),
('attrName': '', 'type': '', 'desc': '{颜色2}:渐变的第一种颜色,{Color2}和{ThemeColor2}只能设置一种', 'value': array()),
('attrName': 'Color2', 'type': 'string', 'desc': 'RGB颜色', 'value': array()),
('attrName': 'ThemeColor2', 'type': 'int', 'desc': '主题颜色', 'value': array()),
('attrName': 'Shading', 'type': 'int', 'desc': '底纹样式', 'value': array('0: 水平渐变,颜色1从上到下渐变到颜色2', '1: 水平渐变,颜色2从上到下渐变到颜色1',
'2: 水平渐变,三层颜色,颜色1从上渐变到中间颜色2,再从颜色2渐变到底部颜色1',
'3: 垂直渐变,颜色1从左到右渐变到颜色2',
'4: 垂直渐变,颜色2从右到左渐变到颜色1',
'5: 垂直渐变,三层颜色,颜色1从左渐变到中间颜色2,再从颜色2渐变到右边颜色1',
'6: 斜上渐变,颜色1左上渐变到右下颜色2',
'7: 斜上渐变,颜色2左上渐变到右下颜色1',
'8: 斜上渐变,三层颜色,颜色1从左上渐变到对角线颜色2,再从颜色2渐变到右下颜色1',
'9: 斜下渐变,颜色1右上渐变到左下颜色2',
'10: 斜下渐变,颜色2左上渐变到右下颜色1',
'11: 斜下渐变,三层颜色,颜色1从左上渐变到对角线颜色2,再从颜色2渐变到右下颜色1',
'12: 角部辐射渐变,颜色1左上角辐射渐变到右下角2',
'13: 角部辐射渐变,颜色1右上角辐射渐变到左下角颜色2',
'14: 角部辐射渐变,颜色1左下角辐射渐变到右上角2',
'15: 角部辐射渐变,颜色1右下角辐射渐变到左上角颜色2',
'16: 中心辐射渐变,颜色1从中心向四周辐射到颜色2',
)),
),
('attrName': 'Degree', 'type': 'int', 'desc': '渐变的角度(水平、垂直、斜上、斜下)', 'value': array(0, 45, 90, 135, 180, 225, 270, 315)),
('attrName': 'Type', 'type': 'string', 'desc': '辐射渐变,采用辐射渐变时,不需设置{Degree}', 'value': array('path')),
('attrName': 'Left', 'type': 'string', 'desc': '辐射渐变时需设置属性', 'value': array()),
('attrName': 'Right', 'type': 'string', 'desc': '辐射渐变时需设置属性', 'value': array()),
('attrName': 'Top', 'type': 'string', 'desc': '辐射渐变时需设置属性', 'value': array()),
('attrName': 'Bottom', 'type': 'string', 'desc': '辐射渐变时需设置属性', 'value': array()),
('attrName': 'Stop1', 'type': 'class - TStop', 'desc': '渐变点需要设置的信息', 'value': array()),
('attrName': 'Stop2', 'type': 'class - TStop', 'desc': '渐变点需要设置的信息', 'value': array()),
('attrName': 'Stop3', 'type': 'class - TStop', 'desc': '渐变点需要设置的信息', 'value': array()),
),
'Demo': '',
),
('ObjName': 'TStop',
'Desc': ('TStop有以下属性: '),
'AttrInfo': (
('attrName': 'Position', 'type': 'double', 'desc': '', 'value': array()),
('attrName': 'Color', 'type': 'string', 'desc': 'RGB颜色', 'value': array()),
('attrName': 'ThemeColor', 'type': 'int', 'desc': '主题颜色', 'value': array()),
('attrName': 'ThemeColorTint', 'type': 'int', 'desc': '主题颜色的色调', 'value': array()),
),
'Demo': '',
),
('ObjName': 'TProtection',
@@ -669,7 +672,8 @@ style.Protection.Lock := 1;
('attrName': 'Scale', 'type': 'int', 'desc': '缩放比例(%)', 'value': array()),
('attrName': 'FitToWidth', 'type': 'int', 'desc': '页宽', 'value': array()),
('attrName': 'FitToHeight', 'type': 'int', 'desc': '页高', 'value': array()),
('attrName': 'FirstPageNumber', 'type': 'int', 'desc': '起始页码', 'value': array()),
('attrName': 'UseFirstPageNumber', 'type': 'bool', 'desc': '是否启用起始页码', 'value': array()),
('attrName': 'FirstPageNumber', 'type': 'int', 'desc': '起始页码,{UseFirstPageNumber}为true时有效', 'value': array()),
('attrName': 'Orientation', 'type': 'string', 'desc': '纸张方向', 'value': array('"landscape": 横向', '"portrait": 纵向')),
('attrName': 'PageOrder', 'type': 'string', 'desc': '打印顺序', 'value': array('nil(默认): 先列后行', '"overThenDown": 先行后列')),
('attrName': 'BlackAndWhite', 'type': 'boolean', 'desc': '单色打印', 'value': array()),
@@ -697,10 +701,9 @@ style.Protection.Lock := 1;
('ObjName': 'THyperLink',
'Desc': ('THyperLink有以下属性: '),
'AttrInfo': (
('attrName': 'LinkType', 'type': 'string', 'desc': '超链接类型', 'value': array('"External": 外部超链接', '"Location"': 内部超链接)),
('attrName': 'LinkType', 'type': 'string', 'desc': '超链接类型', 'value': array('"external": 外部超链接', '"location"': 内部超链接)),
('attrName': 'LinkUrl', 'type': 'string', 'desc': '超链接地址', 'value': array()),
('attrName': 'Tooltip', 'type': 'string', 'desc': '超链接悬浮提示内容', 'value': array()),
('attrName': 'Display', 'type': 'string', 'desc': '单元格显示的内容', 'value': array()),
),
'Demo': '',
),
@@ -722,5 +725,61 @@ style.Protection.Lock := 1;
),
'Demo': '',
),
('ObjName': 'TProtect',
'Desc': ('TProtect有以下属性: '),
'AttrInfo': (
('attrName': 'EditObjects', 'type': 'bool', 'desc': '编辑方案', 'value': array()),
('attrName': 'EditScenarios', 'type': 'bool', 'desc': '编辑方案', 'value': array()),
('attrName': 'FormatCells', 'type': 'bool', 'desc': '设置单元格格式', 'value': array()),
('attrName': 'FormatColumns', 'type': 'bool', 'desc': '设置列格式', 'value': array()),
('attrName': 'FormatRows', 'type': 'bool', 'desc': '设置行格式', 'value': array()),
('attrName': 'InsertColumns', 'type': 'bool', 'desc': '插入行', 'value': array()),
('attrName': 'InsertRows', 'type': 'bool', 'desc': '插入列', 'value': array()),
('attrName': 'InsertHyperlinks', 'type': 'bool', 'desc': '插入超链接', 'value': array()),
('attrName': 'DeleteColumns', 'type': 'bool', 'desc': '删除列', 'value': array()),
('attrName': 'DeleteRows', 'type': 'bool', 'desc': '删除行', 'value': array()),
('attrName': 'SelectLockedCells', 'type': 'bool', 'desc': '选定锁定的单元格', 'value': array()),
('attrName': 'Sort', 'type': 'bool', 'desc': '排序', 'value': array()),
('attrName': 'AutoFilter', 'type': 'bool', 'desc': '使用自动筛选', 'value': array()),
('attrName': 'PivotTables', 'type': 'bool', 'desc': '使用自动透视表和自动透视图', 'value': array()),
),
'Demo': '',
),
('ObjName': 'TSheetView',
'Desc': ('TSheetView有以下属性: '),
'AttrInfo': (
('attrName': 'ShowGridLines', 'type': 'bool', 'desc': '网格线', 'value': array()),
('attrName': 'ShowRowColHeaders', 'type': 'bool', 'desc': '标题', 'value': array()),
('attrName': 'View', 'type': 'bool', 'desc': '工作簿视图', 'value': array('"pageBreakPreview": 分页预览')),
('attrName': 'ZoomScale', 'type': 'string', 'desc': '缩放比例(%)', 'value': array()),
),
'Demo': '',
),
('ObjName': 'TPane',
'Desc': ('TPane有以下属性: '),
'AttrInfo': (
('attrName': 'XSplit', 'type': 'int', 'desc': '按列分割', 'value': array()),
('attrName': 'YSplit', 'type': 'int', 'desc': '按行分割', 'value': array()),
('attrName': 'ActivePane', 'type': 'string', 'desc': '激活窗格', 'value': array('"bottomRight": 都设置{XSplit}和{YSplit}时为该值', '"topRight": 仅设置{XSplit}时', '"bottomLeft": 仅设置{YSplit}时')),
('attrName': 'State', 'type': 'string', 'desc': '冻结窗口', 'value': array('"frozen"')),
('attrName': 'TopLeftCell', 'type': 'string', 'desc': '顶部单元格,根据{ActivePane}的值设定', 'value': array()),
),
'Demo': '',
),
('ObjName': 'TCalcPr',
'Desc': ('TCalcPr有以下属性: '),
'AttrInfo': (
('attrName': 'CalcMode', 'type': 'string', 'desc': '工作簿计算模式', 'value': array('nil(默认): 自动重算', '"autoNoTable": 除模拟运算表外自动重算', '"manual": 手动重算')),
('attrName': 'RefMode', 'type': 'string', 'desc': 'R1C1引用样式', 'value': array('nil(默认): 不启用', '"R1C1": 启用R1C1引用样式')),
('attrName': 'Iterate', 'type': 'bool', 'desc': '是否启用迭代计算', 'value': array()),
('attrName': 'IterateCount', 'type': 'int', 'desc': '最多迭代次数', 'value': array()),
('attrName': 'IterateDelta', 'type': 'double', 'desc': '最大误差', 'value': array()),
('attrName': 'CalcOnSave', 'type': 'bool', 'desc': '保存工作簿之前重新计算,{CalcMode}为"manual"时有效', 'value': array()),
('attrName': 'ConCurrentCalc', 'type': 'bool', 'desc': '是否启用多线程计算', 'value': array()),
('attrName': 'ConCurrentManualCount', 'type': 'int', 'desc': '自定义计算线程数', 'value': array()),
('attrName': 'FullPrecision', 'type': 'bool', 'desc': '是否采用完整精度', 'value': array()),
),
'Demo': '',
),
);
End
-127
View File
@@ -1,127 +0,0 @@
docx := new TSDocxFile();
//_test_readParagraphs(docx);
_test_newfile(docx);
//_test_addtable(docx);
//_test_Properties(docx);
//_test_picture(docx);
Function _test_picture(docx);
Begin
[err, errmsg] := docx.NewFile();
if err then
return echo 'Open Fail:', errmsg, '\n';
picture := TOfficeObj('TPicture');
picture.Descr := 'Hans Tan\'s Picture test';
readfile(rwbinary(), '', 'F:\\temp\\VS2010Ultim\\Setup\\banner.bmp', 0, 1024*1024, data);
picture.Image := data;
p := docx.AddPicture(picture, -1);
v := docx.SaveAs('', 'f:\\temp\\p.docx');
println('Save={}', v);
End;
Function _test_Properties(docx);
Begin
f := 'F:\\temp\\test.docx';
[err, errmsg] := docx.OpenFile('', f);
if err then return
echo 'Open Fail:', errmsg, '\n';
core := docx.Properties();
core.Author := 'Hans Tan';
core.Modified := now();
docx.SaveAs('', 'f:\\temp\\core.docx');
End;
Function _test_addtable(docx);
Begin
[err, errmsg] := docx.NewFile();
if err then return
echo 'Open Fail:', errmsg, '\n';
data := array(("Name":"Small","Apple":2,"Orange":3,"Pear":3),
("Name":"Normal","Apple":5,"Orange":2,"Pear":4),
("Name":"Large","Apple":6,"Orange":7,"Pear":8));
tbl := docx.CreateTable(data, true, true);
//tbl.TblPr.Style := 1;
tbl := docx.InsertTable(tbl, -1);
v := docx.SaveAs('', 'f:\\temp\\t.docx');
println('Save={}', v);
End;
Function _test_newfile(docx);
Begin
[err, errmsg] := docx.NewFile();
if err then return
echo 'Open Fail:', errmsg, '\n';
paragraph := TOfficeObj('TParagraph');
paragraph.Run.Text := 'This is the 1 Line.';
p := docx.AddParagraph(paragraph, -1);
p := docx.AddLineBreak(p);
p := docx.AddLineBreak(p);
paragraph.Run.Text := 'This is the 2 Line.';
p := docx.AddParagraph(paragraph, -1);
p := docx.AddPageBreak(p);
paragraph.Run.Text := 'This is the 3 Line.';
p := docx.AddParagraph(paragraph, -1);
p := docx.AddColumnBreak(p);
paragraph.Run.Text := '';
p := docx.AddParagraph(paragraph, -1);
p.SetText('This is the 4 Line\nline5\nline6\nline7.');
v := docx.SaveAs('', 'f:\\temp\\new.docx');
println('Save={}', v);
End;
Function _test_readParagraphs(docx);
Begin
f := 'F:\\temp\\test.docx';
[err, errmsg] := docx.OpenFile('', f);
if err then return
echo 'Open Fail:', errmsg, '\n';
paragraph := TOfficeObj('TParagraph');
paragraph.Run.Text := 'New paragraph';
v := docx.AddParagraph(paragraph, 0);
paragraphs := docx.Paragraphs();
println("AddParagraph={}", v);
paragraphs[9].SetText('1、修改文字;
2、第2段;
3、第3段;
4、第4段。');
paragraphs := docx.Paragraphs();
for i:=0 to length(paragraphs)-1 do Begin
println('Name={}, Text={}', paragraphs[i].Name(), paragraphs[i].Text());
End;
tcnt := docx.TablesCount();
println('\n\nTableCount={}',tcnt);
for i := 0 to tcnt-1 do Begin
table := docx.GetTable(i);
for j := 0 to table.Rows()-1 do Begin
for k := 0 to table.Cols()-1 do Begin
cell := table.Cell(j, k);
if ifObj(cell) then Begin
println('row={}, col={}, text={}', j, k, cell.Text());
continue;
End;
println('row={}, col={}, Cell=nil', j, k);
End;
End;
End;
println('all text={}, textArray={}', docx.Text(), docx.TextArray());
docx.SaveAs('', 'f:\\temp\\p.docx');
End;
+188 -79
View File
@@ -1,10 +1,12 @@
TOfficeApi().CodePage('中文');
testCount := 0;
sheetName := "hello";
sheetName2 := "world";
sheetName := "你好";
sheetName2 := "中文";
// OpenFile
excel := new TSExcelFile();
[err, errmsg] := excel.OpenFile('', 'd:\\temp\\raw.xlsx');
[err, errmsg] := excel.OpenFile('', 'd:\\temp\\b.xlsx');
PrintInfo("OpenFile", err, errmsg);
// Save
@@ -12,43 +14,61 @@ PrintInfo("OpenFile", err, errmsg);
PrintInfo("Save", err, errmsg);
excel := new TSExcelFile();
// NewFile
[err, errmsg] := excel.NewFile();
PrintInfo("NewFile", err, errmsg);
// SaveAs
// [err, errmsg] := excel.SaveAs('', 'd:\\temp\\test.xlsx');
// PrintInfo("SaveAs", err, errmsg);
[err, errmsg] := excel.SaveAs('', 'd:\\temp\\test.xlsx');
PrintInfo("SaveAs", err, errmsg);
// FileName
name := excel.FileName();
println("[success] name = {}", name);
// GetSheet
sheets := excel.GetSheets();
println("[success] sheets = {}", sheets);
// GetSheetsCount
sheetCount := excel.GetSheetsCount();
println("[success] GetSheetsCount = {}", sheetCount);
// SetSheetName
[err, errmsg] := excel.SetSheetName("sheet1", sheetName);
PrintInfo("SetSheetName", err, errmsg);
excel.SetSheetName("sheet1", sheetName);
println("[success] SetSheetName");
// GetSheetName
sheetName := excel.GetSheetName(0);
println("[success] GetSheetName = {}", sheetName);
Name := excel.GetSheetName(0);
println("[success] GetSheetName = {}", Name);
// NewSheet
[err, errmsg] := excel.NewSheet(sheetName2);
PrintInfo("NewSheet", err, errmsg);
excel.NewSheet(sheetName2);
println("[success] NewSheet");
// NewSheet
excel.NewSheet(sheetName, 'sheet_copy');
println("[success] NewSheet2");
// InsertSheet
excel.InsertSheet(sheetName, sheetName + 'before');
println("[success] NewSheet2");
// GetSheets
sheets := excel.GetSheets();
println("[success] sheets = {}", sheets);
// DeleteSheet
[err, errmsg] := excel.NewSheet("test1");
//[err, errmsg] := excel.DeleteSheet("test1");
//PrintInfo("DeleteSheet", err, errmsg);
excel.NewSheet("test1");
excel.DeleteSheet("test1");
println("[success] DeleteSheet");
// SetCellValue
excel.SetCellValue(sheetName, "A1", 100);
excel.SetCellValue(sheetName, "F1", "中文的壹佰");
println("[success] SetCellValue");
// GetCellValue
[err, errmsg] := excel.GetCellValue(sheetName, "A1");
PrintInfo("GetCellValue A1 ", err, errmsg);
[err, errmsg] := excel.GetCellValue(sheetName, "F1");
PrintInfo("GetCellValue F1 ", err, errmsg);
// TotalCols
totalCols := excel.TotalCols(sheetName);
@@ -58,17 +78,9 @@ println("[success] TotalCols = {}", totalCols);
totalRows := excel.TotalRows(sheetName);
println("[success] TotalRows = {}", totalRows);
// SetCellValue
flag := excel.SetCellValue(sheetName, "A1", 100);
println("[success] SetCellValue = ", flag);
// GetCellValue
[err, errmsg] := excel.GetCellValue(sheetName, "A1");
PrintInfo("GetCellValue", err, errmsg);
// SetCellRichText
richText := TOfficeObj('TRichtext');
text1 := richText.AddText('Hello');
text1 := richText.AddText('Hello 你好');
text1.Font.Size := 35;
text1.Font.Color := "FFF000";
text2 := richText.AddText(" World");
@@ -77,10 +89,9 @@ text2.Font.Bold := true;
excel.SetCellRichText(sheetName, "A2", richText);
text2.Text := "python";
excel.SetCellRichText(sheetName, "A3", richText);
println("[success] SetCellRichText");
// GetCellRichText
arr := excel.GetCellRichText(sheetName, "A3");
arr := excel.GetCellRichText(sheetName, "A2");
println("[success] GetCellRichText = {}", arr);
// ClearCell
@@ -89,7 +100,7 @@ excel.ClearCell(sheetName, "A1");
println("[success] ClearCell");
// SetCellFormula
excel.SetCellFormula(sheetName, "A2", "=100*50");
excel.SetCellFormula(sheetName, "A2", "100*50");
println("[success] SetCellFormula");
// GetCellFormula
@@ -130,13 +141,13 @@ println("[success] RemoveRow");
// SetRowHeight
excel.SetRowHeight(sheetName, 1, 30);
excel.SetRowHeight(sheetName, 15, 30);
excel.SetRowHeight(sheetName, 5, 30);
println("[success] SetRowHeight");
// GetRowHeight
height := excel.GetRowHeight(sheetName, 2);
println("[success] GetRowHeight = {}", height);
height := excel.GetRowHeight(sheetName, 15);
height := excel.GetRowHeight(sheetName, 5);
println("[success] GetRowHeight = {}", height);
// SetColWidth
@@ -161,6 +172,9 @@ println("[success] GetSheetDefaultColWidth = {}", width);
excel.AddComment(sheetName, "A1", "csh", "heiheihei");
println("[success] AddComment");
[author, comment] := excel.GetComment(sheetName, 'A1');
println("[success] GetComment author = {}, comment = {}", author, comment);
// AddChart
data := array(("Name":"Small","Apple":2,"Orange":3,"Pear":3),
("Name":"Normal","Apple":5,"Orange":2,"Pear":4),
@@ -192,8 +206,6 @@ excel.NewSheet('Sheet1');
[err, errinfo] := excel.InsertTable("Sheet1","A5",data, true);
chart1 := excel.AddChart('Sheet1', 'A11:G30', chart);
println("[success] AddChart");
[err, errmsg] := excel.saveas("", "d:\\temp\\test.xlsx");
println("saveas : {}", err);
// GetCharts
[err, charts] := excel.GetCharts('Sheet1');
@@ -205,10 +217,6 @@ End;
[err, col, row] := excel.SplitCellName("AK47");
if not err then println("[success] {} = col : {}, row = {}", "SplitCellName", col, row);
// JoinCellName
[err, errmsg] := excel.JoinCellName("AK", 47);
PrintInfo("JoinCellName", err, errmsg);
// ColumnNameToNumber
[err, errmsg] := excel.ColumnNameToNumber("AK");
PrintInfo("ColumnNameToNumber", err, errmsg);
@@ -221,13 +229,19 @@ PrintInfo("ColumnNumberToName", err, errmsg);
[err, col, row] := excel.CellNameToCoordinates("A2");
if not err then println("[success] {} = col : {}, row = {}", "CellNameToCoordinates", col, row);
// CoordinatesToCellName
[err, cell] := excel.CoordinatesToCellName(1, 2, true);
println("[success] CoordinatesToCellName, cell = {}", cell);
[err, cell] := excel.CoordinatesToCellName(1, 2);
println("[success] CoordinatesToCellName, cell = {}", cell);
// RGBToHSL
[err, h, s, l] := excel.RGBToHSL(255, 15, 33);
if not err then println("[success] {} = {}, {}, {}", "RGBToHSL", h, s, l);
[h, s, l] := excel.RGBToHSL(255, 15, 33);
println("[success] {} = {}, {}, {}", "RGBToHSL", h, s, l);
// HSLToRGB
[err, r, g, b] := excel.HSLToRGB(h, s, l);
if not err then println("[success] {} = {}, {}, {}", "HSLToRGB", h, s, l);
[r, g, b] := excel.HSLToRGB(h, s, l);
println("[success] {} = {}, {}, {}", "HSLToRGB", r, g, b);
// NewStyle
style := TOfficeObj('TStyle');
@@ -244,6 +258,7 @@ style.Alignment.Horizontal := "center";
style.Alignment.Vertical := "justify";
style.Alignment.WrapText := True;
style.Alignment.ReadingOrder := 2;
style.Alignment.TextRotation := 45;
style.Border.Left.LineStyle := "thin";
style.Border.Left.Color := "A020F0";
style.Border.Right.LineStyle := "thin";
@@ -260,9 +275,11 @@ style.NumberFormat.FormatCode := "#,##0.000_ ";
//style.Fill.Pattern.PatternType := "solid";
//style.Fill.Pattern.ForegroundColor := "FF6699FF";
//style.Fill.Pattern.BackgroundColor := "FFFF0000";
style.Fill.Gradient.ThemeColor1 := 0;
style.Fill.Gradient.ThemeColor2 := 4;
style.Fill.Gradient.Shading := 1;
style.Fill.Gradient.Degree := 270;
style.Fill.Gradient.Stop1.Position := 0;
style.Fill.Gradient.Stop1.ThemeColor := 0;
style.Fill.Gradient.Stop2.Position := 1;
style.Fill.Gradient.Stop2.ThemeColor := 4;
style.Protection.Hide := 1;
style.Protection.Lock := 1;
@@ -275,8 +292,23 @@ println("[success] SetCellStyle");
styleid := excel.GetCellStyle(sheetName, "A1");
println("[success] GetCellStyle = {}", styleid);
styleid := excel.GetCellStyle(sheetName, "D4");
println("[success] GetCellStyle = {}", styleid);
style := excel.GetStyle(styleid);
println("font.Name = {}", style.Font.Name);
println("font.Italic = {}", style.Font.Italic);
println("border.left.Color = {}", style.border.left.Color);
println("border.Top.LineStyle = {}", style.border.Top.LineStyle);
println("border.DiagonalDown = {}", style.border.DiagonalDown);
println("numberFormat.FormatCode = {}", style.NumberFormat.FormatCode);
println("alignment.vertical = {}", style.Alignment.Vertical);
println("alignment.TextRotation = {}", style.Alignment.TextRotation);
println("protection.Hide = {}", style.Protection.Hide);
println("protection.Lock = {}", style.Protection.Lock);
//println("fill.pattern.PatternType = {}", style.Fill.Pattern.PatternType);
//println("fill.pattern.ForegroundColor = {}", style.Fill.Pattern.ForegroundColor);
println("style.Fill.Gradient.Degree = {}", style.Fill.Gradient.Degree);
println("style.Fill.Gradient.Stop1.ThemeColor = {}", style.Fill.Gradient.Stop1.ThemeColor);
println("style.Fill.Gradient.Stop2.Position = {}", style.Fill.Gradient.Stop2.Position);
// SetSheetHeaderFooter
headerFooter := TOfficeObj("THeaderFooter");
@@ -291,7 +323,6 @@ headerFooter.EvenFooter := "&L456&R789";
headerFooter.FirstHeader := "&L++";
headerFooter.FirstFooter := "&R--";
excel.SetSheetHeaderFooter(sheetName, headerFooter);
println("[success] SetSheetHeaderFooter");
// SetSheetVisible
excel.SetSheetVisible(sheetName, True);
@@ -333,8 +364,8 @@ println("[success] SetPageMargins");
// GetPageMargins
margins := excel.GetPageMargins(sheetName2);
println("[success] GetPageMargins top = {}, bottom = {}, left = {}, right = {}, header = {}, footer = {}",
margins.Value('Top'), margins.Value('Bottom'), margins.Value('Left'), margins.Value('Right'),
margins.Value('Header'), margins.Value('Footer'));
margins.Top, margins.Bottom, margins.Left, margins.Right,
margins.Header, margins.Footer);
// MergeCell
excel.SetCellStyle(sheetName2, "A4", "A4", styleid1);
@@ -346,14 +377,35 @@ println("[success] MergeCell");
excel.UnMergeCell(sheetName2, "A4", "C4");
println("[success] UnMergeCell");
// TODO 未完全开发完毕
// SetSheetViewOptions
sheetView := TOfficeObj('TSheetView');
sheetView.ShowGridLines := false;
sheetView.ShowRowColHeaders := false;
sheetView.View := 'pageBreakPreview';
sheetView.ZoomScale := 60;
excel.SetSheetViewOptions(sheetName, 0, sheetView);
println("[success] SetSheetViewOptions");
// GetSheetViewOptions
view := excel.GetSheetViewOptions(sheetName, 0);
println("[success] GetSheetViewOptions ShowGridLines = {}, ShowRowColHeaders = {}, View = {}, ZoomScale = {}", view.ShowGridLines, view.ShowRowColHeaders, view.ZoomScale, view.View);
// SetPane
Pane := TOfficeObj('TPane');
Pane.XSplit := 6;
Pane.YSplit := 14;
Pane.ActivePane := 'bottomRight';
Pane.TopLeftCell := excel.CoordinatesToCellName(Pane.XSplit + 1, Pane.YSplit + 1)[1];
Pane.State := 'frozen';
excel.SetPane(sheetName, 0, Pane);
println("[success] SetPane");
// SetPageLayout
pageLayout := TOfficeObj('TPageLayout');
pageLayout.FitToWidth := 10;
pageLayout.FitToHeight := 10;
pageLayout.UseFirstPageNumber := true;
pageLayout.FirstPageNumber := 5;
pageLayout.Orientation := "portrait";
pageLayout.BlackAndWhite := true;
@@ -378,11 +430,11 @@ println("[success] GetDefaultSheet = {}", sheet);
// SetCellHyperLink
link := TOfficeObj('THyperLink');
link.LinkType := "Location";
link.LinkType := "location";
link.LinkUrl := sheetName $ "!A1";
excel.SetCellHyperLink(sheetName2, 'A1', link);
link := TOfficeObj('THyperLink');
link.LinkType := "External";
link.LinkType := "external";
link.LinkUrl := "https://www.baidu.com";
link.Tooltip := "超链接悬浮提示";
excel.SetCellValue(sheetName2, 'A2', '超链接');
@@ -391,12 +443,13 @@ println("[success] SetCellHyperLink");
// GetCellHyperLink
hyperlink := excel.GetCellHyperLink(sheetName2, 'A2');
println("[success] GetCellHyperLink LinkType = {}, LinkUrl = {}, Tooltip = {}", hyperlink.Value('LinkType'), hyperlink.Value('LinkUrl'), hyperlink.Value('Tooltip'));
println("[success] GetCellHyperLink LinkType = {}, LinkUrl = {}, Tooltip = {}", hyperlink.LinkType, hyperlink.LinkUrl, hyperlink.Tooltip);
// SetSheetBackground
ret := readfile(rwBinary(), "", "C:\\Users\\csh05\\Pictures\\Saved Pictures\\1.jpg", 0, 1024000, data);
imagepath := "C:\\Users\\csh05\\Pictures\\1png.png";
ret := readfile(rwBinary(), "", imagepath, 0, 1024000, data);
if not ret then return echo "readfile error!";
picture := TOfficeObj('TPicture');
Image := TOfficeObj('TPicture');
picture.Image := data;
excel.SetSheetBackground(sheetName, picture);
println("[success] SetSheetBackground");
@@ -443,6 +496,8 @@ shape_format.EndColOff := 7653;
shape_format.BegRowOff := 55577;
shape_format.EndRowOff := 66675;
shape_type := "roundRect";
excel.AddShape(sheetName2, "A15", "C17", shape_type, shape_format);
println("[success] AddShape");
// SetCoreProps
core := TOfficeObj('TCoreProperty');
@@ -450,11 +505,10 @@ core.Title := "标题";
core.Subject := "主题";
core.Creator := "作者";
excel.SetCoreProps(core);
println("[success] SetCoreProps");
// GetCoreProps
core := excel.GetCoreProps();
println("[success] GetCoreProps Title = {}, subject = {}, Creator = {}", core.Value("Title"), core.Value("Subject"), core.Value("Creator"));
println("[success] GetCoreProps Title = {}, subject = {}, Creator = {}", core.Title, core.Subject, core.Creator);
// SetAppProps
appProps := TOfficeObj('TAppProperty');
@@ -464,7 +518,7 @@ appProps.ScaleCrop := "true";
appProps.Company := "TS";
appProps.LinksUpToDate := "true";
appProps.HyperlinksChanged := "true";
appProps.AppVersion := "1.000";
appProps.Version := "1.000";
appProps.Manager := "这是主管";
//appProps.HyperlinkBase := "这是超链接基础";
excel.SetAppProps(appProps);
@@ -472,32 +526,87 @@ println("[success] SetAppProps");
// GetAppProps
app_props := excel.GetAppProps();
println("[success] GetAppProps Manager = {}, Company = {}, Application = {}", app_props.Value('Manager'), app_props.Value('Company'), app_props.Value('Application'));
println("[success] GetAppProps Manager = {}, Company = {}, Application = {}", app_props.Manager, app_props.Company, app_props.Application);
// CopySheet
excel.CopySheet(sheetName2, 'copy');
println("[success] CopySheet");
// ProtectSheet
protect := TOfficeObj('TProtect');
protect.EditObjects := true;
protect.EditScenarios := true;
protect.FormatCells := true;
protect.FormatColumns := true;
protect.FormatRows := true;
protect.InsertColumns := true;
protect.InsertRows := true;
protect.InsertHyperlinks := true;
protect.DeleteColumns := true;
protect.DeleteRows := true;
protect.Sort := true;
protect.AutoFilter := true;
protect.PivotTables := true;
protect.SelectLockedCells := true;
protect.SelectUnLockedCells := true;
excel.ProtectSheet(sheetName2, protect);
println("[success] ProtectSheet");
// SetDefaultFont
font := tofficeobj('tfont');
font.Name := '黑体';
font.Size := 13;
font.ThemeColor := 1;
excel.SetDefaultFont(font);
println("[success] SetDefaultFont");
tfont := excel.GetDefaultFont();
println("[success] GetDefaultFont , name = {}, size = {}, themecolor = {}", tfont.Name, tfont.Size, tfont.ThemeColor);
calcpr := TOfficeObj('TCalcPr');
calcpr.CalcMode := "";
calcpr.RefMode := "R1C1";
calcpr.Iterate := 1;
calcpr.IterateCount := 300;
calcpr.IterateDelta := "3E-3";
calcpr.CalcOnSave := true;
calcpr.ConCurrentCalc := true;
calcpr.ConCurrentManualCount := 4;
calcpr.FullPrecision := 0;
excel.SetCalcOptions(calcpr);
println("[success] SetCalcOptions");
calc := excel.GetCalcOptions();
println("[success] GetCalcOptions, CalcMode = {}, RefMode = {}, Iterate = {},
IterateCount = {}, IterateDelta = {}, CalcOnSave = {}, conCurrentCalc = {},
conCurrentManualCount = {}, FullPrecision = {}", calc.CalcMode, calc.RefMode, calc.Iterate,
calc.IterateCount, calc.IterateDelta, calc.CalcOnSave, calc.conCurrentCalc,
calc.conCurrentManualCount, calc.FullPrecision);
excel.SetRowOutlineLevel(sheetName2, 1, 1);
excel.SetRowOutlineLevel(sheetName2, 2, 1);
println("[success] SetRowOutlineLevel");
level1 := excel.GetRowOutlineLevel(sheetName2, 1);
level2 := excel.GetRowOutlineLevel(sheetName2, 3);
println("[success] GetRowOutlineLevel, level1 = {}, level2 = {}", level1, level2);
excel.SetColOutlineLevel(sheetName2, 'A', 1);
excel.SetColOutlineLevel(sheetName2, 'B', 2);
excel.SetColOutlineLevel(sheetName2, 'C', 1);
println("[success] SetColOutlineLevel");
level1 := excel.GetColOutlineLevel(sheetName2, 'A');
level2 := excel.GetColOutlineLevel(sheetName2, 'B');
println("[success] GetColOutlineLevel, level1 = {}, level2 = {}", level1, level2);
[err, errmsg] := excel.saveas("", "d:\\temp\\test.xlsx");
println("saveas : {}", err);
Function _test_background(excel);
Begin
f := 'D:\\temp\\a.xlsx';
[err, msg] := excel.OpenFile('', f);
if err then return
echo "Open Fail:", msg, '\n';
ret := readfile(rwBinary(), "", "C:\\Users\\csh05\\Pictures\\Saved Pictures\\1.png", 0, 102400, data);
if ret then pictrue := new TSImage(data);
else return echo "readfile error!";
excel.SetSheetBackground('Sheet1', pictrue);
[err, errmsg] := excel.SaveAs('', 'd:\\temp\\e.xlsx');
println('SaveAs->{}',err);
End
// ============================================================
Function PrintInfo(msg, err, errinfo);
Begin
if err then debugreturn println("{} : errorno = {}, errorinfo = {}!", msg, err, errinfo);
println("[success] {} = {}", msg, errinfo);
End
+117 -64
View File
@@ -1,3 +1,4 @@
///Version:V1.03
///Create by Tinysoft.
///自动生成 TSDocxFile 帮助文件
mtic;
@@ -6,7 +7,7 @@ docx := new TSDocxFile();
[err, errmsg] := docx.NewFile();
if err then
return println( 'Create NewFile Fail:{}.', errmsg);
//多级项目编号
sysparams['numId'] := docx.NumberingObject().NumberId('multilevel', 'decimal');
@@ -55,6 +56,12 @@ _13_TNumbering(docx);
///TDocxChart
_14_TDocxChart(docx);
///TOfficeApi
_15_TOfficeApi(docx);
///ExecInnerTSL
_16_Template(docx);
///附注
_Annotation(docx);
@@ -62,13 +69,15 @@ _Annotation(docx);
_Faq(docx);
///目录
docx.AddTableContent(paragraphTitle, 1, 3);
content := docx.AddTableContent(paragraphTitle, 1, 3);
docx.AddPageBreak(content.node_);
v := docx.SaveAs('', 'TSDocFile-Help.docx');
v := docx.SaveAs('', TOfficeApi().CurCodePageToGBK('DocxFile使用帮助.docx'));
println('Test Over!\n Save {}: {},time={}秒', file, v, mtoc);
//info := GetProfilerInfo(true);
//exportfile(ftstream(),'','f:\\temp\\ProfilerInfo.stm',info);
//exportfile(ftstream(),'','\\temp\\ProfilerInfo.stm',info);
///////////////////////////////////////////////////////////////////////////////////////////////
///子函数
@@ -77,7 +86,7 @@ Function _0_AddTitle(docx);
Begin
_PrintMsg('AddTitle');
p := _AddTitle(docx, '天软DOCX文档操作接口帮助文档', 0);//添加文档标题
p.Font.Size := 48;
p.Font.Size := 24;
p.Apply();
for i:=0 to 16 do
docx.AddLineBreak(-1);//换行符
@@ -119,13 +128,13 @@ Begin
//添加段落
preface := TOfficeObj('TParagraph');
preface.Run.T := '本文档由word_help.tsl脚本,调用本文档中描述的接口自动生成!';
preface.Run.SetText( '本文档由word_help.tsl脚本,调用本文档中描述的接口自动生成!' );
preface.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
preface.Format.LeftIndent := 440;//段落左边距
preface.Font.Name := '宋体';
preface.Font.Color := 'FF0000';
preface.Font.Bold := true;
preface.Font.Size := 32;
preface.Font.Size := 16;
p1 := docx.AddParagraph(preface, -1, nil);
println(' >>OK\n');
@@ -153,11 +162,10 @@ Begin
_AddTitle(docx, 'TParagraph对象(段落)', 1); //第三段标题
///TParagraph属性
_AddTitle(docx, 'TParagraph属性', 2); //第二级标题
formatObj := new TOfficeObj('TwpPr');
_LoadObjectAttributes(formatObj, attrs, '段落属性', 'Format');
fontObj := new TOfficeObj('TwrPr');
_LoadObjectAttributes(fontObj, attrs, '字体属性', 'Font');
_AddTitle(docx, 'TParagraph属性(段落属性TwpPr对象、字体属性TwrPr对象)', 2); //第二级标题
attrs := array(('类别':'缺省w:r元素', '接口':'Run', '说明':'TRun对象'),
('类别':'段落属性', '接口':'Format', '说明':'TwpPr对象'),
('类别':'字体属性', '接口':'Font', '说明':'TwrPr对象'));
_AddClassHelpTable(docx, attrs);//添加表格:TParagraph属性
///TParagraph方法
@@ -166,10 +174,16 @@ Begin
conf union= _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TOfficeObj.tsf', 'DocObject');
_AddFunctionHelpInfo(docx, '' $ paragraph $ '.2.', conf, 3);
///TRun方法
_AddTitle(docx, 'TRun方法(段落中w:r元素)', 2);
conf := _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TOfficeObj.tsf', 'TRun');
conf union= _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TOfficeObj.tsf', 'DocObject');
_AddFunctionHelpInfo(docx, '' $ paragraph $ '.3.', conf, 3);
///TTabStops对象
_AddTitle(docx, 'TTabStops对象', 2);
conf := _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TOfficeObj.tsf', 'TTabStops');
_AddFunctionHelpInfo(docx, '' $ paragraph $ '.3.', conf, 3);
_AddFunctionHelpInfo(docx, '' $ paragraph $ '.4.', conf, 3);
///TabStop属性
_AddTitle(docx, 'TTabStop属性', 2); //第二级标题
@@ -191,8 +205,9 @@ Begin
///TTable对象
_AddTitle(docx, 'TTable对象属性', 2); //第二级标题
tbl := new TOfficeObj('TTable');
_LoadObjectAttributes(tbl.Format, attrs, '表格属性', 'Format');
_LoadObjectAttributes(tbl.FormatEx, attrs, '表格扩展属性', 'FormatEx');
attrs := array(('类别':'单元格属性', '接口':'Paragraph', '说明':'TParagrap对象:设置单元格段落格式、字体格式'));
_LoadObjectAttributes(tbl.Format, attrs, '表格样式', 'Format');
_LoadObjectAttributes(tbl.FormatEx, attrs, '浮动表设置', 'FormatEx');
_AddClassHelpTable(docx, attrs);//添加表格:TTable属性
///TTable方法
@@ -228,11 +243,11 @@ Begin
_AddTitle(docx, 'TPicture对象属性', 2);
attrs := array(('类别':'图片信息', '接口':'Image', '说明':'二进制内容'),
('类别':'图片信息', '接口':'Descr', '说明':'图像描述'),
('类别':'图片信息', '接口':'Width', '说明':'图像宽度'),
('类别':'图片信息', '接口':'Height', '说明':'图像高度')
('类别':'图片信息', '接口':'Width', '说明':'图像宽度cm'),
('类别':'图片信息', '接口':'Height', '说明':'图像高度cm')
);
pPr := new TOfficeObj('TpicsPpr');
_LoadObjectAttributes(pPr, attrs, '图像属性', 'Format');
//pPr := new TOfficeObj('TpicsPpr');
//_LoadObjectAttributes(pPr, attrs, '图像属性', 'Format');
_AddClassHelpTable(docx, attrs);//添加表格:TPicture对象
///TPicture方法
@@ -244,8 +259,8 @@ Begin
_AddTitle(docx, '插入图像案例', 2);
picture := TOfficeObj('TPicture');
picture.Descr := '插入图像案例';
readfile(rwbinary(), '', docx.GetPath() + '\\funcext\\TSOffice\\template\\tinysoft.gif', 0, 1024*1024, data);
picture.Image := data;
picture.Image := TOfficeTemplate('tinysoft.gif',true);
if ifnil(picture.Image) then return;
p := docx.AddPicture(picture, -1);
//添加图像外边框
p.Format.Ln.SolidFill.SchemeClr.Val := 'accent1';
@@ -287,10 +302,10 @@ Begin
p1 := TOfficeObj('TParagraph');
p1.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
p1.Format.LeftIndent := 440;//段落左边距
p1.Run.AddText('本文档由天软科技制作。');
p1.Run.SetText('本文档由天软科技制作。');
p1.Run.rPr.Name := '宋体';
p1.Run.rPr.Bold := true;
p1.Run.rPr.Size := 32;
p1.Run.rPr.Size := 16;
p1.Run.rPr.Color := 'FF0000';
p2 := docx.AddParagraph(p1, -1, nil);
//插入批注
@@ -375,10 +390,10 @@ Begin
p1 := TOfficeObj('TParagraph');
p1.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
p1.Format.LeftIndent := 440;//段落左边距
p1.Run.T := '插入案例。';
p1.Run.SetText( '插入案例。' );
p1.Run.rPr.Name := '宋体';
p1.Run.rPr.Bold := true;
p1.Run.rPr.Size := 32;
p1.Run.rPr.Size := 16;
p1.Run.rPr.Color := 'FF0000';
pAddRevision := docx.AddParagraph(p1, -1, nil);
//插入修订
@@ -394,10 +409,10 @@ Begin
p1 := TOfficeObj('TParagraph');
p1.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
p1.Format.LeftIndent := 440;//段落左边距
p1.Run.T := '删除修订案例。';
p1.Run.SetText( '删除修订案例。' );
p1.Run.rPr.Name := '宋体';
p1.Run.rPr.Bold := true;
p1.Run.rPr.Size := 32;
p1.Run.rPr.Size := 16;
p1.Run.rPr.Color := 'FF0000';
pDelRevision := docx.AddParagraph(p1, -1, nil);
//删除修订
@@ -481,30 +496,30 @@ Begin
///添加页眉、页脚案例
_AddTitle(docx, '添加页眉、页脚案例', 2);
help := TOfficeObj('TParagraph');
help.Run.T := '参考word_help.tsl脚本(TDocxFile::Sections, TDocSection::AddHeader, TDocSection::AddFooter)!';
help.Run.SetText( '参考word_help.tsl脚本(TDocxFile::Sections, TDocSection::AddHeader, TDocSection::AddFooter)!' );
help.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
help.Format.LeftIndent := 440;//段落左边距
help.Font.Name := '宋体';
help.Font.Color := 'FF0000';
help.Font.Bold := true;
help.Font.Size := 30;
help.Font.Size := 15;
p1 := docx.AddParagraph(help, -1, nil);
section := docx.Sections(-1);//获取缺省章节
footer := section.AddFooter('');//添加缺省页脚
//页脚内容
p := TOfficeObj('TParagraph');
p.Run.T := '电 话:0755-83937039';
p.Run.SetText( '电 话:0755-83937039' );
p.AddRun('网 址:http://www.tinysoft.com.cn', true);
p.AddRun('公司地址:深圳市福田区莲花街道梅岭社区新闻路59号深茂商业中心19F', true);
p.Format.Bdr.Top.val := 'single';//页脚横线
p.Format.SpaceAfter := 0;
p.Font.Name := '宋体';
p.Font.Color := 'FF0000';
p.Font.Size := 16;
p.Font.Size := 8;
p2 := footer.AddParagraph(p, -1, nil);
p.Font.Size := 18;
pgno := footer.AddPageNumber('第 {0} 页,共 {1} 页', p.Font); //添加页码
p.Font.Size := 8;
pgno := footer.AddPageNumber('第 {-3} 页,共 {1} 页', p.Font); //添加页码
pgno.Format.Alignment := 'center'; //据中对齐
pgno.Format.SpaceAfter := 0;
pgno.Apply();
@@ -512,12 +527,12 @@ Begin
//添加页眉
header := section.AddHeader('');//添加缺省页眉
p := TOfficeObj('TParagraph');
p.Run.T := '深圳市天软科技开发有限公司';
p.Run.SetText( '深圳市天软科技开发有限公司' );
p.Format.Alignment := 'right'; //据右对齐
//p.Format.Bdr.Bottom.val := 'single';//页眉横线
p.Font.Name := '宋体';
p.Font.Color := 'FF0000';
p.Font.Size := 16;
p.Font.Size := 8;
p1 := header.AddParagraph(p, -1, nil);
println(' >>OK\n');
@@ -565,24 +580,24 @@ Begin
p1 := TOfficeObj('TParagraph');
p1.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
p1.Format.LeftIndent := 440;//段落左边距
p1.Run.T := '深圳市天软公司';
p1.Run.SetText( '深圳市天软公司' );
p1.Run.rPr.Name := '宋体';
pTest := docx.AddParagraph(p1, -1, nil);
//修改部分文字字体
range := pTest.Range(3,2);
range.Font.Size := 32;
range.Font.Size := 16;
range.Font.Color := 'FF0000';
range.Font.Bold := true;
range.Apply();
//添加文字1
range1 := pTest.AddText(5, '科技开发有限');
range1.Font.Size := 28;
range1.Font.Size := 14;
range1.Font.Color := '00FF00';
range1.Font.Bold := true;
range1.Apply();
//添加文字2
range2 := pTest.AddText(0, '广东省');
range2.Font.Size := 28;
range2.Font.Size := 14;
range2.Font.Color := '0000FF';
range2.Font.Bold := true;
range2.Apply();
@@ -590,7 +605,7 @@ Begin
//r.Text := 'Tinysoft';
r := pTest.AddText(-1, ':www.tinysoft.com.cn');//段落后追加
r.Font.Size := 20;
r.Font.Size := 10;
r.Font.Color := '0000FF';
r.Font.Bold := true;
r.Apply();
@@ -610,6 +625,12 @@ Begin
conf := _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\document\\TDocxStyles.tsf', 'TDocxStyles');
_AddFunctionHelpInfo(docx, '' $ paragraph $ '.1.', conf, 3);
_AddTitle(docx, '样式(TDocxStyle', 2); //第二级标题
attrs := array();
formatObj := new TOfficeObj('TDocxStyle');
_LoadObjectAttributes(formatObj, attrs, '样式', '');
_AddClassHelpTable(docx, attrs);
println(' >>OK\n');
End;
@@ -637,11 +658,11 @@ Begin
p := TOfficeObj('TParagraph');
p.Format.numPr.Level := 0;//项目编号
p.Format.numPr.numId := docx.NumberingObject().NumberId('bullet', i); //项目编号
p.Font.Size := 28;
p.Font.Size := 14;
p.Font.Color := 'FF0000';
p.Font.Bold := true;
p.Format.LeftIndent := 700;//段落左边距
p.Run.T := 'NumberId("bullet", ' $ i $ ')';
p.Run.SetText( 'NumberId("bullet", ' $ i $ ')' );
docx.AddParagraph(p, -1, nil);
End;
@@ -782,6 +803,40 @@ Begin
println(' >>OK\n');
End;
///TOfficeApi
Function _15_TOfficeApi(docx);
Begin
paragraph := sysparams['Test'];
_PrintMsg('TOfficeApi接口');
_AddTitle(docx, 'TOfficeApi', 1);
_AddTitle(docx, 'TOfficeApi接口', 2);
conf := _LoadClassInfo(docx.GetPath() + '\\funcext\\TSOffice\\TSUtils\\TOfficeApi.tsf', 'TOffice');
_AddFunctionHelpInfo(docx, '' $ paragraph $ '.1.', conf, 3);
println(' >>OK\n');
End;
Function _16_Template(docx);
Begin
paragraph := sysparams['Test'];
_PrintMsg('报告模板(ExecInnerTSL');
_AddTitle(docx, '报告模板(docx.ExecInnerTSL()', 1);
//添加段落
p := TOfficeObj('TParagraph');
p.Run.SetText( '系统提供docx.ExecInnerTSL()接口,用户可以制作自定义的报告模板,参考文档:' + 'template.docx。');
p.Format.FirstLineIndent := 220; //指定段落第一行缩进的相对差异的值
p.Format.LeftIndent := 440;//段落左边距
p.Font.Name := '宋体';
p.Font.Color := 'FF0000';
p.Font.Bold := true;
p.Font.Size := 15;
p1 := docx.AddParagraph(p, -1, nil);
println(' >>OK\n');
End;
Function _AddTitle(docx, subject, level);
Begin
leftIndent := array((0,0), (425,425), (453,850), (708,1508));
@@ -814,7 +869,7 @@ Begin
if not ifString(conf[i]['comment']) or conf[i]['comment'] = '' then continue;
arr := str2array(conf[i]['funcname'], '(');
k := lowercase(arr[0]);
if hash[k]=1 and ( not k in array('create')) then continue;
if hash[k]=1 and not (k in array('create')) then continue;
hash[k] := 1;
subject := head $ ind++ $ ' ' $ conf[i]['funcname'];
_AddTitle(docx, conf[i]['funcname'], level);
@@ -825,7 +880,7 @@ Begin
pFun.Format.LeftIndent := 1760;//段落左边距
pFun.Font.Name := '宋体';
println(' Subject:{}', subject);
pFun.Run.T := 'Function ' + conf[i]['funcname'];
pFun.Run.SetText( 'Function ' + conf[i]['funcname'] );
p1 := docx.AddParagraph(pFun, -1, nil);//函数方法
//设置首行字体颜色、黑体
firstRun := p1.GetRun(0);
@@ -836,7 +891,7 @@ Begin
//添加函数帮助信息段落
arr := str2array(conf[i]['comment'], '\n');
for j:=0 to length(arr)-1 do Begin
pFun.Run.T := '///' + arr[j];
pFun.Run.SetText('///' + arr[j]);
p2 := docx.AddParagraph(pFun, -1, nil);
End;
@@ -887,10 +942,10 @@ Function _AddClassHelpTable(docx, data);
Begin
//设置边框属性
tbl := docx.CreateTable(data, true, true);
tbl.Format.Borders.Top.Size := 24;
tbl.Format.Borders.Left.Size := 24;
tbl.Format.Borders.Bottom.Size := 24;
tbl.Format.Borders.Right.Size := 24;
tbl.Format.Borders.Top.Size := 12;
tbl.Format.Borders.Left.Size := 12;
tbl.Format.Borders.Bottom.Size := 12;
tbl.Format.Borders.Right.Size := 12;
tbl.Format.Borders.Top.Val := 'thinThickThinMediumGap';
tbl.Format.Borders.Left.Val := 'thinThickThinMediumGap';
tbl.Format.Borders.Bottom.Val := 'thinThickThinMediumGap';
@@ -911,9 +966,9 @@ Begin
tbl.Format.Borders.Right.themeTint := '99';
//设置列宽
tbl.ColumnWidth(1, 800);
tbl.ColumnWidth(2, 2000);
tbl.ColumnWidth(3, 2000);
tbl.ColumnWidth(1, 600);
tbl.ColumnWidth(2, 2100);
tbl.ColumnWidth(3, 2100);
tbl.ColumnWidth(4, 6000);
//设置表格左边距
@@ -921,7 +976,7 @@ Begin
tbl.format.IndentType := 'dxa';
//tbl.TblPr.Style := 1;
tbl := docx.InsertTable(tbl, -1);
//设置表头底纹
rows := tbl.Rows();
cols := tbl.Cols();
@@ -941,7 +996,7 @@ Begin
cell.Format.Shading.Fill := 'DBEEF3';
cell.Apply();
End;
//合并单元格
fields := select distinct [1] as 'type' from data where thisrowindex > 0 end;
for i:=0 to length(fields)-1 do begin
@@ -949,8 +1004,8 @@ Begin
r := select thisrowindex+1 as 'row' from data where [1] = key end;
begRow := r[0]['row'];
endRow := r[length(r)-1]['row'];
[err, begCell] := xlsx_call("CoordinatesToCellName", 2, begRow);
[err, endCell] := xlsx_call("CoordinatesToCellName", 2, endRow);
[err, begCell] := CoordinatesToCellName(2, begRow);
[err, endCell] := CoordinatesToCellName(2, endRow);
tbl.Merge(begCell, endCell, true);
//设置合并单元格据中对齐
@@ -1044,7 +1099,7 @@ Begin
_AddTitle(docx, '附注一:内置对象', 1); //附注标题
ind := 1;
hash := array('TwpPr':1, 'TwrPr':1);
hash := array();
while i < length(r) do Begin
attrs := array();
_LoadObjectAttributes(r[i]['obj'], attrs, '属性', '');
@@ -1072,10 +1127,8 @@ Begin
_PrintMsg('FAQ');
_AddTitle(docx, '附注二:FAQ', 1); //附注FAQ标题
[err,fh] := io_open( _ReplaceFileName(docx.GetPath() + '\\funcext\\TSOffice\\template\\faq.txt') );
if err then return t;
[err, data] := io_read(fh);
io_close(fh);
data := TOfficeTemplate('faq.txt');
if ifnil(data) then return;
lines := str2array(string(data), '\n');
numId := docx.NumberingObject().NumberId('bullet', 1); //项目编号
for i:=0 to length(lines)-1 do Begin
@@ -1088,12 +1141,12 @@ Begin
str := str[2:];
println(' FAQ: {}', str);
End;
p.Run.T := str;
p.Run.SetText( str );
End;
if title then Begin
p.Format.numPr.Level := 0;//项目编号
p.Format.numPr.numId := numId;
p.Font.Size := 28;
p.Font.Size := 14;
p.Font.Color := 'FF0000';
p.Font.Bold := true;
p.Format.LeftIndent := 500;//段落左边距
@@ -1113,4 +1166,4 @@ Begin
if f[1] = '/' then
f := ReplaceStr(f, '\\', '/');
return f;
End;
End;
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+4 -3
View File
@@ -8,16 +8,17 @@ TSOffice 项目:纯 TSL 代码实现 excel、word 文件读写
对应文件夹的dll文件按如下要求
- `fmt_pubkrnl_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
- `office_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
- `tsxlsx.dll` 放入 tsl 安装根目录
可选:
- `fmt_pubkrnl_plugin` 放入 tsl 安装根目录下 Plugin 文件夹,若需要执行Demo文件夹下的[ExcelHelp.tsl](./Demo/ExcelHelp.tsl)和[WordHelp.tsl](./Demo/WordHelp.tsl),需要部署改动态库
### Linux
根据架构选择aarch64或x86版本将对应文件夹内容进行部署
- `liboffice_plugin` 放入 tsl 安装根目录下 Plugin 文件夹
- `libTsXlsx` 放入 tsl 安装根目录
## 帮助文档
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+251 -74
View File
@@ -1,3 +1,5 @@
// Version 1.4.4
Type TSDocxFile = Class
///Version: V1.0 2022-09-20
///适用于 Microsoft Word docx格式文件
@@ -16,29 +18,41 @@ Type TSDocxFile = Class
Function Create(alias, fname); overload;
Begin
init();
OpenFile(alias, fname);
OpenFile(alias, fname, nil);
End;
///构造函数,打开已经存在的docx文件
///alias: string,文件目录别名
///fname: string,文件名
///passwd: string,密码
Function Create(alias, fname, passwd); overload;
Begin
init();
OpenFile(alias, fname, passwd);
End;
Function Destory();
Begin
End;
Function init();
Begin
DocPrId_ := -1;
zipfile_ := new ZipFile();
xml_ := new xlsxXml();
End;
///打开docx文件
///alias: string,文件目录别名
///fname: string,文件名
///[passwd]: string,密码
///返回:[err, errmsg]
Function OpenFile(alias, fname);
Function OpenFile(alias, fname, passwd);
Begin
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
[err, errmsg] := zipfile_.Open(alias, fname);
if zipfile_.FilesCount() > 0 then zipfile_ := new ZipFile();
[err, errmsg] := zipfile_.Open(alias, fname, passwd);
if err=0 then Begin
document_ := new docxDocument(zipfile_, xml_);
document_ := new docxDocument(zipfile_);
End;
return array(err, errmsg);
End;
@@ -47,12 +61,18 @@ Type TSDocxFile = Class
///返回:[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);
def := TOfficeTemplate('default.docx', true);
[err, errmsg] := zipfile_.LoadFromMem(def);
if err=0 then Begin
document_ := new docxDocument(zipfile_);
End;
return array(err, errmsg);
End;
///设置密码
Function SetPassword(passwd)
Begin
zipfile_.Password := passwd;
End;
///保存文件
@@ -71,6 +91,25 @@ Type TSDocxFile = Class
return zipfile_.Save(alias, fname);
End;
///另存为二进制流数据
///返回: [err, fileContent] fileContent 文件内容,为Binary数据类型
Function SaveToMem();
Begin
return zipfile_.Save2Mem();
End;
///打开二进制内容
///data: 二进制数据
///返回: [err, errmsg]
Function LoadFromMem(data);
Begin
[err, errmsg] := zipfile_.LoadFromMem(data);
if err=0 then Begin
document_ := new docxDocument(zipfile_);
End;
return array(err, errmsg);
End;
///真实文件名
///返回:string
Function FileName();
@@ -92,7 +131,7 @@ Type TSDocxFile = Class
///返回TParagraph对象
Function AddParagraph(paragraph, posOpt, styleId);
Begin
return document_.Body().AddParagraph(paragraph, posOpt, styleId);
return document_.Body().AddParagraph(paragraph, getPosNode(posOpt), styleId);
End;
///添加标题
@@ -102,11 +141,12 @@ Type TSDocxFile = Class
///返回TParagraph对象
Function AddHeading(title, posOpt, level);
Begin
if ifstring(level) then return document_.Body().AddHeading(title, getPosNode(posOpt), level);
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);
style := StyleObject().AddDefaultStyle(styleName);
return document_.Body().AddHeading(title, getPosNode(posOpt), ifObj(style) ? style.StyleId : nil);
End;
///插入分页符
@@ -114,7 +154,7 @@ Type TSDocxFile = Class
///返回TParagraph对象
Function AddPageBreak(posOpt);
Begin
return document_.Body().AddBreak(posOpt, 'page');
return document_.Body().AddBreak(getPosNode(posOpt), 'page');
End;
///插入换行符
@@ -122,7 +162,7 @@ Type TSDocxFile = Class
///返回TParagraph对象
Function AddLineBreak(posOpt);
Begin
return document_.Body().AddBreak(posOpt, '');
return document_.Body().AddBreak(getPosNode(posOpt), '');
End;
///插入分栏符
@@ -130,15 +170,15 @@ Type TSDocxFile = Class
///返回TParagraph对象
Function AddColumnBreak(posOpt);
Begin
return document_.Body().AddBreak(posOpt, 'column');
return document_.Body().AddBreak(getPosNode(posOpt), 'column');
End;
///删除指定段落
///删除指定段落(表格、图片、图表、文本框等)
///posOpt: 段落位置,0 DOCX文件开头;-1 文件尾;N 第N段;posOpt段落
///返回:true
Function DelParagraph(posOpt);
Begin
return document_.Body().DelParagraph(posOpt);
return document_.Body().DelParagraph(getPosNode(posOpt));
End;
///word文档所有内容的文本串
@@ -148,14 +188,13 @@ Type TSDocxFile = Class
return document_.Body().Text();
End;
///word文档所有内容的文本串数组,包含段落信息
///返回:array(("pNode":nodeObj, "pIndex":p, "rNode":nodeObj, "rIndex":r))
//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();
@@ -169,7 +208,7 @@ Type TSDocxFile = Class
End;
///word文档指定表格
///n: int 第n个表格
///n: int 从0开始,第n个表格
///返回:TTable对象
Function GetTable(n);
Begin
@@ -183,7 +222,9 @@ Type TSDocxFile = Class
///返回: TTable对象
Function CreateTable(data, IncludeHeader, IncludeIndex);
Begin
return document_.Body().CreateTable(data, IncludeHeader, IncludeIndex);
tbl := TOfficeObj('TTable');
tbl.SetData(self, data, IncludeHeader, IncludeIndex);
return tbl;
End;
///插入数据表
@@ -192,7 +233,7 @@ Type TSDocxFile = Class
///返回: TTable对象
Function InsertTable(tbl, posOpt);
Begin
return document_.Body().InsertTable(tbl, posOpt);
return document_.Body().InsertTable(tbl, getPosNode(posOpt));
End;
///返回CoreProperties对象
@@ -224,7 +265,7 @@ Type TSDocxFile = Class
///返回:TDocSection对象
Function AddSection(session, posOpt);overload;
Begin
return document_.Body().AddSection(session, posOpt);
return document_.Body().AddSection(session, getPosNode(posOpt));
End;
///插入图片
@@ -233,7 +274,8 @@ Type TSDocxFile = Class
///返回:TPicture对象
Function AddPicture(picture, posOpt);
Begin
return document_.Body().AddPicture(picture, posOpt);
picture.Run.Drawing.WInline.ID := GetDocPrId();
return document_.Body().AddPicture(picture, getPosNode(posOpt));
End;
///插入图表
@@ -245,9 +287,11 @@ Type TSDocxFile = Class
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());
p := AddParagraph(p, getPosNode(posOpt), nil);
chart.pNode := p.node_;
p.Node().InsertEndChild(o.GetInnerXml());
TOfficeApi().Set('CurrentShape', p.node_);
chart.chartFileName := 'word/charts/chart' $ o.ChartId_ $ '.xml';
return chart;
End;
@@ -256,10 +300,10 @@ Type TSDocxFile = Class
Function GetCharts();overload;
Begin
r := array();
uri := 'w:p/w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart';
uri := '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);
node := class(TSXml).GetNode(ps[i].node_, uri);
if ifObj(node) then Begin
chart := TOfficeObj('TChart');
chart.Init(self, ps[i].node_, node);
@@ -269,6 +313,92 @@ Type TSDocxFile = Class
return r;
End;
///从Excel中Copy指定的chart图到文档中指定位置
///excelFileNamestring xlsx文件名
///excelSheetNamestring sheetname
///chartNamestring or integerchart图名称或当前sheet中chart图索引号
///Widthchart图宽度,单位cm
///Heightchart图高度,单位cm
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
///返回TChart对象
Function CopyExcelChart(excelFileName, excelSheetName, chartName, Width, Height, posOpt);
Begin
excel := new TSExcelFile();
[err, msg] := excel.OpenFile('', excelFileName);
if err then return nil;
[err, charts] := excel.GetCharts(excelSheetName);
if err or length(charts)=0 then return nil;
drawingObj := excel.WorkBook().GetXmlFileObj(charts[0].drawingFileName);
if not ifObj(drawingObj) then return nil;
node := drawingObj.FirstChildElement('xdr:wsDr').FirstChildElement('xdr:twoCellAnchor');
ind := 0;
chartRid := '';
while ifObj(node) do Begin
findChart := false;
cNvPr := class(TSXml).GetNode(node, 'xdr:GraphicFrame/xdr:nvGraphicFramePr/xdr:cNvPr');
name := ifObj(cNvPr) ? cNvPr.GetAttribute('name') : '';
if ifstring(chartName) then Begin
if name = chartName then
find := true;
End
else if ifInt(chartName) and ind = chartName then
find := true;
if find then Begin
chartNode := class(TSXml).GetNode(node, 'xdr:GraphicFrame/a:graphic/a:graphicData/c:chart');
if not ifObj(chartNode) then return nil;
chartRid := chartNode.GetAttribute('r:id');
break;
End;
ind ++;
node := node.NextElement();
End;
for i:=0 to length(charts)-1 do Begin
if charts[i].Rid = chartRid then Begin
chart := TOfficeObj('TChart');
chart.Width := Width;
chart.Height := Height;
chart.Name := name;
chart.Type := 'line';
chart.ShowBubbleSize := false;
chart.ShowPercent := false;
chart.DataTable := false;
chart.AddSeries('test', array('line1'), array(1,2));
chart := AddChart(chart, getPosNode(posOpt));
xmlObj := Zip().Get(chart.chartFileName);
xmlObj.Data := charts[i].xmlObj.Data;
return chart;
End;
End;
return nil;
End;
///复制Word内容
///docxObj: TSDocxFile对象
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
///返回: [err, TDocxCopy对象]
///TDocxCopy.GetCopiedTable() 返回复制的对象表格数组
///TDocxCopy.GetCopiedParagraph() 返回复制对象的段落数组
///TDocxCopy.GetCopiedDrawing() 返回复制对象的图表数组
Function InsertFile(alias, fileName, posOpt);
Begin
docxObj := new TSDocxFile();
[err, msg] := docxObj.OpenFile(alias, fileName);
if err then return array(err, msg);
copy_obj := new TDocxCopy(self, docxObj);
copy_obj.Init();
copy_obj.Copy(posOpt);
return array(0, copy_obj);
End;
///遍历文档中所有[TSTAG][/TSTAG]标签,针对每一个TAG执行tagObj.Apply()
///tagNamestring 标签名称
///tagObjTAG对象方法
///返回:[err,tslTagCount,errArr]: err 执行错误TAG次数,tslTagCount TAG总数,errArr 错误信息(array(('code':'代码', 'err':'错误信息'))
Function ExecTsTag(tagName, tagObj);
Begin
return Body().ExecTsTag(self, tagName, tagObj);
End;
///文档中全部的批注信息
///返回:DocComments对象
Function Comments();
@@ -288,11 +418,11 @@ Type TSDocxFile = Class
<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, target] := class(TSXml).FindRelationshipRid(xmlfile, '');
rId ++;
class(xlsxXml).AddRelationshipRid(xmlfile, 'comments.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', 'rId' $ rId);
class(TSXml).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');
class(TSXml).AddOverrideContentType(contentType, '/word/comments.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml');
End
xmlfile := zipfile_.Get(file);
id := 0;
@@ -304,50 +434,56 @@ Type TSDocxFile = Class
node := node.NextElement('w:comment');
End;
c := TOfficeObj('TDocComment');
c.p.Run.T := txt;
c.p.Run.SetText( txt );
c.Author := author;
c.ID := id;
xmlfile.FirstChildElement('w:comments').InsertEndChild(c.Marshal());
return c;
End;
///格式刷:复制段落格式(包括字体格式
///格式刷:段落格式 + 字体格式
///fromParagraph:源段落
Function CopyFormat(fromParagraph);
///toParagraph:目标段落
Function CopyFormat(fromParagraph, toParagraph);
Begin
selectPrargraph_ := fromParagraph;
toParagraph.ClearFormat();//清除目标段落格式、字体格式
CopyParagraphFormat(fromParagraph, toParagraph);//段落格式
//字体格式
if not ifObj(fromParagraph) then
return;
fromRun := fromParagraph.GetRun(0);
if ifObj(fromRun) then Begin
runs := toParagraph.GetRuns();
for i:=0 to length(runs)-1 do Begin
runs[i].CopyFontFormat(fromRun);
End;
End;
End;
///格式刷:将源段落格式(包括字体格式),刷到目标格式
///格式刷:仅段落格式
///fromParagraph:源段落
///toParagraph:目标段落
Function PasteFormat(toParagraph);
Function CopyParagraphFormat(fromParagraph, 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();
pPr := toParagraph.node_.FirstChildElement('w:pPr');
//清除段落格式
if ifObj(pPr) then
toParagraph.node_.DeleteChild(pPr);
pPr := ifObj(fromParagraph) ? fromParagraph.node_.FirstChildElement('w:pPr') : nil;
if ifObj(pPr) then Begin //复制段落格式
arr := pPr.Marshal();
toParagraph.node_.InsertFirstChild(arr[0]);
End;
End;
///格式刷:仅字体格式
///fromRun:源段落
///toRun:目标段落
Function CopyFontFormat(fromRun, toRun);
Begin
toRun.CopyFontFormat(fromRun);
End;
///添加目录
///[posOpt: 段落位置],在posOpt之后新添加目录(否则在首页添加)
///UpperHeadingLevel:标题最高级别
@@ -358,15 +494,13 @@ Type TSDocxFile = Class
Begin
content := new TTableContent(self);
content.SetDefaultFormat(); //缺省目录格式
node := posOpt;
if ifObj(posOpt) and not (posOpt is Class(XmlNode)) then
node := posOpt.Node();
node := getPosNode(posOpt);
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_);
//AddPageBreak(content.node_);
return content;
End;
@@ -376,10 +510,10 @@ Type TSDocxFile = Class
///返回:array((("Level":level,"Paragraph":"object","Text":title));
Function GetHeadingList(UpperHeadingLevel, LowerHeadingLevel);
Begin
return document_.Body().GetHeadingListImpl(self, UpperHeadingLevel, LowerHeadingLevel, nil, true);
return document_.Body().GetHeadingListImpl(self, nil, UpperHeadingLevel, LowerHeadingLevel, nil, true);
End;
///返回Document对象
//返回Document对象
Function Document();
Begin
return document_;
@@ -401,20 +535,63 @@ Type TSDocxFile = Class
return numberingObj_;
End;
Function ZipObject();
///执行word文档内嵌tsl代码(执行内嵌脚本的环境字符集为GBK)
///返回:[err,tslFuncCount,errArr]: err 执行错误TSL代码段次数,tslFuncCount TSL代码段总数,errArr 执行TSL错误信息(array(('code':'代码', 'err':'错误信息'))
Function ExecInnerTSL();
Begin
return Body().ExecInnerTSL(self);
End;
Function Zip();//兼容excel
Begin
return zipfile_;
End;
Function IsWord();
Begin
return true;
End;
Function GetPath();
Begin
return ExtractFileDir(ExtractFileDir(PluginPath()));
End;
Function GetDocPrId();
Begin
if DocPrId_ < 0 then Begin
DocPrId_ := 0;
ps := Paragraphs();
for i:=0 to length(ps)-1 do Begin
node := class(TSXml).GetNode(ps[i].node_, 'w:r/w:drawing/wp:inline/wp:docPr');
if not ifObj(node) then
node := class(TSXml).GetNode(ps[i].node_, 'w:r/w:pict/v:shape/v:textbox/w:txbxContent/wp:docPr');
if not ifObj(node) then
node := class(TSXml).GetNode(ps[i].node_, 'w:r/mc:AlternateContent/mc:Choice/w:drawing/wp:anchor/wp:docPr');
if ifObj(node) then Begin
id := class(TSXml).SafeStrToIntDef(node.GetAttribute('id'), 0);
if id > DocPrId_ then
DocPrId_ := id;
break;
End;
End;
End;
DocPrId_ ++;
return DocPrId_;
End;
Function GetPosNode(posOpt);
Begin
node := posOpt;
if ifObj(node) and not (node is Class(XmlNode)) then
node := node.Node();
return node;
End;
private
zipfile_; //压缩文件对象
document_; //Document对象
xml_; //xlsxXml对象
styleObj_;
numberingObj_;
selectPrargraph_;//被选中的段落
DocPrId_;
End;
+337 -130
View File
@@ -1,22 +1,34 @@
// Version 1.4.4
Type TSExcelFile = Class
///Version: V1.0 2022-08-08
///适用于 Microsoft Excel? 2007 及以上版本创建的电子表格文档。支持 XLSX / XLSM / XLTM / XLTX 等多种文档格式。
///纯TSL模块实现
///Excel文件读写接口
//缺省构造函数
///缺省构造函数
Function Create(); overload;
Begin
init();
End;
//构造函数,打开已经存在的excel文件
//alias: string,文件目录别名
//fname: string,文件名
///构造函数,打开已经存在的excel文件
///alias: string,文件目录别名
///fname: string,文件名
Function Create(alias, fname); overload;
Begin
init();
OpenFile(alias, fname);
OpenFile(alias, fname, nil);
End;
///构造函数,打开已经存在的excel文件
///alias: string,文件目录别名
///fname: string,文件名
///passwd: string,密码
Function Create(alias, fname, passwd); overload;
Begin
init();
OpenFile(alias, fname, passwd);
End;
//析构函数
@@ -33,11 +45,13 @@ Type TSExcelFile = Class
///打开excel文件
///alias: string,文件目录别名
///fname: string,文件名
///[passwd]: string,密码
///返回: [err, errmsg]
Function OpenFile(alias, fname);
Function OpenFile(alias, fname, passwd);
Begin
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
[err, errmsg] := zipfile_.Open(alias, fname);
if zipfile_.FilesCount() > 0 then zipfile_ := new ZipFile();
[err, errmsg] := zipfile_.Open(alias, fname, passwd);
if err=0 then Begin
workbook_ := new xlsxWorkBook(zipfile_);
workbook_.Load();
@@ -49,12 +63,14 @@ Type TSExcelFile = Class
///返回: [err, info]
Function NewFile();
Begin
path := ExtractFileDir(ExtractFileDir(PluginPath()));
if path[1] = '/' then
defaultFileName := path + '\\funcext\\TSOffice\\template\\default.xlsx';
else
defaultFileName := path + '/funcext/TSOffice/template/default.xlsx';
return OpenFile('', defaultFileName);
def := TOfficeTemplate('default.xlsx', true);
[err, errmsg] := zipfile_.LoadFromMem(def);
if err = 0 then
begin
workbook_ := new xlsxWorkBook(zipfile_);
workbook_.Load();
end
return array(err, errmsg);
End;
///保存文件
@@ -64,6 +80,33 @@ Type TSExcelFile = Class
return zipfile_.Save();
End;
///设置密码
Function SetPassword(passwd)
Begin
zipfile_.Password := passwd;
End;
///打开二进制内容
///data: 二进制数据
///返回: [err, errmsg]
Function LoadFromMem(data);
Begin
[err, errmsg] := zipfile_.LoadFromMem(data);
if err = 0 then
begin
workbook_ := new xlsxWorkBook(zipfile_);
workbook_.Load();
end
return array(err, errmsg);
End;
///保存为二进制内容
///返回: [err, fileContent] fileContent二进制文件内容
Function SaveToMem();
Begin
return zipfile_.Save2Mem();
End;
///另存为
///alias: string,文件目录别名
///fname: string,文件名
@@ -84,7 +127,12 @@ Type TSExcelFile = Class
///返回: array('Sheet1','Sheet2')
Function GetSheets();
Begin
return workbook_.GetSheets();
sheets := workbook_.GetSheets();
for i:=0 to length(sheets)-1 do
begin
sheets[i] := class(TSXml).Utf8ToCurCodePage(sheets[i]);
end
return sheets;
End;
///获取工作表数
@@ -94,38 +142,51 @@ Type TSExcelFile = Class
return workbook_.GetSheetsCount();
End;
///设置工作表名
///sourceName: string, 原工作表名
///destName: string,目标工作表名
///返回: [err, errinfo]
Function SetSheetName(sourceName, destName);
Begin
return workbook_.SetSheetName(sourceName, destName);
End;
///获取工作表名
///index: int,工作表索引
///返回: string
Function GetSheetName(index);
Begin
name := workbook_.GetSheets()[index];
return ifString(name) ? name : '';
name := workbook_.GetSheetName(index);
return class(TSXml).Utf8ToCurCodePage(name);
End;
///创建新sheet
///sheet: string,工作表名称
///返回: [err, info]
Function NewSheet(sheet);
Function NewSheet(sheet);overload;
Begin
return workbook_.NewSheet(sheet);
return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sheet));
End;
///在指定sheet之后插入新sheet
///sourceSheet: string,指定工作表名称
///destSheet: string,目的工作表名称
Function NewSheet(sourceSheet, destSheet);overload;
Begin
return workbook_.NewSheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet));
End;
///在指定sheet之前插入新sheet
///sourceSheet: string,指定工作表名称
///destSheet: string,目的工作表名称
Function InsertSheet(sourceSheet, destSheet);
Begin
return workbook_.InsertSheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet));
End;
///删除sheet
///sheet: string,工作表名称
///返回: [err, info]
Function DeleteSheet(sheet);
Begin
return workbook_.DeleteSheet(sheet);
return workbook_.DeleteSheet(class(TSXml).CurCodePageToUtf8(sheet));
End;
///设置工作表名
///sourceName: string, 原工作表名
///destName: string, 目标工作表名
Function SetSheetName(sourceName, destName);
Begin
return workbook_.SetSheetName(class(TSXml).CurCodePageToUtf8(sourceName), class(TSXml).CurCodePageToUtf8(destName));
End;
///获取总列数
@@ -133,8 +194,7 @@ Type TSExcelFile = Class
///返回: int
Function TotalCols(sheet);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.TotalCols();
return workbook_.TotalCols(class(TSXml).CurCodePageToUtf8(sheet));
End;
///获取总行数
@@ -142,8 +202,7 @@ Type TSExcelFile = Class
///返回: int
Function TotalRows(sheet);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.TotalRows();
return workbook_.TotalRows(class(TSXml).CurCodePageToUtf8(sheet));
End;
///获取单元格的值
@@ -152,9 +211,18 @@ Type TSExcelFile = Class
///返回: [err, value:string]
Function GetCellValue(sheet, axis);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.GetCellValue(axis);
return class(ErrorMessage).Fail();
[err, value] := workbook_.GetCellValue(class(TSXml).CurCodePageToUtf8(sheet), axis);
if not err then return array(err, class(TSXml).Utf8ToCurCodePage(value));
return array(err, value);
End;
///获取单元格数据类型
///sheet: string,工作表名称
///axis: string,单元格坐标,如: "A6"
///返回: type:string
Function GetCellValueType(sheet, axis);
Begin
return workbook_.GetCellValueType(class(TSXml).CurCodePageToUtf8(sheet), axis);
End;
///设置单元格的值
@@ -169,8 +237,9 @@ Type TSExcelFile = Class
/// 属性s:单元格样式
Function SetCellValue(sheet, axis, val, opt);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.SetCellValue(axis, val, opt);
sheet_name := class(TSXml).CurCodePageToUtf8(sheet);
value := class(TSXml).CurCodePageToUtf8(val);
return workbook_.SetCellValue(sheet_name, axis, value, opt);
End;
///获取富文本格式
@@ -179,9 +248,9 @@ Type TSExcelFile = Class
///返回: [err, richtxt:string],参见SetCellRichText
Function GetCellRichText(sheet, axis);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.GetCellValue(axis, 'RichText');
return class(ErrorMessage).Fail();
[err, str] := workbook_.GetCellRichText(class(TSXml).CurCodePageToUtf8(sheet), axis);
if err then return array(err, str);
else return array(err, class(TSXml).Utf8ToCurCodePage(str));
End;
///设置富文本格式
@@ -190,10 +259,12 @@ Type TSExcelFile = Class
///richtext: stringxml串或富文本对象TSOfficeObj('TRichText')
Function SetCellRichText(sheet, axis, richtext);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then begin
o := workbook_.GetSheetObj(class(TSXml).CurCodePageToUtf8(sheet));
if ifObj(o) then
begin
xml := richtext;
if ifObj(richtext) then
xml := class(xlsxXml).Dom2Xml(richtext.Marshal());
xml := class(TSXml).Dom2Xml(richtext.Marshal());
return o.SetCellValue(axis, xml, array('t':'s'), 'RichText');
end
End;
@@ -207,8 +278,7 @@ Type TSExcelFile = Class
/// 用法3ClearCell('A5', 'D8'); //Clear矩形区间所有单元格
Function ClearCell(sheet, topLeft, bottomRight);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then o.ClearCell(topLeft, bottomRight);
return workbook_.ClearCell(class(TSXml).CurCodePageToUtf8(sheet), topLeft, bottomRight);
End;
///设置公式
@@ -217,8 +287,7 @@ Type TSExcelFile = Class
///formula: string,公式
Function SetCellFormula(sheet, axis, formula);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then o.SetCellFormula(axis, formula);
return workbook_.SetCellFormula(class(TSXml).CurCodePageToUtf8(sheet), axis, formula);
End;
///获取公式
@@ -227,9 +296,7 @@ Type TSExcelFile = Class
///返回: [err, formula:string]
Function GetCellFormula(sheet, axis);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.GetCellFormula(axis);
return class(ErrorMessage).Fail();
return workbook_.GetCellFormula(class(TSXml).CurCodePageToUtf8(sheet), axis);
End;
///按行赋值
@@ -299,11 +366,12 @@ Type TSExcelFile = Class
///sheet: string,工作表名称
///topLeft: string,左上角坐标,如: "A4"
///bottomRight: string,右下角坐标,如: "B8",为空获取从topLeft开始的整张表
///[IncludeHeader: bool] 是否包括表头,默认FALSE
///[IncludeIndex: bool] 是否包括索引号,默认FALSE
///返回: table
Function GetTable(sheet, topLeft, bottomRight);
Function GetTable(sheet, topLeft, bottomRight, includeHeader, includeIndex, forceSingle);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.Import(topLeft, bottomRight);
return workbook_.GetTable(class(TSXml).CurCodePageToUtf8(sheet), topLeft, bottomRight, includeHeader, includeIndex, forceSingle);
End;
///插入列,在指定列前插入空白列
@@ -311,7 +379,7 @@ Type TSExcelFile = Class
///col: string 列名,如: "D"
Function InsertCol(sheet, col);
Begin
return workbook_.InsertCol(sheet, col);
return workbook_.InsertCol(class(TSXml).CurCodePageToUtf8(sheet), col);
End;
///插入行,在指定行前插入空白行
@@ -319,7 +387,7 @@ Type TSExcelFile = Class
///row: int
Function InsertRow(sheet, row);
Begin
return workbook_.InsertRow(sheet, row);
return workbook_.InsertRow(class(TSXml).CurCodePageToUtf8(sheet), row);
End;
///删除列
@@ -327,7 +395,7 @@ Type TSExcelFile = Class
///col: string,如: "D"
Function RemoveCol(sheet, col);
Begin
return workbook_.RemoveCol(sheet, col);
return workbook_.RemoveCol(class(TSXml).CurCodePageToUtf8(sheet), col);
End;
///删除行
@@ -335,7 +403,7 @@ Type TSExcelFile = Class
///row: int
Function RemoveRow(sheet, row);
Begin
return workbook_.RemoveRow(sheet, row);
return workbook_.RemoveRow(class(TSXml).CurCodePageToUtf8(sheet), row);
End;
///设置行高度
@@ -344,7 +412,7 @@ Type TSExcelFile = Class
///height: double,行高[0-409]
Function SetRowHeight(sheet, row, height);
Begin
return workbook_.SetRowHeight(sheet, row, height);
return workbook_.SetRowHeight(class(TSXml).CurCodePageToUtf8(sheet), row, height);
End;
///获取行高度
@@ -353,7 +421,7 @@ Type TSExcelFile = Class
///返回: double
Function GetRowHeight(sheet, row);
Begin
return workbook_.GetRowHeight(sheet, row);
return workbook_.GetRowHeight(class(TSXml).CurCodePageToUtf8(sheet), row);
End;
///设置列宽度
@@ -363,7 +431,7 @@ Type TSExcelFile = Class
///width: double,列宽[0-255]
Function SetColWidth(sheet, startCol, endCol, width);
Begin
return workbook_.SetColWidth(sheet, startCol, endCol, width);
return workbook_.SetColWidth(class(TSXml).CurCodePageToUtf8(sheet), startCol, endCol, width);
End;
///获取列宽度
@@ -372,7 +440,7 @@ Type TSExcelFile = Class
///返回: double
Function GetColWidth(sheet, col);
Begin
return workbook_.GetColWidth(sheet, col);
return workbook_.GetColWidth(class(TSXml).CurCodePageToUtf8(sheet), col);
End;
///设置工作表默认列宽
@@ -380,7 +448,7 @@ Type TSExcelFile = Class
///width: double
Function SetSheetDefaultColWidth(sheet, width);
Begin
return workbook_.SetSheetDefaultColWidth(sheet, width);
return workbook_.SetSheetDefaultColWidth(class(TSXml).CurCodePageToUtf8(sheet), width);
End;
///获取工作表默认列宽
@@ -388,7 +456,7 @@ Type TSExcelFile = Class
///返回: double
Function GetSheetDefaultColWidth(sheet);
Begin
return workbook_.GetSheetDefaultColWidth(sheet);
return workbook_.GetSheetDefaultColWidth(class(TSXml).CurCodePageToUtf8(sheet));
End;
///添加批注
@@ -399,7 +467,29 @@ Type TSExcelFile = Class
Function AddComment(sheet, axis, Author, comment);
Begin
o := getOj(sheet, 'xlsxComment');
if ifObj(o) then o.AddComment(axis, Author, comment);
if ifObj(o) then return o.AddComment(axis, Author, comment);
End;
///获取批注
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
///返回: [author:string, comment: string]
Function GetComment(sheet, axis);
Begin
author := nil;
comment := nil;
o := getOj(sheet, 'xlsxComment');
if ifObj(o) then [author, comment] := o.GetComment(axis);
return array(class(TSXml).Utf8ToCurCodePage(author), class(TSXml).Utf8ToCurCodePage(comment));
End;
///移除批注
///sheet: string,工作表名称
///axis: string,单元格,如"A7"
Function RemoveComment(sheet, axis);
Begin
o := getOj(sheet, 'xlsxComment');
if ifObj(o) then return o.RemoveComment(axis);
End;
///添加图表
@@ -417,7 +507,7 @@ Type TSExcelFile = Class
///返回: [err, ChartList]
Function GetCharts(sheet);
Begin
return workbook_.GetCharts(sheet);
return workbook_.GetCharts(class(TSXml).CurCodePageToUtf8(sheet));
End;
///单元格坐标切分
@@ -425,16 +515,7 @@ Type TSExcelFile = Class
///返回: [err, col:string, row:int]"AK47" -> return array(0, "AK", 47);
Function SplitCellName(cell);
Begin
return xlsx_call("SplitCellName", cell);
End;
///单元格坐标组合
///col: string
///row: int
///返回 [err, cell:string],参见SplitCellName
Function JoinCellName(col, row);
Begin
return xlsx_call("JoinCellName", col, row);
return SplitCellName(cell);
End;
///列名转索引
@@ -442,7 +523,7 @@ Type TSExcelFile = Class
///返回 [err, index:int]"AK" -> return array(0, 37);
Function ColumnNameToNumber(name);
Begin
return xlsx_call("ColumnNameToNumber", name);
return ColumnNameToNumber(name);
End;
///索引转列名
@@ -450,7 +531,7 @@ Type TSExcelFile = Class
///返回 [err, name:string]37 -> return array(0, "AK");
Function ColumnNumberToName(index);
Begin
return xlsx_call("ColumnNumberToName", index);
return ColumnNumberToName(index);
End;
///单元格坐标转索引
@@ -458,7 +539,7 @@ Type TSExcelFile = Class
///返回 [err, col:int, row: int] "A2" -> [1,2]
Function CellNameToCoordinates(cell);
Begin
return xlsx_call("CellNameToCoordinates", cell);
return CellNameToCoordinates(cell);
End;
///索引转单元格坐标
@@ -468,38 +549,56 @@ Type TSExcelFile = Class
///返回 [err, cell:string] [1,2,true] -> "$A$2"
Function CoordinatesToCellName(col, row, abs);
Begin
return xlsx_call("CoordinatesToCellName", col, row, abs);
return CoordinatesToCellName(col, row, abs);
End;
///RGB与HSL色彩空间色值转换
///r: int
///g: int
///b: int
///返回: [err, h:double, s:double, l:double]
///返回: [h:double, s:double, l:double]
Function RGBToHSL(r, g, b);
Begin
return xlsx_call("RGBToHSL", r, g, b);
return RGBToHSL(r, g, b);
End;
///HSL与RGB色彩空间色值转换
///h: double
///s: double
///l: double
///返回: [err, r:int, g:int, b:int]
Function HSLToRGB(sheet, h, s, l);
///返回: [r:int, g:int, b:int]
Function HSLToRGB(h, s, l);
Begin
return xlsx_call("HSLToRGB", h, s, l);
return HSLToRGB(h, s, l);
End;
///新建样式对象
///style: TStyle对象
///返回: styleid
Function NewStyle(style);
Function NewStyle(style); overload;
Begin
styleObj := new xlsxStyles('', self);
return styleObj.GetStyleId(style);
End;
///新建样式对象,已存在样式的基础上返回新的样式Id
///style: TStyle对象
///oldStyleId: 已存在的styleId
///返回: styleid
Function NewStyle(style, oldStyleId); overload;
Begin
styleObj := new xlsxStyles('', self);
return styleObj.GetStyleId(style, oldStyleId);
End;
///获取样式对象
///返回: TStyle对象
Function GetStyle(styleid);
Begin
styleObj := new xlsxStyles('', self);
return styleObj.GetStyle(styleid);
End;
///设置单元格样式
///sheet: string,工作表名称
///topLeft: string,左上角坐标
@@ -507,8 +606,7 @@ Type TSExcelFile = Class
///styleid: string,样式Id
Function SetCellStyle(sheet, topLeft, bottomRight, styleid);
Begin
o := workbook_.GetSheetObj(sheet);
if ifObj(o) then return o.SetCellStyle(topLeft, bottomRight, styleid);
return workbook_.SetCellStyle(class(TSXml).CurCodePageToUtf8(sheet), topLeft, bottomRight, styleid);
End;
///获取单元格样式Id,获取到的Id可以在复制单元格样式时,作为调用 SetCellValue、或SetCellStyle 函数的参数使用。
@@ -517,7 +615,7 @@ Type TSExcelFile = Class
///返回: styleId: string
Function GetCellStyle(sheet, axis);
Begin
return workbook_.GetCellStyle(sheet, axis);
return workbook_.GetCellStyle(class(TSXml).CurCodePageToUtf8(sheet), axis);
End;
///设置工作表页眉页脚
@@ -534,7 +632,7 @@ Type TSExcelFile = Class
///visible: boolean
Function SetSheetVisible(sheet, visible);
Begin
return workbook_.SetSheetVisible(sheet, visible);
return workbook_.SetSheetVisible(class(TSXml).CurCodePageToUtf8(sheet), visible);
End;
///获取工作表可见性
@@ -542,7 +640,7 @@ Type TSExcelFile = Class
///visibility: boolean
Function GetSheetVisible(sheet);
Begin
return workbook_.GetSheetVisible(sheet);
return workbook_.GetSheetVisible(class(TSXml).CurCodePageToUtf8(sheet));
End;
///设置行可见性
@@ -551,7 +649,7 @@ Type TSExcelFile = Class
///visible: boolean
Function SetRowVisible(sheet, row, visible)
Begin
return workbook_.SetRowVisible(sheet, row, visible);
return workbook_.SetRowVisible(class(TSXml).CurCodePageToUtf8(sheet), row, visible);
End;
///获取工作表行可见性
@@ -560,7 +658,7 @@ Type TSExcelFile = Class
///返回: [err, visible:boolean]
Function GetRowVisble(sheet, row);
Begin
return workbook_.GetRowVisble(sheet, row);
return workbook_.GetRowVisble(class(TSXml).CurCodePageToUtf8(sheet), row);
End;
///设置列可见性
@@ -571,7 +669,7 @@ Type TSExcelFile = Class
Begin
[err, col] := ColumnNameToNumber(col);
if err then return "Col error.";
return workbook_.SetColVisible(sheet, col, visible);
return workbook_.SetColVisible(class(TSXml).CurCodePageToUtf8(sheet), col, visible);
End;
///获取列可见性
@@ -582,7 +680,7 @@ Type TSExcelFile = Class
Begin
[err, col] := ColumnNameToNumber(col);
if err then return array(-1, col);
return workbook_.GetColVisble(sheet, col);
return workbook_.GetColVisble(class(TSXml).CurCodePageToUtf8(sheet), col);
End;
///设置工作表页边距
@@ -590,8 +688,7 @@ Type TSExcelFile = Class
///margins: TMargins 对象
Function SetPageMargins(sheet, margins);
Begin
o := getOj(sheet, 'xlsxMargins');
if ifObj(o) then o.SetPageMargins(margins);
return workbook_.SetPageMargins(class(TSXml).CurCodePageToUtf8(sheet), margins);
End;
///获取工作表页边距
@@ -599,9 +696,7 @@ Type TSExcelFile = Class
///返回: TMargins对象
Function GetPageMargins(sheet);
Begin
o := getOj(sheet, 'xlsxMargins');
if ifObj(o) then return o.GetPageMargins();
return "sheet error";
return workbook_.GetPageMargins(class(TSXml).CurCodePageToUtf8(sheet));
End;
///合并单元格
@@ -610,7 +705,7 @@ Type TSExcelFile = Class
///vcell: string,右下角坐标
Function MergeCell(sheet, hcell, vcell);
Begin
return workbook_.MergeCell(sheet, hcell, vcell);
return workbook_.MergeCell(class(TSXml).CurCodePageToUtf8(sheet), hcell, vcell);
End;
///取消合并单元格
@@ -619,40 +714,57 @@ Type TSExcelFile = Class
///vcell: string,右下角坐标
Function UnMergeCell(sheet, hcell, vcell);
Begin
return workbook_.UnMergeCell(sheet, hcell, vcell);
return workbook_.UnMergeCell(class(TSXml).CurCodePageToUtf8(sheet), hcell, vcell);
End;
///新建窗口
///返回:windowsIndex int, 窗口索引
Function NewSheetPane();
Begin
return workbook_.NewSheetView();
End;
///设置窗格
///sheet: string,工作表名称
///windowsIndex: int,窗口索引,从0开始
///Pane: TPane对象
Function SetPane(sheet, windowsIndex, Pane);
Begin
o := getOj(sheet, 'xlsxSheetView');
if ifObj(o) then return o.SetPane(windowsIndex, Pane);
End;
///设置工作表视图属性
///sheet: string,工作表名称
///viewIndex: int视图索引
///windowsIndex: int窗口索引,从0开始
///sheet: objectTSheetView对象
Function SetSheetViewOptions(sheet, viewIndex, sheetView);
Function SetSheetViewOptions(sheet, windowsIndex, sheetView);
Begin
o := getOj(sheet, 'xlsxSheetView');
if ifObj(o) then return o.SetSheetViewOptions(viewIndex, sheetView);
if ifObj(o) then return o.SetSheetViewOptions(windowsIndex, sheetView);
End;
///获取工作表视图属性
///sheet: string,工作表名称
///viewindex: int视图索引,viewIndex 可以是负数,如果是这样,则向后计数(-1 代表最后一个视图)
///windowsIndex: int窗口索引,从0开始
///返回: object, TSheetView对象
Function GetSheetViewOptions(sheet, viewIndex);
Function GetSheetViewOptions(sheet, windowsIndex);
Begin
o := getOj(sheet, 'xlsxSheetView');
if ifObj(o) then return o.GetSheetViewOptions(viewIndex);
if ifObj(o) then return o.GetSheetViewOptions(windowsIndex);
End;
// TODO printerSettings1.bin?
///设置工作表页面设置
///设置工作表页面布局
///sheet: string,工作表名称
///pageLayout: TPageLayout对象,属性:
Function SetPageLayout(sheet, pageLayout);
Begin
o := getOj(sheet, 'xlsxPageLayout');
if ifObj(o) then return o.SetPageLayout(sheet, pageLayout);
if ifObj(o) then return o.SetPageLayout(class(TSXml).CurCodePageToUtf8(sheet), pageLayout);
End;
///获取工作表页面设置
///获取工作表页面布局
///sheet: string,工作表名称
///返回: TPageLayout对象
Function GetPageLayout(sheet);
@@ -662,17 +774,19 @@ Type TSExcelFile = Class
return "error sheet";
End;
///设置默认工作表
///sheet: string,工作表名称
Function SetDefaultSheet(sheet);
Begin
return workbook_.SetDefaultSheet(sheet);
return workbook_.SetDefaultSheet(class(TSXml).CurCodePageToUtf8(sheet));
End;
///获取默认工作表
///返回: string,工作表名称
Function GetDefaultSheet();
Begin
return workbook_.GetDefaultSheet();
sheet := workbook_.GetDefaultSheet();
return class(TSXml).Utf8ToCurCodePage(sheet);
End;
///设置超链接
@@ -707,8 +821,8 @@ Type TSExcelFile = Class
///添加图片
///sheet: string, 工作表名称
///topLeft: string, 图片插入左上角单元格
///bottomRight: string, 图片插入右下角单元格
///topLeft: string, 图片插入左上角单元格
///bottomRight: string, 图片插入右下角单元格
///picture: TPicture 图片对象
///format: TPictureFormat 图片设置对象
Function AddPicture(sheet, topLeft, bottomRight, picture, format);
@@ -719,19 +833,19 @@ Type TSExcelFile = Class
///删除图片
///sheet: 工作表名称
///topLeft: string, 图片插入左上角单元格
///bottomRight: string, 图片插入右下角单元格
///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
///topLeft: string, 左上角单元格
///bottomRight: string, 右下角单元格
///tableStyle: 表格选项类 TTableStyle
///[includeHeader: bool] 是否包括表头,默认FALSE
Function AddTable(sheet, topLeft, bottomRight, tableStyle, includeHeader);
Begin
@@ -744,7 +858,7 @@ Type TSExcelFile = Class
///row: int,行号
Function InsertPageBreak(sheet, row);
Begin
return workbook_.InsertPageBreak(sheet, row);
return workbook_.InsertPageBreak(class(TSXml).CurCodePageToUtf8(sheet), row);
End;
///删除指定行分页符
@@ -752,13 +866,13 @@ Type TSExcelFile = Class
///row: int,行号
Function RemovePageBreak(sheet, row);
Begin
return workbook_.RemovePageBreak(sheet, row);
return workbook_.RemovePageBreak(class(TSXml).CurCodePageToUtf8(sheet), row);
End;
///添加形状
///sheet: string,工作表名称
///topLeft: string, 左上角单元格
///bottomRight: string, 右下角单元格
///topLeft: string, 左上角单元格
///bottomRight: string, 右下角单元格
///shapeType: string, 形状类型
///format: 形状设置,TShapeFormat类
Function AddShape(sheet, topLeft, bottomRight, shapeType, format);
@@ -767,7 +881,7 @@ Type TSExcelFile = Class
if ifObj(o) then return o.AddShape(topLeft, bottomRight, shapeType, format);
End;
///设置工作簿的核心属性
///设置工作簿的核心属性
///coreProps: TCoreProperty对象
Function SetCoreProps(coreProps);
Begin
@@ -799,6 +913,99 @@ Type TSExcelFile = Class
return o.GetAppProps();
End;
///复制Sheet
///sourceSheet: 源工作表
///destSheet: 目的工作表
Function CopySheet(sourceSheet, destSheet);
Begin
return workbook_.CopySheet(class(TSXml).CurCodePageToUtf8(sourceSheet), class(TSXml).CurCodePageToUtf8(destSheet));
End;
///保护工作表
///sheet: 工作表
///protect: TProtect对象
Function ProtectSheet(sheet, protect);
Begin
return workbook_.ProtectSheet(class(TSXml).CurCodePageToUtf8(sheet), protect);
End;
///取消保护工作
///sheet: 工作表
Function UnProtectSheet(sheet);
Begin
return workbook_.UnProtectSheet(class(TSXml).CurCodePageToUtf8(sheet));
End;
///设置默认字体
///font: TFont对象
Function SetDefaultFont(font);
Begin
return workbook_.SetDefaultFont(font);
End;
///获取默认字体
///返回: TFont对象
Function GetDefaultFont();
Begin
return workbook_.GetDefaultFont();
End;
///设置工作簿计算选项
///calcPr: TCalcPr对象
Function SetCalcOptions(calcPr);
Begin
return workbook_.SetCalcOptions(calcPr);
End;
///获取工作簿计算选项
///返回: TCalcPr对象
Function GetCalcOptions();
Begin
return workbook_.GetCalcOptions();
End;
///创建行的分级显示,根据给定的工作表、行号和分级参数创建组
///sheet: string, 工作表名称
///row: int, 行号
///level: int, 分级参数
Function SetRowOutlineLevel(sheet, row, level);
Begin
return workbook_.SetRowOutlineLevel(class(TSXml).CurCodePageToUtf8(sheet), row, level);
End;
///获取行的分级参数
///sheet: string, 工作表名称
///row: int, 行号
///返回: int,分级参数,分级不存在返回0
Function GetRowOutlineLevel(sheet, row);
Begin
return workbook_.GetRowOutlineLevel(class(TSXml).CurCodePageToUtf8(sheet), row);
End;
///
///创建列的分级显示,根据给定的工作表、列名和分级参数创建组
///sheet: string, 工作表名称
///col: string, 列名
///level: int, 分级参数
Function SetColOutlineLevel(sheet, col, level);
Begin
[err, col] := ColumnNameToNumber(col);
if err then return "Col error.";
return workbook_.SetColOutlineLevel(class(TSXml).CurCodePageToUtf8(sheet), col, level);
End;
///获取列的分级参数
///sheet: string, 工作表名称
///col: string, 列名
///返回: int,分级参数,分级不存在返回0
Function GetColOutlineLevel(sheet, col);
Begin
[err, col] := ColumnNameToNumber(col);
if err then return "Col error.";
return workbook_.GetColOutlineLevel(class(TSXml).CurCodePageToUtf8(sheet), col);
End;
Function WorkBook();
Begin
return workbook_;
@@ -810,8 +1017,9 @@ Type TSExcelFile = Class
End;
private
Function getOj(sheetname, objname);
Function getOj(sheet, objname);
Begin
sheetname := class(TSXml).CurCodePageToUtf8(sheet);
if not ifarray(objMgr_) then objMgr_:= array();
k := sheetname + '.' + objname;
o := objMgr_[ k ];
@@ -827,8 +1035,6 @@ private
return class(xlsxChart).NewObject(sheetname, self);//不缓存xlsxChart对象
'xlsxHeaderFooter':
o := class(xlsxHeaderFooter).NewObject(sheetname, self);
'xlsxMargins':
o := class(xlsxMargins).NewObject(sheetname, self);
'xlsxSheetView':
o := class(xlsxSheetView).NewObject(sheetname, self);
'xlsxPageLayout':
@@ -852,3 +1058,4 @@ private
workbook_; //WorkBook对象
objMgr_; //各种对象缓存、管理
End;
+31 -35
View File
@@ -1,9 +1,12 @@
Type NodeInfo = class
public
Function Create(p, name);
Function Create(parentObj, name);
Begin
Parent := p;
if ifObj(parentObj) then
NodeUri := parentObj.NodeUri = '' ? name : (parentObj.NodeUri + '/' + name);
else
NodeUri := '';
NodeName := name;
ExtAttr := array();
ExtNodes := array();
@@ -20,7 +23,9 @@ public
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']);
curNode := class(TSXml).GetNode(RootObj, NodeUri);
if ifObj(curNode) then
class(TSXml).UpdateNode(curNode, arr['attributes'], arr['children']);
End;
End;
End;
@@ -74,7 +79,7 @@ public
if ifnil(obj) then continue;
//find := select thisrowindex as "rowindex_", * from child_arr where ['name'] = children_[i]['name'] end; //优化为循环,性能提高15-20%2022-12-20
find := array();
for j:=0 to length(child_arr)-1 do Begin
for j:=length(child_arr)-1 downto 0 do Begin //支持列表模式(如多节点:<w:t xml:space=""></w:t>),查找最近的节点
if child_arr[j]['name'] = children_[i]['name'] then Begin
find[0] := child_arr[j];
find[0]['rowindex_'] := j;
@@ -93,10 +98,9 @@ public
arr := array('type': 'element', 'name': children_[i]['name'], 'attributes': array());
if node_type = 'empty' then // <b/>
begin
end
else if node_type = 'empty_string' then
begin
if ifstring(obj) then arr['attributes'] := array(key : obj);
empty_name := children_[i]['attrEx'] ? children_[i]['attrEx'] : 'val';
if obj = 0 then arr['attributes'] := array(empty_name: 0);
else if obj = 1 then arr['attributes'] := array(empty_name: 1)
end
else if node_type = 'pcdata' then
begin
@@ -152,46 +156,37 @@ public
Function Value(name);
Begin
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;
if not ifObj(RootObj) then return nil;
if NodeUri <> '' then
node := class(TSXml).GetNode(RootObj, NodeUri);
else
node := RootObj;
if not ifObj(node) then return nil;
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;
if istable(r) then
begin
value := node.GetAttribute(r[1]);
return trystrtofloat(value, r) ? r : value;
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);
node := node.FirstChildElement(r['name']);
if not ifObj(node) and r['nodeType'] = 'empty' then return false;
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);//返回属性
value := node.GetAttribute(key);
if r['nodeType'] = 'empty' and value = '' then return true;
return trystrtofloat(value, r) ? r : value;
End;
return nil;
End;
@@ -274,8 +269,9 @@ public
NodeName;
ExtAttr;
ExtNodes;
Parent;
//Parent;
ReplaceArr;
RootObj;
RootObj; // xml node
NodeUri:string;
children_;
End
+256
View File
@@ -0,0 +1,256 @@
Function TOfficeApi();
Begin
if not ifObj(sysparams['TOffice sys api']) then
sysparams['TOffice sys api'] := new TOffice();
return sysparams['TOffice sys api'];
End;
Type TOffice = Class
Function Create();
Begin
hash_ := array();
End;
///检测当前环境字符集
///调用规范:TOfficeApi().CodePage('中文');
Function CodePage(zw);
Begin
cp := 'utf8';//默认环境为UTF8格式
str := StrToBase64(zw);
case str of
'1tDOxA==':
cp := 'gbk';
'5Lit5paH':
cp := 'utf8';
'pKSk5Q==':
cp := 'big5';
End;
hash_['CodePage'] := cp;
End;
///当前环境是否UTF8
Function IsUtf8();
Begin
if ifnil(hash_['CodePage']) or hash_['CodePage'] = 'utf8' then
return true;
return false;
End;
///UTF8转当前字符集
Function Utf8ToCurCodePage(str);
Begin
if ifstring(str) and not IsUtf8() then
return UTF8ToAnsi(str);
return str;
End;
///当前字符集转UTF8
Function CurCodePageToUtf8(str);
Begin
if ifstring(str) and not IsUtf8() then
return AnsiToUTF8(str);
return str;
End;
///当前字符集转GBK
Function CurCodePageToGBK(str);
Begin
if ifstring(str) and IsUtf8() then
return UTF8ToAnsi(str);
return str;
End;
///获得当前文档对象:TDocxFile对象
Function GetDocument();
Begin
return hash_['Docx'];
End;
///设置当前段落标签
///namestring 标签名称
Function SetParagraphTag(name);
Begin
hash_['Paragraph-Node-' + name] := hash_['CurrentParagraph'];
End;
Function GetCurrentPosition()
Begin
return hash_['CurrentPosition'];
End;
///获取当前TSL代码段所在段落
///返回:TParagraph对象
Function GetCurrentParagraph();
Begin
node := hash_['CurrentParagraph'];
if not ifObj(node) then
return nil;
p := TOfficeObj('TParagraph');
p.Init(node);
return p;
End;
///获取当前TSL代码段所在段落的w:r元素
///返回:TRun对象
Function GetCurrentRun();
Begin
node := hash_['CurrentRun'];
if not ifObj(node) then
return nil;
p := TOfficeObj('TRun');
p.Init(node);
return p;
End;
///获取指定标签段落
///namestring 标签名称
///返回:TParagraph对象
Function GetParagraph(name);
Begin
node := hash_['Paragraph-Node-' + name];
if not ifObj(node) then
return nil;
p := TOfficeObj('TParagraph');
p.Init(node);
return p;
End;
///获取当前TSL代码段上一个表格
///[p]:可选参数,为Nil指当前段落
///返回:TTable对象
Function GetPrevTable(p);
Begin
return getTableImpl(p, false);
End;
///获取当前TSL代码段下一个表格
///[p]:可选参数,为Nil指当前段落
///返回:TTable对象
Function GetNextTable(p);
Begin
return getTableImpl(p, true);
End;
///获取当前TSL代码段上一张图片
///[p]:可选参数,为Nil指当前段落
///返回:TPicture对象
Function GetPrevPicture(p);
Begin
return getPictureImpl(p, false);
End;
///获取当前TSL代码段下一张图片
///[p]:可选参数,为Nil指当前段落
///返回:TPicture对象
Function GetNextPicture(p);
Begin
return getPictureImpl(p, true);
End;
///获取当前TSL代码段上一个Chart图
///[p]:可选参数,为Nil指当前段落
///返回:TChart对象
Function GetPrevChart(p);
Begin
return getChartImpl(p, false);
End;
///获取当前TSL代码段下一个Chart图
///[p]:可选参数,为Nil指当前段落
///返回:TChart对象
Function GetNextChart(p);
Begin
return getChartImpl(p, true);
End;
///获取当前TSL代码段上一个文本框图
///[p]:可选参数,为Nil指当前段落
///返回:TTextBox对象
Function GetPrevTextBox(p);
Begin
p1 := getTextBoxImpl(p, false);
End;
///获取当前TSL代码段下一个文本框图
///[p]:可选参数,为Nil指当前段落
///返回:TTextBox对象
Function GetNextTextBox(p);
Begin
return getTextBoxImpl(p, true);
End;
Function Set(k, v);
Begin
hash_[k] := v;
End;
Function Get(k);
Begin
return hash_[k];
End;
private
Function getTableImpl(p, next);
Begin
if not ifObj(p) then
p := GetCurrentParagraph();
node := next ? p.node_.NextElement('w:tbl') : p.node_.PrevElement('w:tbl');
if not ifObj(node) then
return nil;
tbl := TOfficeObj('TTable');
tbl.Init(node);
return tbl;
End;
Function getPictureImpl(p, next);
Begin
if not ifObj(p) then
p := GetCurrentParagraph();
node := next ? p.node_.NextElement('w:p') : p.node_.PrevElement('w:p');
while ifObj(node) do Begin
draw := class(TSXml).GetNode(node, 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/pic:pic');
if ifObj(draw) then Begin
p := TOfficeObj('TPicture');
p.Init(node);
return p;
End;
node := next ? p.node.NextElement('w:p') : p.node.PrevElement('w:p');
End;
return nil;
End;
Function getChartImpl(p, next);
Begin
if not ifObj(p) then
p := GetCurrentParagraph();
node := next ? p.node_.NextElement('w:p') : p.node_.PrevElement('w:p');
while ifObj(node) do Begin
chartNode := class(TSXml).GetNode(node, 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart');
if ifObj(chartNode) then Begin
p := TOfficeObj('TChart');
p.Init(hash_['Docx'], node, chartNode);
return p;
End;
node := next ? p.node.NextElement('w:p') : p.node.PrevElement('w:p');
End;
return nil;
End;
Function getTextBoxImpl(p, next);
Begin
if not ifObj(p) then
p := GetCurrentParagraph();
node := next ? p.node_.NextElement('w:p') : p.node_.PrevElement('w:p');
while ifObj(node) do Begin
p := TOfficeObj('TParagraph');
boxs := p.TextBoxs();
if istable(boxs) then Begin
if next then return boxs[0];
return boxs[ length(boxs) - 1];
End;
node := next ? p.node.NextElement('w:p') : p.node.PrevElement('w:p');
End;
return nil;
End;
hash_;
End;
+4
View File
@@ -0,0 +1,4 @@
Function TOfficeInit();
Begin
sysparams['TOffice sys api'] := nil;
End;
+5 -5
View File
@@ -103,7 +103,7 @@ Type TSChart = Class
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),
task := array(('c:chartSpace/c:chart/c:title/c:tx/c:rich/a:p/a:r/a:t', 'pcdata', class(TSXml).CurCodePageToUtf8(chartData_.Title)),
('c:chartSpace/c:chart/c:plotVisOnly', 'val', chartData_.plotVisOnly),
('c:chartSpace/c:chart/c:dispBlanksAs', 'val', chartData_.ShowBlanksAs),
('c:chartSpace/c:chart/c:legend', 'Del', ifnil(chartData_.Legend)),
@@ -111,16 +111,16 @@ Type TSChart = Class
('c:chartSpace/c:chart/c:view3D', 'unmarshal', getview3D().Marshal())
);
for i:=0 to length(task)-1 do Begin
class(xlsxXml).SetNodeValue(xmlObj, task[i]);
class(TSXml).SetNodeValue(xmlObj, task[i]);
End;
if ifObj(chartData_.Legend) then Begin
node := class(xlsxXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:legend');
node := class(TSXml).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']);
class(TSXml).UpdateNode(node, arr['attributes'], arr['children']);
End;
End;
chartData_.ChartNode := class(xlsxXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea');
chartData_.plotAreaNode := class(TSXml).GetNode(xmlObj, 'c:chartSpace/c:chart/c:plotArea');
if chartData_.DataTable then
chartData_.ShowDataTable(true);
End;
+127 -196
View File
@@ -2,220 +2,151 @@ Type TSImage = Class
Function Create(stream); overload;
Begin
content_ := stream;
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);
'Bmp':
[px_width, px_height, horz_dpi, vert_dpi] := bmp_dimensions(stream);
'Tiff':
[px_width, px_height, horz_dpi, vert_dpi] := tiff_dimensions(stream, imageDef[ind][2]);
End;
End;
//println('width={},height={}',px_width, px_height);
end;
width_ := 0;
height_ := 0;
imagetypeDef := array(
('name': 'bmp', 'position': 0, 'value': array(0x42, 0x4d)),
('name': 'png', 'position': 0, 'value': array(0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)),
('name': 'gif', 'position': 0, 'value': array(0x47, 0x49, 0x46, 0x38, 0x39, 0x61)),
('name': 'gif', 'position': 0, 'value': array(0x47, 0x49, 0x46, 0x38, 0x37, 0x61)),
('name': 'jpeg', 'position': 0, 'value': array(0xFF, 0xD8, 0xFF, 0xE1)),
('name': 'jpg', 'position': 0, 'value': array(0xFF, 0xD8)),
('name': 'tiff', 'position': 0, 'value': array(0x49, 0x49), 'order': 'littleEndian'),
('name': 'tiff', 'position': 0, 'value': array(0x4D, 0x4D), 'order': 'bigEndian'),
);
stringObj_ := new TMemoryStream();
size := length(stream);
stringObj_.Write(stream[0:size-1], size);
index := getImageType(imagetypeDef);
ExtFileName := imagetypeDef[index]['name'];
case ExtFileName of
'bmp':
[width_, height_] := bmp_dimensions();
'png':
[width_, height_] := png_dimensions();
'gif':
[width_, height_] := gif_dimensions();
'tiff':
[width_, height_] := tiff_dimensions(imagetypeDef[i]['order']);
'jpeg', 'jpg':
[width_, height_] := jpeg_dimensions();
end
//println("width_ = {}, height_ = {}", width_, height_);
End;
Function getImageType(def);
Begin
for i:=0 to length(def)-1 do
begin
value := def[i]['value'];
stringObj_.Seek(def[i]['position']);
for j:=0 to length(value)-1 do
begin
r := 0;
stringObj_.Read(r, 1);
if r <> value[j] then break;
if j = length(value)-1 then return i;
end
end
return -1;
End
Function Width();
Begin
return integer((px_width / horz_dpi) * 914400);
return width_;
End;
Function Height();
Begin
return integer((px_height / vert_dpi) * 914400);
return height_;
End;
(*
Function exif_dimensions(stream, r);
Property Content read readContent;
Function readContent();
Begin
start := 0;
code := nil;
while code <> 0xd9 do Begin
[code, off] := _exif_next(start);
case code of
0xe0:
Begin
segment_length := _read_int(stream, off, '', 2);
density_units := _read_int(stream, off + 9, '', 1);
horz_dpi := read_int(stream, off + 10, '', 2);
vert_dpi := read_int(stream, off + 12, '', 2);
End;
End;
start := off + segment_length;
End;
return content_;
End;
Function _exif_next(start);
Function jpeg_dimensions();
Begin
while 1 do Begin
position := _offset_of_next_ff_byte(start);
[position, byte_] = _next_non_ff_byte(position+1);
start := position + 1;
if byte_ = 0x00 then continue;
marker_code := byte_;
segment_offset := position + 1;
break;
End;
return array(marker_code, segment_offset);
des1 := 0xff;
des2 := 0xc0;
flag := 1;
while flag do
begin
stringObj_.Read(byte1, 1);
stringObj_.Read(byte2, 1);
if byte1 = des1 and byte2 = des2 then flag := 0;
end
if flag then return array(0, 0);
stringObj_.Read(tmp, 3);
height := readBigEndianByte(2);
width := readBigEndianByte(2);
return array(width, height);
End;
Function _offset_of_next_ff_byte(start);
Function tiff_dimensions(byteOrder);
Begin
for i:=start to length(content_)-1 do Begin
byte_ := ord(content_[i]);
if byte_ <> 0xff then return array(start - 1, byte_);
return array(start, 0);
stringObj_.seek(4);
if byteOrder = 'bigEndian' then
IFD := readBigEndianByte(4);
else stringObj_.Read(IFD, 4);
return array(0, 0);
End;
Function _next_non_ff_byte(start);
Function bmp_dimensions();
Begin
for i:=start to length(content_)-1 do Begin
byte_ := ord(content_[i]);
if byte_ = 0xff then return start - 1;
return start;
stringObj_.Seek(0x12);
width := 0;
stringObj_.Read(width, 4);
height := 0;
stringObj_.Read(height, 4);
//stringObj_.Seek(0x26);
//horz_px_per_meter := 0;
//stringObj_.Read(horz_px_per_meter, 4);
//vert_px_per_meter := 0;
//stringObj_.Read(vert_px_per_meter, 4);
//horz_dpi_ := _bmp_dpi(horz_px_per_meter);
//vert_dpi_ := _bmp_dpi(vert_px_per_meter);
return array(width, height);
End;
*)
Function tiff_dimensions(stream, r);
Function png_dimensions();
Begin
off := _read_int(stream, 4, r[0], 4);
count := _read_int(stream, off, r[0], 2);
m := array();
for i:=0 to count-1 do Begin
dir_entry_offset := off + 2 + i*12;
tag_code := _read_int(stream, dir_entry_offset, r[0], 2);
field_type := _read_int(stream, dir_entry_offset + 2, r[0], 2);
value_count := _read_int(stream, dir_entry_offset + 4, r[0], 4);
value_offset := _read_int(stream, dir_entry_offset + 8, r[0], 4);
case field_type of
2:
val := stream[value_offset:value_offset+value_count-1];
3:
if value_count=1 then
val := _read_int(stream, dir_entry_offset + 8, r[0], 2);
4:
if value_count=1 then
val := _read_int(stream, dir_entry_offset + 8, r[0], 4);
5:
if value_count=1 then Begin
numerator := _read_int(stream, value_offset, r[0], 4);
denominator := _read_int(stream, value_offset + 4, r[0], 4);
val := numerator / denominator;
End;
End;
println('off={}, tag={},type={},value_count={},value_off={},val={}',off, tag_code,field_type,value_count,value_offset,val);
m[tag_code] := val;
End;
px_width := m[256];
px_height := m[257];
horz_dpi := _tiff_dpi(282, m);
vert_dpi := _tiff_dpi(283, m);
return array(px_width, px_height, horz_dpi, vert_dpi);
stringObj_.Seek(0x10);
width := readBigEndianByte(4);
height := readBigEndianByte(4);
return array(width, height);
End;
Function _read_int(stream, off, t, size);
Function gif_dimensions();
Begin
stm := new TMemoryStream();
if t = 'M' then Begin
s := '';
setlength(s, 8);
for i:=0 to size-1 do Begin
s[i] := stream[off + size - i - 1];
End;
stm.Write(s, size);
End
else Begin
stm.Write(stream[off:off + 7], size);
End;
stm.Seek(0);
v := 0;
stm.Read(v, size);
return v;
stringObj_.Seek(0x6);
width := 0;
stringObj_.Read(width, 2);
height := 0;
stringObj_.Read(height, 2);
return array(width, height);
End;
Function bmp_dimensions(stream);
Function readBigEndianByte(num);
Begin
s := new TMemoryStream();
s.Write(stream[0:63], 64);
s.Seek(0x12);
px_width := 0;
s.Read(px_width, 4);
px_height := 0;
s.Read(px_height, 4);
s.Seek(0x26);
horz_px_per_meter := 0;
s.Read(horz_px_per_meter, 4);
vert_px_per_meter := 0;
s.Read(vert_px_per_meter, 4);
horz_dpi := _bmp_dpi(horz_px_per_meter);
vert_dpi := _bmp_dpi(vert_px_per_meter);
return array(px_width, px_height, horz_dpi, vert_dpi);
ret := 0;
while num do
begin
stringObj_.Read(b, 1);
ret := _Shl(ret, 8);
ret += b;
num --;
end
return ret;
End;
Function gif_dimensions(stream);
Begin
s := new TMemoryStream();
s.Write(stream[6:9], 4);
s.Seek(0);
px_width := 0;
s.Read(px_width, 2);
px_height := 0;
s.Read(px_height, 2);
return array(px_width, px_height, 72, 72);
End;
Function getImageDef(stream, imageDef);
Begin
for i:=0 to length(imageDef)-1 do Begin
off := imageDef[i][1];
len := length(imageDef[i][2]);
buf := stream[off:off+len-1];
if eq(buf, imageDef[i][2]) then Begin
return i;
End;
End;
return -1;
End;
Function eq(buf, r);
Begin
for i:=0 to length(buf)-1 do Begin
c := ifstring(r) ? r[i + 1] : r[i];
if ifint(c) then c := chr(c);
if c <> buf[i+1] then return 0;
End;
return 1;
End;
Function _tiff_dpi(tag, m);
Begin
if not ifint(m[tag]) then return 72;
v := ifint(m[296]) ? m[296] : 2;
if v = 1 then return 72;
units_per_inch := (v=2 ? 2.54 : 1);
dots_per_unit := m[tag];
return integer(round(dots_per_unit * units_per_inch));
End;
Function _bmp_dpi(px_per_meter);
Begin
if px_per_meter = 0 then return 96;
return integer(round(px_per_meter * 0.0254));
End;
Name;
content_;
px_width:integer;
px_height:integer;
horz_dpi:integer;
vert_dpi:integer;
ExtFileName:string;
End;
Name:string;
content_;
stringObj_;
width_:integer;
height_:integer;
End;
@@ -1,4 +1,4 @@
Type xlsxXml = Class
Type TSXml = Class
class Function XmlHeader();
Begin
return '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> \n';
@@ -20,22 +20,26 @@ Type xlsxXml = Class
'workbook_rels':('FileName':'xl/_rels/workbook.xml.rels','Template':'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet" Target="worksheets/sheet1.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/></Relationships>'),
'sheet_rels':('FileName':'','Template':'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>'),
'drawing_rels':('FileName':'','Template':'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"></Relationships>'),
'SheetContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'),
'sheetContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'),
'RelationshipWorkSheet':('FileName':'','Template':'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet'),
'table1':('FileName':'xl/tables/table1.xml','Template':'<table xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="xr xr3" xmlns:xr="http://schemas.microsoft.com/office/spreadsheetml/2014/revision" xmlns:xr3="http://schemas.microsoft.com/office/spreadsheetml/2016/revision3"></table>'),
'tableContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml'),
'commentContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'),
'drawingContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.drawing+xml'),
'chartContentType':('FileName':'','Template':'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'),
);
End
class Function GetFileName(key);
Begin
map := class(xlsxXml).GetMap();
map := class(TSXml).GetMap();
if ifarray(map[key]) then return map[key]['FileName'];
return '';
End;
class Function GetTemplate(key);
Begin
map := class(xlsxXml).GetMap();
map := class(TSXml).GetMap();
if ifarray(map[key]) then return map[key]['Template'];
return '';
End;
@@ -101,12 +105,14 @@ Type xlsxXml = Class
child := node.FirstChild();
else
child := node.FirstChild(children[i]['name']);
if not ifObj(child) then
child := node.InsertEndChild(children[i]['type'], children[i]['name']);
if not ifObj(child) then Begin
child := node.InsertEndChild(children[i]);
continue;
End;
if children[i]['type'] = 'pcdata' then
child.SetValue(children[i]['value']);
else
class(xlsxXml).UpdateNode(child, children[i]['attributes'], children[i]['children']);
class(TSXml).UpdateNode(child, children[i]['attributes'], children[i]['children']);
End;
End;
@@ -166,7 +172,7 @@ Type xlsxXml = Class
End;
node := node.NextElement();
End;
return array(rID, findtarget);
return array(rID, findtarget, i);
End;
class Function FindRelationship(xmlfile, rid);
@@ -180,6 +186,14 @@ Type xlsxXml = Class
return nil;
End;
class Function FindRelationshipTarget(xmlfile, rid);
Begin
node := class(TSXml).FindRelationship(xmlfile, rid);
if ifObj(node) then
return node.GetAttribute('Target');
return nil;
End;
class Function AddRelationshipRid(xmlfile, target, type, rid, targetMode);
Begin
node := xmlfile.FirstChildElement('Relationships').InsertEndChild('element', 'Relationship');
@@ -247,8 +261,8 @@ Type xlsxXml = Class
class Function GetWorkSheetPrevNode(workNode, nodeName);
Begin
order_arr := array('dimension', 'sheetViews', 'sheetFormatPr', 'cols', 'sheetData', 'phoneticPr',
'pageMargins', 'headerFooter', 'pageSetup', 'rowBreaks', 'colBreaks', 'drawing', 'legacyDrawing', 'picture');
order_arr := array('dimension', 'sheetPr', 'sheetViews', 'sheetFormatPr', 'cols', 'sheetData', 'sheetProtection', 'mergeCells', 'phoneticPr',
'hyperlinks', 'pageMargins', 'headerFooter', 'pageSetup', 'rowBreaks', 'colBreaks', 'drawing', 'legacyDrawing', 'picture');
for i:=0 to length(order_arr)-1 do
begin
if order_arr[i] = nodeName then return prev;
@@ -257,6 +271,30 @@ Type xlsxXml = Class
else prev := ifObj(current) ? current : prev;
end
End
class Function GetWorkBookPrevNode(workNode, nodeName);
Begin
order_arr := array('fileVersion', 'workbookPr', 'bookViews');
for i:=0 to length(order_arr)-1 do
begin
if order_arr[i] = nodeName then return prev;
current := workNode.FirstChild(order_arr[i]);
if i = 0 then prev := current;
else prev := ifObj(current) ? current : prev;
end
End
class Function GetWorkSheetNode(workNode, nodeName);
Begin
node := workNode.FirstChildElement(nodeName);
if not ifObj(node) then
begin
prev_node := class(TSXml).GetWorkSheetPrevNode(workNode, nodeName);
if ifObj(prev_node) then node := workNode.InsertAfterChild(prev_node, 'element', nodeName);
else node := workNode.InsertFirstChild('element', nodeName);
end
return node;
End
class Function GetDatetimeStr(v);
Begin
@@ -303,6 +341,26 @@ Type xlsxXml = Class
r1.rFont.cs := _cp(r1.rFont.cs, r2.rFont.cs);
End;
End;
class Function CodePage(zw);
Begin
TOfficeApi().CodePage(zw);
End;
class Function IsUtf8();
Begin
return TOfficeApi().IsUtf8();
End;
class Function Utf8ToCurCodePage(str);
Begin
return TOfficeApi().Utf8ToCurCodePage(str);
End;
class Function CurCodePageToUtf8(str);
Begin
return TOfficeApi().CurCodePageToUtf8(str);
End;
//字体属性
class Function ReadRprFormat(node);
@@ -350,6 +408,7 @@ Type xlsxXml = Class
class Function SafeStrToIntDef(s, defaultV);
Begin
if ifnumber(s) then return integer(s);
if not ifstring(s) then
return defaultV;
return StrToIntDef(s, defaultV);
+24 -16
View File
@@ -2,43 +2,49 @@ Type TDocxChart = Class(TSChart)
///缺省构造函数
Function Create(docx, chartData); overload;
Begin
docx_ := docx;
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);
chartId_ := 1 + vselect countof( ['FileName'] ) from docx.Zip().Files() where AnsiStartsText('word/charts/chart', ['FileName']) end;
targetFileName := 'charts/chart' $ chartId_ $ '.xml';
chartFile := 'word/' + targetFileName;
chartFileName_ := chartFile;
docx.Zip().Add(chartFile, GetDefaultXml());
xmlObj_ := docx.Zip().Get(chartFile);
if not chartData_.DisableExcel and istable(chartData.Series) and istable(chartData.Series[0]['Categories']) and istable(chartData.Series[0]['Values']) then Begin
chartData_.NewExcelFile();
End;
Apply(xmlObj_);
chartData_.AddExcelFile(docx, xmlObj_, chartId_);//添加excel数据文件
//Relationship
relsObj := docx.ZipObject().Get('word/_rels/document.xml.rels');
[rId_, target] := class(xlsxXml).FindRelationshipRid(relsObj, '');
relsObj := docx.Zip().Get('word/_rels/document.xml.rels');
[rId_, target] := class(TSXml).FindRelationshipRid(relsObj, '');
rId_ ++;
class(xlsxXml).AddRelationshipRid(relsObj, '/' + chartFile, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_);
class(TSXml).AddRelationshipRid(relsObj, targetFileName, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' $ rId_);
//Content_Types
contentType := docx.ZipObject().Get('[Content_Types].xml');
class(xlsxXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
contentType := docx.Zip().Get('[Content_Types].xml');
class(TSXml).AddOverrideContentType(contentType, '/' + chartFile, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
End;
Function GetInnerXml();
Begin
ETU := 360045;//1cm单位
return fmt('<w:r>
return format('<w:r>
<w:drawing>
<wp:inline>
<wp:extent cx="{}" cy="{}"/>
<wp:extent cx="%d" cy="%d"/>
<wp:effectExtent l="0" t="0" r="19050" b="19050"/>
<wp:docPr id="{}" name="{}"/>
<wp:docPr id="%d" name="%s"/>
<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"/>
<c:chart xmlns:c="http://schemas.openxmlformats.org/drawingml/2006/chart" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId%d"/>
</a:graphicData>
</a:graphic>
</wp:inline>
</w:drawing>
</w:r>', integer(chartData_.Width * ETU), integer(chartData_.Height * ETU), chartId_, chartData_.Name, rId_);
</w:r>', integer(chartData_.Width * ETU), integer(chartData_.Height * ETU), docx_.GetDocPrId(), class(TSXml).CurCodePageToUtf8(chartData_.Name), rId_);
End;
Function IsWord();override;
@@ -46,6 +52,8 @@ Type TDocxChart = Class(TSChart)
return true;
End;
docx_;
chartId_;
rId_;
xmlObj_;
End;
+450
View File
@@ -0,0 +1,450 @@
Type TDocxCopy = class
Function Create(oldObj, newObj)
Begin
old_docx_obj_ := oldObj;
new_docx_obj_ := newObj;
copy_table_ := array();
copy_paragraph_ := array();
copy_drawing_ := array();
style_copy_obj_ := new TDocxStyleCopy(oldObj.StyleObject(), newObj.StyleObject());
number_copy_obj_ := new TDocxNumberCopy(oldObj, newObj);
End;
Function Init();
Begin
style_copy_obj_.Init();
End;
///从posOpt位置开始复制word
///posOpt: 段落位置,0 在DOCX文件开头;-1 文件尾;N 在第N段之后;XmlNode节点对象或DocObject对象 在posOpt之后新添加图片
Function Copy(posOpt);
Begin
// 复制所有的样式
style_copy_obj_.CopyStyle();
parts := new_docx_obj_.Body().Parts();
pos := old_docx_obj_.GetPosNode(posOpt);
for i:=0 to length(parts)-1 do
begin
case GetPartType(parts[i]) of
0: pos := CopyParagraph(parts[i], pos);
1: pos := CopyDrawing(parts[i], pos);
2: pos := CopyTable(parts[i], pos);
end;
end
End;
Function CopyParagraph(obj, pos);
Begin
paragraph := old_docx_obj_.Body().CopyWp(obj, pos);
SetParagraphInfo(paragraph);
copy_paragraph_[length(copy_paragraph_)] := paragraph;
return paragraph;
End;
Function CopyDrawing(obj, pos);
Begin
paragraph := old_docx_obj_.Body().CopyWp(obj, pos);
SetDrawingInfo(paragraph);
copy_drawing_[length(copy_drawing_)] := paragraph;
return paragraph;
End;
Function CopyTable(obj, pos);
Begin
table := old_docx_obj_.Body().CopyWtbl(obj, pos);
SetTableInfo(table);
copy_table_[length(copy_table_)] := table;
return table;
End;
Function GetCopiedTable();
Begin
return copy_table_;
End;
Function GetCopiedParagraph();
Begin
return copy_paragraph_;
End;
Function GetCopiedDrawing();
Begin
return copy_drawing_;
End;
private
Function DeleteComment(paragraph);
Begin
node := paragraph.node_.FirstChildElement('w:commentRangeStart');
while ifObj(node) do
begin
name := node.GetName();
if name = "w:commentRangeStart" or name = "w:commentRangeEnd" then
begin
delete_node := node;
node := node.NextElement();
paragraph.node_.DeleteChild(delete_node);
if node.FirstChildElement('w:commentReference') then
begin
delete_node := node;
node := node.NextElement();
paragraph.node_.DeleteChild(delete_node);
end
end
else begin
node := node.NextElement();
end
end
End;
Function SetPic(node);
Begin
// 获取新文件的图片
rembed := node.GetAttribute('r:embed');
rels := new_docx_obj_.Zip().Get('word/_rels/document.xml.rels');
target := class(TSXml).FindRelationshipTarget(rels, rembed);
image_file := new_docx_obj_.Zip().Get('word/' $ target).Data();
// 比较新文件的图片在旧文件中是否存在
zip := old_docx_obj_.Zip();
files := sselect ['FileName'] from zip.Files() where AnsiStartsText('word/media/image', ['FileName']) end;
for i:=0 to length(files)-1 do Begin
if zip.Diff(files[i], image_file) = 0 then Begin
prefix := ReplaceStr(files[i], 'word/', '');
[maxRid, imageFile, rid] := class(TSXml).FindRelationshipRid(xml, prefix);
End;
End;
xml := zip.Get('word/_rels/document.xml.rels');
if rid = 0 then
begin
image_cnt := length(files) + 1;
if ParseRegExpr("\\w+$", target, "", result, Mpos, Mlen) then
begin
postfix := result[0][0];
image_path := "media/image" $ image_cnt $ '.' $ postfix;
[rid, tar] := class(TSXml).FindRelationshipRid(xml, '');
rid ++;
class(TSXml).AddRelationshipRid(xml, image_path, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid);
zip.Add('word/' + image_path, image_file);
contentXml := zip.Get('[Content_Types].xml');
class(TSXml).AddDefaultContentType(contentXml, postfix, 'image/' $ postfix);
node.SetAttribute('r:embed', 'rId' $ rid);
end
end
End;
Function SetChart(node);
Begin
rid := node.GetAttribute('r:id');
rels := new_docx_obj_.Zip().Get('word/_rels/document.xml.rels');
target := class(TSXml).FindRelationshipTarget(rels, rid);
new_zip := new_docx_obj_.Zip();
chart_file := new_zip.Get('word/' $ target);
// 复制charN.xml
zip := old_docx_obj_.Zip();
files := sselect ['FileName'] from zip.Files() where AnsiStartsText('word/charts/chart', ['FileName']) end;
new_chart_file := "charts/chart" $ (length(files) + 1) $ ".xml";
xml := zip.Get('word/_rels/document.xml.rels');
[new_rid, tar] := class(TSXml).FindRelationshipRid(xml, '');
new_rid++;
class(TSXml).AddRelationshipRid(xml, new_chart_file, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart", 'rId' $ new_rid);
zip.Add('word/' + new_chart_file, chart_file.Data());
contentXml := zip.Get('[Content_Types].xml');
class(TSXml).AddOverrideContentType(contentXml, '/word/' + new_chart_file, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
node.SetAttribute('r:id', 'rId' $ new_rid);
// 复制charN.xml.rels
chart_rels := "word/charts/_rels" + target[pos('/', target):] $ ".rels";
chart_rels_xml := new_zip.Get(chart_rels);
if ifObj(chart_rels_xml) then
begin
zip.Add('word/charts/_rels/chart' $ (length(files) + 1) $ ".xml.rels", chart_rels_xml.Data());
relationship := chart_rels_xml.FirstChildElement('Relationships').FirstChildElement('Relationship');
while ifObj(relationship) do
begin
target := relationship.GetAttribute('Target');
target_path := AnsiReplaceText(target, '..', 'word');
file := new_zip.Get(target_path);
if ifObj(file) then
begin
[new_file, filetype] := GetNewTargetFileName(zip, target_path);
zip.Add(new_file, file.Data());
if filetype then Class(TSXml).AddDefaultContentType(contentXml, filetype[2:], 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
end
relationship := relationship.NextElement();
end;
end
End;
Function GetNewTargetFileName(zip, fileName);
Begin
files := zip.Files()[:, 'FileName'];
ret := ParseRegExpr("(.*/)(\\w+)(\.\\w+)$", fileName, "", result, Mpos, Mlen);
count := 0;
while fileName in files do
begin
if ret then
fileName := result[0][1] $ result[0][2] $ "tinysoft" $ count $ result[0][3];
else fileName := fileName $ "tinysoft" $ count;
count++;
end
if ret then filetype := result[0][3];
return array(fileName, filetype);
End;
Function SetDrawingInfo(drawing);
Begin
graphic_node := class(TSXml).GetNode(drawing.node_,'w:r/w:drawing/wp:inline/a:graphic/a:graphicData');
if ifObj(graphic_node) then
begin
node := class(TSXml).GetNode(graphic_node,'pic:pic/pic:blipFill/a:blip');
if ifObj(node) then SetPic(node);
node := class(TSXml).GetNode(graphic_node, 'c:chart');
if ifObj(node) then SetChart(node);
end;
End;
Function SetParagraphInfo(paragraph);
Begin
style := class(TSXml).GetNode(paragraph.node_, 'w:pPr/w:pStyle');
if ifObj(style) then
begin
styleid := style.GetAttribute('w:val');
new_id := style_copy_obj_.GetStyleNewId(styleid);
if new_id then style.SetAttribute('w:val', new_id);
end
numpr := class(TSXml).GetNode(paragraph.node_, 'w:pPr/w:numPr/w:numId');
if ifObj(numpr) then
begin
id := numpr.GetAttribute('w:val');
numberid := number_copy_obj_.CopyNumbering(id);
numpr.SetAttribute('w:val', id);
end
DeleteComment(paragraph); // 删除批注
End;
Function SetTableInfo(table);
Begin
style := class(TSXml).GetNode(table.node_, 'w:tblPr/w:tblStyle');
if ifObj(style) then
begin
id := style.GetAttribute('w:val');
new_id := style_copy_obj_.GetStyleNewId(id);
if new_id then style.SetAttribute('w:val', new_id);
end
col := table.Cols();
row := table.Rows();
for r:=1 to row do
begin
for c:=1 to col do
begin
cell := table.Cell(r, c);
if not cell then continue;
node := cell.node_;
if (tbl := node.FirstChildElement('w:tbl')) then
begin
obj := TOfficeObj('TTable');
obj.Init(tbl);
SetTableInfo(obj);
end
else if (p := node.FirstChildElement('w:p')) then
begin
draw := class(TSXml).GetNode(p, 'w:r/w:drawing');
if ifObj(draw) then
begin
obj := TOfficeObj('TPicture');
obj.Init(p);
SetDrawingInfo(obj);
end
else begin
obj := TOfficeObj('TParagraph');
obj.Init(p);
SetParagraphInfo(obj);
end
end
end
end
End;
/// 普通段落: 0
/// 图片段落: 1
/// 表格: 2
/// 其他类型暂不复制
Function GetPartType(part);
Begin
name := part.name_;
case name of
'w:p':
begin
if class(TSXml).GetNode(part.node_, 'w:r/w:drawing') then return 1;
return 0;
end
'w:tbl':
return 2;
else
return -1;
end
End;
private
old_docx_obj_;
new_docx_obj_;
style_copy_obj_;
number_copy_obj_;
copy_table_;
copy_paragraph_;
copy_drawing_;
End;
Type TDocxStyleCopy = class
Function Create(oldObj, newObj);
Begin
old_style_obj_ := oldObj;
new_style_obj_ := newObj;
style_id_map_ := array();
style_name_map_ := array();
style_id_map2_ := array();
style_name_map2_ := array();
id_map_ := array();
End;
Function Init();
Begin
id_styles := new_style_obj_.Styles();
for id, obj in id_styles do
begin
new_obj := obj;
id_map_[id] := new_obj;
SetId(new_obj, id);
SetName(new_obj);
end
End;
Function CopyStyle();
Begin
for id, obj in id_map_ do
begin
SetBasedOn(obj);
SetLink(obj);
old_style_obj_.CopyStyle(obj);
end;
End;
Function GetStyleNewId(oldId)
Begin
if ifnumber(oldId) then oldId := tostring(oldId);
return style_id_map_[oldId];
End;
private
Function SetId(obj, id);
Begin
new_id := GetNewId(id);
obj.node_.SetAttribute('w:styleId', new_id);
style_id_map_[id] := new_id;
style_id_map2_[new_id] := id;
End;
Function SetName(obj);
Begin
name_node := obj.node_.FirstChildElement('w:name');
name := name_node.GetAttribute('w:val');
new_name := GetNewName(name);
name_node.SetAttribute('w:val', new_name);
style_name_map_[name] := new_name;
style_name_map2_[new_name] := name;
End;
Function SetBasedOn(obj);
Begin
basedon := obj.node_.FirstChildElement('w:basedOn');
if ifObj(basedon) then
begin
val := basedon.GetAttribute('w:val');
if style_id_map_[val] then basedOn.SetAttribute('w:val', style_id_map_[val]);
end
End;
Function SetLink(obj);
Begin
link := obj.node_.FirstChildElement('w:link');
if ifObj(link) then
begin
val := link.GetAttribute('w:val');
if style_id_map_[val] then link.SetAttribute('w:val', style_id_map_[val]);
end
End;
Function GetNewName(name);
Begin
new_name := name;
count := 0;
while ifObj(old_style_obj_.GetStyle(new_name)) or style_name_map2_[new_name] do
new_name := new_name $ count++;
return new_name;
End;
Function GetNewId(id);
Begin
new_id := id;
count := 0;
while ifObj(old_style_obj_.GetStyleById(new_id)) or style_id_map2_[new_id] do
new_id := new_id $ count++;
return new_id;
End;
private
old_style_obj_;
new_style_obj_;
style_id_map_; // [old_id: new_id];
style_name_map_; // [old_name: new_name];
style_id_map2_; // [new_id: old_id];
style_name_map2_; // [old_name: new_name];
id_map_; // [id: styleobj]
End;
Type TDocxNumberCopy = class
Function Create(oldObj, newObj);
Begin
numberingxml := newObj.Zip().Get('word/numbering.xml');
if ifObj(numberingxml) then
begin
old_number_obj_ := oldObj.NumberingObject();
new_number_obj_ := newObj.NumberingObject();
end
else begin
old_number_obj_ := nil;
new_number_obj_ := nil;
end
id_map_ := array();
End;
Function CopyNumbering(number);
Begin
if ifObj(old_number_obj_) and ifObj(new_number_obj_) then
begin
if (obj := new_number_obj_.NumberStyle(number)) and not id_map_[number] then
begin
number_obj := old_number_obj_.CopyNumber(obj);
id_map_[number] := number_obj;
return number_obj;
end
end;
End;
private
old_number_obj_;
new_number_obj_;
id_map_; // [id: styleobj]
End;
+37 -24
View File
@@ -3,7 +3,7 @@ Type TDocxStyles = Class
Function Create(docx);
Begin
docx_ := docx;
stylesXml_ := docx.ZipObject().Get('word/styles.xml');
stylesXml_ := docx.Zip().Get('word/styles.xml');
idMap_ := array();
nameMap_ := array();
maxStyleId_ := 1;
@@ -21,13 +21,13 @@ Type TDocxStyles = Class
_addStyle(o);
node := node.NextElement('w:style');
End;
pNode := class(xlsxXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault');
pNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:pPrDefault');
if ifObj(pNode) then
defaultPpr_ := Class(xlsxXml).ReadPprFormat(pNode);
defaultPpr_ := Class(TSXml).ReadPprFormat(pNode);
rNode := class(xlsxXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault');
rNode := class(TSXml).GetNode(stylesNode, 'w:docDefaults/w:rPrDefault');
if ifObj(rNode) then
defaultRpr_ := Class(xlsxXml).ReadRprFormat(rNode);
defaultRpr_ := Class(TSXml).ReadRprFormat(rNode);
End;
End;
End;
@@ -38,7 +38,7 @@ Type TDocxStyles = Class
Function Default(styleType);
Begin
for k, obj in idMap_ do Begin
if obj.wType_ = styleType then Begin
if obj.wType = styleType then Begin
v := obj.node_.GetAttribute('w:default');
if v <> '1' then
return obj;
@@ -52,7 +52,7 @@ Type TDocxStyles = Class
///返回:TDocxStyle对象
Function GetStyle(name);
Begin
return nameMap_[ lowercase(name) ];
return nameMap_[ class(TSXml).CurCodePageToUtf8(lowercase(name)) ];
End;
///返回指定StyleId名称的TDocxStyle
@@ -60,11 +60,12 @@ Type TDocxStyles = Class
///返回:TDocxStyle对象
Function GetStyleById(id);
Begin
return idMap_[ id ];
newid := ifnumber(id) ? tostring(id) : id;
return idMap_[ newid ];
End;
///返回全部LatentStyles对象列表
///返回:TDocxStyle对象列表
//返回全部LatentStyles对象列表
//返回:TDocxStyle对象列表
Function LatentStyles();
Begin
r := array();
@@ -76,7 +77,6 @@ Type TDocxStyles = Class
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;
@@ -134,6 +134,23 @@ Type TDocxStyles = Class
return nil;
End;
///复制样式
///newstyle:样式节点TDocxStyle对象
///返回:TDocxStyle对象
Function CopyStyle(newstyle);
Begin
if ifObj(newstyle) and ifObj(newstyle.node_) then Begin
node := stylesXml_.FirstChildElement('w:styles').InsertEndChild(newstyle.node_.Marshal()[0]);
obj := TOfficeObj('TDocxStyle');
obj.StyleId := node.GetAttribute('w:styleId');
obj.Name := node.FirstChildElement('w:name').GetAttribute('w:val');
obj.Init(node);
_addStyle(obj);
return obj;
End;
return nil;
End;
///插入新的LatentStyle段落样式
///oTDocxStyle对象
///返回:TDocxStyle对象
@@ -151,25 +168,21 @@ Type TDocxStyles = Class
///插入缺省的段落样式(Title、Heading1-9
///返回:TDocxStyle对象
Function AddDefaultStyle(path, Name);
Function AddDefaultStyle(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;
styleFname := 'wStyle/' + styleId + '.xml';
cStyleFname := 'wStyle/' + charId + '.xml';
xmlData := TOfficeTemplate(styleFname);
if ifnil(xmlData) then
return xmlData;
o := AddStyleByInnerXml(styleId, xmlData);
charStyle := idMap_[charId];
if not ifObj(charStyle) then Begin
if ReadFile(rwraw(), '', cStyleFname, 0, 100 * 1024, xmlData) then Begin
xmlData := TOfficeTemplate(cStyleFname);
if ifstring(xmlData) then Begin
AddStyleByInnerXml(charId, xmlData);
End;
End;
@@ -190,4 +203,4 @@ private
idMap_;
nameMap_;
maxStyleId_:integer;
End;
End;
+39 -30
View File
@@ -3,23 +3,19 @@ Type TNumbering = Class
Function Create(docx);
Begin
docx_ := docx;
numberingXml_ := docx.ZipObject().Get('word/numbering.xml');
numberingXml_ := docx.Zip().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);
xmlData := TOfficeTemplate('numbering/numbering.xml');
if ifString(xmlData) then Begin
docx.Zip().Add('word/numbering.xml', xmlData);
rels := 'word/_rels/document.xml.rels';
relsObj := docx.ZipObject().Get(rels);
[rId, target] := class(xlsxXml).FindRelationshipRid(relsObj, '');
relsObj := docx.Zip().Get(rels);
[rId, target] := class(TSXml).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');
class(TSXml).AddRelationshipRid(relsObj, 'numbering.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering', 'rId' $ rId);
contentType := docx.Zip().Get('[Content_Types].xml');
class(TSXml).AddOverrideContentType(contentType, '/word/numbering.xml', 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml');
numberingXml_ := docx.Zip().Get('word/numbering.xml');
End;
End;
maxAbstractNumId_ := 0;
@@ -80,12 +76,25 @@ Type TNumbering = Class
numIdMap_[''$num.numId] := num.abstractNumId;
return num.numId;
End;
///复制number样式
///numberObj: 样式xmlNode
Function CopyNumber(numberObj);
Begin
obj := AddStyle(numberObj, true);
num := TOfficeObj('TNumber');
num.numId := maxNumId_++;
num.abstractNumId := obj.Id;
numberingXml_.FirstChildElement('w:numbering').InsertEndChild(num.Marshal());
numIdMap_[''$num.numId] := num.abstractNumId;
return num.numId;
End;
///根据numId获取TNumStyle对象(已存在)
///返回:TNumStyle对象
Function NumberStyle(numId);overload;
Begin
abstractNumId := numIdMap_[numId];
abstractNumId := numIdMap_['' $ numId];
if abstractNumId then Begin
return numStyleObjs_[abstractNumId];
End;
@@ -152,14 +161,20 @@ Type TNumbering = Class
///新添加项目样式
///oTNumStyle对象
///返回:TNumStyle对象
Function AddStyle(o);
Function AddStyle(o, flag);
Begin
if ifObj(o) then Begin
o.abstractNumId := maxAbstractNumId_++;
if flag then
begin
o.node_.SetAttribute('w:abstractNumId', o.abstractNumId);
marshal := o.node_.Marshal()[0];
end
else marshal := o.Marshal();
if ifObj(lastAbstractNumStyle_) then
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, o.Marshal());
node := numberingXml_.FirstChildElement('w:numbering').InsertAfterChild(lastAbstractNumStyle_, marshal);
else
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(o.Marshal());
node := numberingXml_.FirstChildElement('w:numbering').InsertFirstChild(marshal);
lastAbstractNumStyle_ := node;
o := TOfficeObj('TNumStyle');
o.Init(node);
@@ -173,14 +188,8 @@ Type TNumbering = Class
//系统默认支持的项目编号样式
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
xmlData := TOfficeTemplate('numbering/' + name + '.xml');
if not ifString(xmlData) then
return nil;
return AddStyleByInnerXml(xmlData);
End;
@@ -208,15 +217,15 @@ Type TNumbering = Class
//生成nsid随机数->转16进制
Function _setNsId(o);
Begin
v := RandomRange(1000000000,2000000000);
id := xlsx_call('tohex',v);
v := Integer(RandomRange(1000000000,2000000000));
id := inttohex(v, 1);
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']);
class(TSXml).UpdateNode(o.node_, arr['attributes'], arr['children']);
End;
private
docx_;
@@ -232,4 +241,4 @@ private
bullet_;
numIdMap_;
hash_;
End;
End;
+72
View File
@@ -0,0 +1,72 @@
Type TSTag = Class
///缺省构造函数
Function Create(); overload;
Begin
End;
Function Init(tagName, attribute, r);
Begin
tagName_ := tagName;
attribute_ := attribute;
runArr_ := r;
range_ := nil;
map_ := nil;
End;
Property Range read readRange;
Function readRange();
Begin
if ifNil(range_) then Begin
range_ := TOfficeObj('TRange');
range_.Init(runArr_);
End;
return range_;
End;
///获取TAG中属性 [font size=12]...[/font]
/// tag.GetAttribute('size');
///返回:string
Function GetAttribute(key);
Begin
if not ifArray(map_) then Begin
map_ := array();
//println('attribute={}',attribute_);
arr := Str2Array(attribute_, ' ');
for i := 0 to length(arr)-1 do Begin
kv := Str2Array(arr[i], '=');
if length(kv)=2 then
map_[kv[0]] := kv[1];
End;
End;
return map_[key];
End;
Function Apply(); virtual;
Begin
case tagName_ of
'add':
_add();
'del':
_del();
End;
End;
Function _add();
Begin
Range.Font.Size := 40;
Range.Font.Color := 'FF0000';
Range.Font.Bold := true;
Range.Apply();
End;
Function _del();
Begin
Range.Clear();
End;
tagName_:string;
attribute_:string;
runArr_;
range_;
map_;
End;
@@ -0,0 +1,297 @@
Unit TSWordTemplateMethods;
Interface
Function ExcelChartCopyPic(excelFileName, excelSheetName, chartName, width, height);
Function WordAddOleObjectFromFile(fileName, width, height);
Function WordBr();
Function WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
Function WordGetCurrentDocument();
Function WordGetCurrentRange();
Function WordGetFont(prop, value);
Function WordGetLastRange();
Function WordGetLastShape();
Function WordGetLastTable();
Function WordGetLastTableCellProp(row, col, name, value);
Function WordGetLastTableProp(name, value);
Function WordLastTableMerge(row1, col1, row2, col2);
Function WordSetCurrentRange(range);
Function WordSetFont(prop, value);
Function WordSetLastTableCellProp(row, col, name, value);
Function WordSetLastTableProp(name, value);
Function WordSetRangeProp(name, value);
Function WordTemplate(data, template, fileName);
Function WordWrite();
Function WordWritePicFromFile(fileName);
Function WordWriteTable(table, writeIntIndex, writeIntTitle, incIntIndex);
Implementation
Function ExcelChartCopyPic(excelFileName, excelSheetName, chartName, width, height);
Begin
docx := TOfficeApi().GetDocument();
chart := docx.CopyExcelChart(excelFileName, excelSheetName, chartName, width, height, TOfficeApi().GetCurrentPosition());
return ifObj(chart);
End;
Function WordBr();
Begin
TOfficeApi().GetDocument().AddLineBreak(TOfficeApi().Get('CurrentPosition'));
End;
Function WordCopyFromExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol);
Begin
excel := new TSXlsFile();
[err, msg] := excel.OpenFile('', excelFileName);
if err then return false;
total_row := excel.TotalRows(excelSheetName);
total_col := excel.TotalCols(excelSheetName);
if not total_row or not total_col then return false;
if ifnil(startRow) then
startRow := 1;
if ifnil(startCol) then
startCol := 1;
if ifnil(endRow) then
endRow := total_row;
if ifnil(endCol) then
endCol := total_col;
data := excel.GetTable(excelSheetName,
CoordinatesToCellName(startCol, startRow),
CoordinatesToCellName(endCol, endRow),
false,
false,
false);
if length(data) = 0 then return false;
//println('data={}',data);
docx := TOfficeApi().GetDocument();
tbl := docx.CreateTable(data, false, false);
tbl.Format.Borders.Top.Val := 'dashed';
tbl.Format.Borders.Left.Val := 'dashed';
tbl.Format.Borders.Bottom.Val := 'dashed';
tbl.Format.Borders.Right.Val := 'dashed';
tbl.Format.Borders.InsideH.Val := 'dashed';
tbl.Format.Borders.InsideV.Val := 'dashed';
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
End;
Function WordGetCurrentDocument();
Begin
return TOfficeApi().GetDocument();
End;
Function WordGetCurrentRange();
Begin
return TOfficeApi().GetCurrentPosition();
End;
Function WordGetFont(prop, value);
Begin
crun := TOfficeApi().GetCurrentRun();
node := crun.Node().FirstChildElement('w:rPr');
rPr := TOfficeObj('TwrPr');
rPr.InitRootNode(node);
value := rPr.Value(prop);
if not ifnil(value) then return true;
return false;
End;
Function WordGetLastShape();
Begin
node := TOfficeApi().Get('CurrentShape');
if not ifObj(node) then return nil;
uri := 'w:r/w:drawing/wp:inline/a:graphic/a:graphicData/c:chart';
cNode := class(TSXml).GetNode(node, uri);
if ifObj(cNode) then Begin
chart := TOfficeObj('TChart');
chart.Init(TOfficeApi().GetDocument(), node, cNode);
return chart;
End;
pic := TOfficeObj('TPicture');
pic.Init(node);
return pic;
End;
Function WordGetLastRange();
Begin
return TOfficeApi().GetCurrentPosition();
End;
Function WordGetLastTable();
Begin
return TOfficeApi().Get('CurrentTable');
End;
Function WordGetLastTableCellProp(row, col, name, value);
Begin
table_node := TOfficeApi().Get('CurrentTable');
if ifnil(table_node) then return false;
table := TOfficeObj("TTable");
table.Init(table_node);
table_cell := table.Cell(row, col);
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'return table_cell.Format.' $ name_ $ '"' $ value $ '"';
value := eval(&str);
return true;
End;
Function WordGetLastTableProp(name, value);
Begin
table_node := TOfficeApi().Get('CurrentTable');
if ifnil(table_node) then return false;
table := TOfficeObj("TTable");
table.Init(table_node);
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'return table.Format.' $ name_ $ '"' $ value $ '"';
value := eval(&str);
return true;
End;
Function WordLastTableMerge(row1, col1, row2, col2);
Begin
table_node := TOfficeApi().Get('CurrentTable');
if ifnil(table_node) then return false;
table := TOfficeObj("TTable");
table.Init(table_node);
[err1, beg_cell] := CoordinatesToCellName(col1, row1);
[err2, end_cell] := CoordinatesToCellName(col2, row2);
if err1 or err2 then return false;
table.Merge(beg_cell, end_cell, false);
return true;
End;
Function WordSetCurrentRange(range);
Begin
TOfficeApi().Set('CurrentPosition', range);
End;
Function WordSetFont(prop, value);
Begin
run := TOfficeApi().GetCurrentRun();
str := 'run.font.' $ prop $ ' := ' $ '"' $ value $ '"';
eval(&str);
run.Apply();
return true;
End;
Function WordSetLastTableCellProp(row, col, name, value);
Begin
table := TOfficeApi().Get('CurrentTable');
if ifnil(table) then return false;
table_cell := table.Cell(row, col);
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'table_cell.Format.' $ name_ $ ' := ';
if ifstring(value) then
str += '"' $ value $ '"';
else
str := str $ value;
eval(&str);
return true;
End;
Function WordSetLastTableProp(name, value);
Begin
table := TOfficeApi().Get('CurrentTable');
if ifnil(table) then return false;
ctr := _wordCompTable();
name_ := ctr[lowercase(name)];
if ifnil(name_) then name_ := name;
str := 'table.Format.' $ name_ $ ' := ';
if ifstring(value) then
str += '"' $ value $ '"';
else
str := str $ value;
eval(&str);
TOfficeApi().Set('CurrentTable', table);
return true;
End;
Function WordSetRangeProp(name, value);
Begin
cur := TOfficeApi().GetCurrentPosition();
if ifnil(cur) then return nil;
End;
Function WordTemplate(data, template, fileName);
Begin
setsysparam('data', data);
docx := new TSDocxFile();
[err, msg] := docx.OpenFile('', template);
if err then return false;
docx.ExecInnerTSL();
if ifstring(fileName) then
begin
[err, msg] := docx.SaveAs('', fileName);
if err then return false;
end
return true;
End;
Function WordWrite();
Begin
docx := TOfficeApi().GetDocument();
curParagraph := TOfficeApi().GetCurrentParagraph();
curRun := TOfficeApi().GetCurrentRun();
for i:=1 to PARAMCOUNT do Begin
argv := params[i];
if ifstring( argv ) then
curRun.AddText( argv );
else if ifnumber(argv) then
curRun.AddText('' $ argv);
else if ifarray(argv) then Begin
tbl := docx.CreateTable(argv, false, false);
tbl := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
End
End
End;
Function WordWritePicFromFile(fileName);
Begin
file_size := fileSize('', fileName);
flag := readfile(rwbinary(), '', fileName, 0, file_size, data);
if not flag then return false;
picture := TOfficeObj('TPicture');
picture.Image := data;
docx := TOfficeApi().GetDocument();
docx.AddPicture(picture, TOfficeApi().GetCurrentPosition());
return true;
End;
Function WordWriteTable(table, writeIntIndex, writeIntTitle, incIntIndex);
Begin
docx := TOfficeApi().GetDocument();
tbl := docx.CreateTable(table, true, writeIntIndex);
table := docx.InsertTable(tbl, TOfficeApi().GetCurrentPosition());
return true;
End;
Function _wordCompTable();
Begin
return array(
'alignment': 'Alignment',
'shadingcolor': 'Shading.Color',
'style': 'StyleID',
'verticalalignment': 'Valign',
'width': 'Width',
);
End;
// TODO:尚未支持
Function WordAddOleObjectFromFile(fileName, width, height);
Begin
End;
Function WordCopyPicFormatExcel(excelFileName, excelSheetName, startRow, startCol, endRow, endCol, picType);
Begin
End;
Function WordGetRangeProp(name, value);
Begin
End;
Function WordLastTableSplit(row, col, rCnt, cCnt);
Begin
End;
End.
+100 -108
View File
@@ -12,38 +12,43 @@ Type TTableContent = class
impl_ := TOfficeObj('TTableContentImpl');
//_CheckNodes('endnotes.xml');
//_CheckNodes('footnotes.xml');
//contentType := docx.ZipObject().Get('[Content_Types].xml');
//class(xlsxXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf');
//contentType := docx.Zip().Get('[Content_Types].xml');
//class(TSXml).AddOverrideContentType(contentType, 'wmf', 'image/x-wmf');
End;
Function SetDefaultFormat();
Begin
defultFont := impl_.stdPr.rPr;
defultFont := impl_.sdtPr.rPr;
defultFont.rFont.cstheme := 'minorBidi';
defultFont.rFont.eastAsia := '宋体';
defultFont.rFont.hAnsi := '宋体';
defultFont.rFont.ascii := '宋体';
defultFont.rFont.XMLeastAsia := '宋体';
defultFont.rFont.XMLhAnsi := '宋体';
defultFont.rFont.XMLascii := '宋体';
//defultFont.kern := 2;
defultFont.Size := 21;
defultFont.Size := 21/2;
defultFont.SzCs := 24;
defultFont.Lang := 'en-US';
defultFont.bidi := 'ar-SA';
defultFont.eastAsia := 'zh-CN';
defultFormat := impl_.stdPr;
defultFont.Color := 'DBDBDB';
defultFormat := impl_.sdtPr;
defultFormat.ID := integer(time()*24*3600);
defultFormat.Color := 'DBDBDB';
//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;
//impl_.sdtEndPr.rPr.Size := 21;
//impl_.sdtEndPr.rPr.SzCs := 22;
impl_.sdtEndPr.rPr.Bold := true;
End;
///应用目录样式
Function Apply(); override;
Begin
arr := impl_.Marshal();
class(xlsxXml).UpdateNode(node_, arr['attributes'], arr['children']);
// sdtContent 不应该updateNode
tmp_impl := TOfficeObj('TTableContentImpl');
tmp_impl.sdtPr := impl_.sdtPr;
tmp_impl.sdtEndPr := impl_.sdtEndPr;
arr := tmp_impl.Marshal();
class(TSXml).UpdateNode(node_, arr['attributes'], arr['children']);
End;
///添加目录条目
@@ -67,10 +72,12 @@ Type TTableContent = class
mParagraph.pPr.RightIndent := 0;
mParagraph.pPr.LeftChars := 0;
mParagraph.pPr.LeftIndent := 0;
mParagraph.pPr.StyleID := _GetStyle('TOC');
mParagraph.Run.T := '目录';
mParagraph.Run.rPr.Name := '宋体';
mParagraph.Run.rPr.Size := 21;
mParagraph.Run.rPr.Bold := true;
mParagraph.Run.rPr.Lang := 'zh-CN';
//mParagraph.Run.rPr.SetName('宋体', true);
//mParagraph.Run.rPr.Size := 21/2;
//mParagraph.Run.rPr.Bold := true;
_AddStdContent(mParagraph);
goback := TOfficeObj('TParagraph');
@@ -78,13 +85,13 @@ Type TTableContent = class
goback.MarkStart.Name := '_GoBack';
goback.MarkStart.ID := id;
goback.MarkEnd.ID := id;
_AddStdContent(goback);
//_AddStdContent(goback);
//缺省目录,需要word或wps打开后,更新目录
_AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
//_AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
//自定义页码计算与word、wps有差异,不推荐使用
//_AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
_AddTableContent(posOpt, UpperHeadingLevel, LowerHeadingLevel);
End;
Function _AddDefaultTableContent(UpperHeadingLevel, LowerHeadingLevel);
@@ -122,7 +129,7 @@ Type TTableContent = class
//instrText
r2 := p.AddRun();
r2.instrTextSpace := 'preserve';
r2.instrText := 'TOC \\o \"' $ UpperHeadingLevel $ '-' $ LowerHeadingLevel $ '\" \\h \\u ';
r2.instrText := 'TOC \\o \"' $ UpperHeadingLevel $ '-' $ LowerHeadingLevel $ '\" \\h \\z \\u ';
//fldCharType
r3 := p.AddRun();
@@ -139,75 +146,74 @@ Type TTableContent = class
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
h := p.AddHyperLink();
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 := '宋体';
h.Anchor := bookmarke;
h.history := 1;
r1 := h.AddRun();
r1.rPr.StyleId := _GetStyle(level);
r1.rPr.noProof := true;
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';
if numStr <> '' then run_t := numStr + ' ' + r[i]['Text'];
else run_t := r[i]['Text'];
r1.SetText(run_t);
r2 := h.AddRun();
r2.rPr.noProof := true;
r2.rPr.WebHidden := true;
r2.Tab := true;
r3 := h.AddRun();
r3.rPr.noProof := true;
r3.rPr.WebHidden := true;
r3.fldCharType := 'begin';
//instrText
r10 := p.AddRun();
r10.instrTextSpace := 'preserve';
r10.instrText := ' PAGEREF ' $ bookmarke $ ' \\h ';
r4 := h.AddRun();
r4.rPr.noProof := true;
r4.rPr.WebHidden := true;
r4.instrTextSpace := 'preserve';
r4.instrText := ' PAGEREF ' $ bookmarke $ ' \\h ';
r5 := h.AddRun();
r5.rPr.noProof := true;
r5.rPr.WebHidden := true;
r5.Tab := true;
//fldCharType
r11 := p.AddRun();
r11.fldCharType := 'separate';
r6 := h.AddRun();
r6.rPr.noProof := true;
r6.rPr.WebHidden := true;
r6.fldCharType := 'separate';
//页码
r12 := p.AddRun();
r12.T := '' $ r[i]['pageNo'];
r7 := h.AddRun();
r7.T := 0;//'' $ 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;
r8 := h.AddRun();
r8.rPr.noProof := true;
r8.rPr.WebHidden := true;
r8.fldCharType := 'end';
_AddStdContent(p);
End;
p2 := TOfficeObj('TParagraph');
//p2.Format.SpaceAfter := 0;
run := p2.AddRun();
run.rPr.Bold := true;
run.rPr.noProof := true;
run.fldCharType := 'end';
_AddStdContent(p2);
End;
///更新目录
@@ -223,21 +229,21 @@ Type TTableContent = class
Property Format read readFormat;
Function readFormat();
Begin
return impl_.stdPr;
return impl_.sdtPr;
End;
Property EndFormat read readEndFormat;
Function readEndFormat();
Begin
return impl_.stdEndPr;
return impl_.sdtEndPr;
End;
Property Font read readFont;
Function readFont();
Begin
return impl_.stdPr.rPr;
return impl_.sdtPr.rPr;
End;
Function _AddStdContent(o);
Begin
impl_.SdtContent.NewChildNode( array("field":"", "name":"w:p", "obj":o, "attrEx":"", "nodeType":"") );
@@ -245,18 +251,10 @@ Type TTableContent = class
Function _GetStyle(level);
Begin
styleName := 'Tinysoft目录 ' $ (level + 1);
style := docx_.StyleObject().GetStyle(styleName);
styleName := ifstring(level) ? level : 'TOC' $ (level + 1);
style := docx_.StyleObject().GetStyleById(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));
style := docx_.StyleObject().AddDefaultStyle(styleName);
End;
return style.StyleId;
End;
@@ -272,33 +270,27 @@ Type TTableContent = class
Function _CheckNodes(name);
Begin
z := docx_.ZipObject();
z := docx_.Zip();
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;
xmlData := TOfficeTemplate(name);
if not ifString(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, target] := class(TSXml).FindRelationshipRid(relsObj, '');
rId ++;
if name = 'endnotes.xml' then Begin
class(xlsxXml).AddRelationshipRid(relsObj, name, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/endnotes', 'rId' $ rId);
class(TSXml).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');
class(TSXml).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);
class(TSXml).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');
class(TSXml).AddOverrideContentType(contentType, '/word/' + name, 'application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml');
End;
End;
End;
@@ -306,4 +298,4 @@ Type TTableContent = class
docx_;
node_;
impl_;
End;
End;
+1 -3
View File
@@ -2,10 +2,9 @@ Type docxDocument = Class
/// word/document.xml对象
///缺省构造函数
Function Create(z,xml); overload;
Function Create(z); overload;
Begin
zipfile_ := z;
xml_ := xml;
document_ := zipfile_.Get('word/document.xml');
root_ := document_.FirstChildElement('w:document');
bodyNode_ := root_.FirstChildElement('w:body');
@@ -44,7 +43,6 @@ Type docxDocument = Class
return bookmarkid_;
End;
private
xml_;
root_;//w:document
bodyNode_;//w:body
body_;
Binary file not shown.
Binary file not shown.
-36
View File
@@ -1,36 +0,0 @@
*如何读取属性值?
对象的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对象)。
@@ -1,17 +0,0 @@
<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>
@@ -1,17 +0,0 @@
<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>
@@ -1,17 +0,0 @@
<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>
@@ -1,17 +0,0 @@
<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>
@@ -1,17 +0,0 @@
<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>
@@ -1,17 +0,0 @@
<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>
@@ -1,17 +0,0 @@
<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>
@@ -1,113 +0,0 @@
<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>
@@ -1,271 +0,0 @@
<?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>
@@ -1,18 +0,0 @@
<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>
@@ -1,18 +0,0 @@
<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.

Before

Width:  |  Height:  |  Size: 3.5 KiB

@@ -1,23 +0,0 @@
<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>
@@ -1,15 +0,0 @@
<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>
@@ -1,24 +0,0 @@
<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>
@@ -1,15 +0,0 @@
<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>
@@ -1,22 +0,0 @@
<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>
@@ -1,13 +0,0 @@
<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>
@@ -1,25 +0,0 @@
<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>
@@ -1,16 +0,0 @@
<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>
@@ -1,21 +0,0 @@
<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>
@@ -1,12 +0,0 @@
<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>
@@ -1,23 +0,0 @@
<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>
@@ -1,14 +0,0 @@
<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>
@@ -1,23 +0,0 @@
<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>
@@ -1,14 +0,0 @@
<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>
@@ -1,23 +0,0 @@
<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>
@@ -1,14 +0,0 @@
<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>
@@ -1,25 +0,0 @@
<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>
@@ -1,16 +0,0 @@
<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>
@@ -1,24 +0,0 @@
<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>
@@ -1,15 +0,0 @@
<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>
+6 -6
View File
@@ -8,12 +8,12 @@ Type xlsxChart = Class(TSChart)
drawingRID_ := excel_.WorkBook().GetSheetDrawing(sheet);
drawingXmlObj_ := excel_.WorkBook().GetXmlFileObj('xl/drawings/drawing' $ drawingRID_ $ '.xml');
drawingRelsObj := excel_.WorkBook().GetDrawingRelsFile(drawingRID_);
[chartRid_, find] := class(xlsxXml).FindRelationshipRid(drawingRelsObj, '');
[chartRid_, find] := class(TSXml).FindRelationshipRid(drawingRelsObj, '');
chartRid_ ++;
class(xlsxXml).AddRelationshipRid(drawingRelsObj, '../charts/chart'+inttostr(chartId_)+'.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' + inttostr(chartRid_));
class(TSXml).AddRelationshipRid(drawingRelsObj, '../charts/chart'+inttostr(chartId_)+'.xml', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart', 'rId' + inttostr(chartRid_));
xlChartFileName_ := 'xl/charts/chart'+inttostr(chartId_)+'.xml';
content_xml := excel_.WorkBook().GetXmlFileObj(class(xlsxXml).GetFileName('Content_Types'));
class(xlsxXml).AddOverrideContentType(content_xml, '/' + xlChartFileName_, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddOverrideContentType(content_xml, '/' + xlChartFileName_, 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml');
End;
class Function NewObject(sheet, excel);
@@ -47,9 +47,9 @@ Type xlsxChart = Class(TSChart)
o.XTo.Row := row2;
o.XTo.RowOff := chartData.EndRowOff ? chartData.EndRowOff : 0;
o.GraphicFrame.macro := '';
//o.GraphicFrame.macro := '';
o.GraphicFrame.GraphicFramePr.Name := chartData.Name ? chartData.Name : 'Chart' + inttostr(chartId_);
o.GraphicFrame.GraphicFramePr.Id := class(xlsxXml).GetcNvPrID(drawingXmlObj_);
o.GraphicFrame.GraphicFramePr.Id := class(TSXml).GetcNvPrID(drawingXmlObj_);
o.GraphicFrame.GraphicFramePr.cNvGraphicFramePr := true;
o.GraphicFrame.XFrm.Off.X := 0;
+42 -20
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, class(xlsxXml).XmlHeader() + '<comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"></comments>');
excel_.Zip().Add(xlCommentFileName, class(TSXml).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,9 +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));
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');
content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddOverrideContentType(content_xml, '/' + xlCommentFileName, 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml');
class(TSXml).AddDefaultContentType(content_xml, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing');
sheetXml := excel_.WorkBook().GetSheetXmlfile(sheetName_).FirstChildElement('worksheet');
legacy := sheetXml.FirstChildElement('legacyDrawing');
@@ -60,6 +60,7 @@ xmlns:v="urn:schemas-microsoft-com:vml">
authors_[ author ] := i ++;
node := node.NextElement();
End;
initCommentObjs();
//println('sheet={},commentfile={},vmlfile={}',sheet, commentXmlFile_, drawingVML_);
End;
@@ -95,12 +96,13 @@ xmlns:v="urn:schemas-microsoft-com:vml">
commentObj.Font.Bold := nil;
commentObj.Space := 'preserve';
domData := comments.Marshal();
node := getComment(cell);
if ifObj(node) then
node := commentObjs_[cell];
if ifObj(node) then
node.DeleteChildren();
else
node := commentXmlFile_.FirstChildElement('comments').FirstChildElement('commentList').InsertEndChild('element', 'comment');
node.UnMarshal(domData);
commentObjs_[cell] := node;
//commentXmlFile_.print;
innerxml := '<v:shape id="_x0000_s1025" o:spt="202" type="#_x0000_t202" style="position:absolute;left:0pt;top:0pt;margin-left:59.85pt;margin-top:1.5pt;height:60pt;width:97.5pt;visibility:hidden;" fillcolor="#FFFFE1" filled="t" stroked="t" o:insetmode="auto" coordsize="21600,21600">
<v:path/>
@@ -122,18 +124,47 @@ xmlns:v="urn:schemas-microsoft-com:vml">
if ifObj(node) then Begin
[err, col, row] := excel_.CellNameToCoordinates(cell);
clientData := TOfficeObj('TClientData');
clientData.Anchor := fmt('{},23,{},0,{},{},{},5',col, row, 1+col+lineCount, colCount+col-1, 1+row+lineCount);
clientData.Anchor := format('%d,23,%d,0,%d,%d,%d,5',col, row, 1+col+lineCount, colCount+col-1, 1+row+lineCount);
clientData.Row := row - 1;
ClientData.Column := col - 1;
node.UnMarshal(clientData.Marshal());
commentObjs_[ length(commentObjs_) ] := array(cell, node);
//xmlObj.Print;
End;
End;
return 'ok';
End;
Function getComment(cell);
Function GetComment(cell);
Begin
o := commentObjs_[cell];
if not ifObj(o) then return array(nil, nil);
r_node := o.FirstChildElement('text').FirstChildElement('r');
author := r_node.FirstChildElement('t').GetText();
if length(author) > 1 then author := author[:length(author)-1];
r_node := r_node.NextElement();
comment := '';
while ifObj(r_node) do
begin
comment += r_node.FirstChildElement('t').GetText();
r_node := r_node.NextElement();
end
if length(comment) > 1 then comment := comment[2:];
return array(author, comment);
End;
Function RemoveComment(cell);
Begin
node := commentObjs_[cell];
if ifObj(node) then
begin
commentXmlFile_.FirstChildElement('comments').FirstChildElement('commentList').DeleteChild(node);
commentObjs_[cell] := nil;
end
End;
private
Function initCommentObjs();
Begin
if not ifarray(commentObjs_) then Begin
commentObjs_ := array();
@@ -143,21 +174,12 @@ xmlns:v="urn:schemas-microsoft-com:vml">
node := node.FirstChildElement('comment');
while ifObj(node) do Begin
ref := node.GetAttribute('ref');
commentObjs_[index++] := array(ref, node);
commentObjs_[ref] := node;
node := node.NextElement();
End;
End;
return vselect [1] from commentObjs_ where [0] = cell end;
End;
Function RemoveComment(cell);
Begin
node := getComment(cell);
if ifObj(node) then
commentXmlFile_.FirstChildElement('comments').DeleteChild(node);
return array(0, 'ok');
End;
private
authors_;
commentId_;
commentFileName_:string;//'../comments/comment1.xml'
+2 -2
View File
@@ -10,7 +10,7 @@ Type xlsxDocProps = Class
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']);
class(TSXml).UpdateNode(node, marshal['attributes'], marshal['children']);
End;
Function GetAppProps();
@@ -27,7 +27,7 @@ Type xlsxDocProps = Class
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']);
class(TSXml).UpdateNode(node, marshal['attributes'], marshal['children']);
End
Function GetCoreProps();
@@ -21,12 +21,14 @@ Type xlsxHeaderFooter = Class
node := xmlFile_.FirstChildElement('worksheet');
header_node := node.FirstChildElement('headerFooter');
if ifObj(header_node) then
node.DeleteChild(header_node);
page_node := node.FirstChildElement('pageMargins');
if ifObj(page_node) then
node.InsertAfterChild(page_node, headerFooter.Marshal());
else
node.InsertEndChild(headerFooter.Marshal());
begin
marshal := headerFooter.Marshal();
class(TSXml).UpdateNode(header_node, marshal['attributes'], marshal['children']);
end
else begin
prev_node := class(TSXml).GetWorkSheetPrevNode(node, 'headerFooter');
node.InsertAfterChild(prev_node, headerFooter.Marshal());
end
End
private
+44 -29
View File
@@ -12,50 +12,52 @@ Type xlsxHyperLink = Class
return new xlsxHyperLink(sheetname, file, xmlFile);
End;
Function SetCellHyperLink(axis, hyperlink);
Function SetCellHyperLink(axis, link);
Begin
hyperlink := link;
work_node := xmlFile_.FirstChildElement('worksheet');
hyperlinks := work_node.FirstChildElement('hyperlinks');
if not ifObj(hyperlinks) then begin
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
insert_node := class(TSXml).GetWorkSheetPrevNode(work_node, 'hyperlinks');
hyperlinks := work_node.InsertAfterChild(insert_node, 'element', 'hyperlinks');
end;
node := hyperlinks.FirstChildElement('hyperlink');
while ifObj(node) do begin
ref := node.GetAttribute('ref');
if ref = axis then begin
node := hyperlinks.DeleteChild(node);
hyperlink_node := node;
break;
end;
node := node.NextElement();
end;
hyperlink.Axis := axis;
marshal := hyperlink.Marshal();
attrs := marshal['attributes'];
if attrs['linkType'] = "Location" then reindex(attrs, array('linkType': nil, 'linkUrl': 'location'));
else if attrs['linkType'] = "External" then
Begin
[rid, commentFileName, sheetFileName, relsfile] := file_.WorkBook().GetRelationshipRid(sheetName_, hyperlink.LinkUrl);
if commentFileName = "" then
if hyperlink.LinkType = "location" then
begin
hyperlink.Location := hyperlink.LinkUrl;
end
else if hyperlink.LinkType = 'external' then
begin
relsfile := file_.WorkBook().GetSheetRelsFile(sheetName_);
[id, target, rid] := class(TSXml).FindRelationshipRid(relsfile, hyperlink.LinkUrl);
if target = "" then
Begin
rid++;
ridstr := 'rId' + inttostr(rid);
xmlfile := file_.WorkBook().GetXmlFileObj(relsfile);
class(xlsxXml).AddRelationshipRid(xmlfile, hyperlink.LinkUrl, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", ridstr, "External");
id++;
ridstr := 'rId' + inttostr(id);
class(TSXml).AddRelationshipRid(relsfile, hyperlink.LinkUrl, "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink", ridstr, "External");
hyperlink.Rid := ridstr;
End
reindex(attrs, array('linkType': nil, 'linkUrl': nil));
attrs['r:id'] := 'rId' + inttostr(rid);
End
marshal['attributes'] := attrs;
hyperlinks.InsertEndChild(marshal);
else hyperlink.Rid := 'rId' + inttostr(rid);
end
hyperlink.LinkType := nil;
hyperlink.LinkUrl := nil;
if not ifObj(hyperlink_node) then
begin
hyperlinks.InsertEndChild(hyperlink.marshal());
end
else begin
marshal := hyperlink.Marshal();
class(TSXml).UpdateNode(node, marshal['attributes'], marshal['children']);
end
End;
Function GetCellHyperLink(axis);
@@ -68,7 +70,20 @@ Type xlsxHyperLink = Class
ref := node.GetAttribute('ref');
if ref = axis then
begin
link.RootObj := node;
location := node.GetAttribute('location');
if location then
begin
link.LinkUrl := location;
link.LinkType := 'location';
end
else begin
link.LinkType := 'external';
rid := node.GetAttribute('r:id');
rels_file := file_.WorkBook().GetSheetRelsFile(sheetName_);
target_node := class(TSXml).FindRelationship(rels_file, rid);
if ifObj(target_node) then link.LinkUrl := target_node.GetAttribute('Target');
end
link.Tooltip := node.GetAttribute('tooltip');
break;
end
node := node.NextElement();
+22 -20
View File
@@ -15,39 +15,42 @@ Type xlsxImage = Class
return new xlsxImage(sheet, excel);
End;
Function SetSheetBackground(picture);
Function SetSheetBackground(pic);
Begin
if not ifBinary(picture.Image) or length(picture.Image) = 0 then
if not ifBinary(pic.Image) or length(pic.Image) = 0 then
return "Invalid Image Data.";
picture := new TSImage(pic.Image);
image_file := getImageFileName(picture);
rels_xmlfile := excel_.WorkBook().GetSheetRelsFile(sheetName_);
prefix := ReplaceStr(image_file, 'xl/', '../');
[rid, target] := class(xlsxXml).FindRelationshipRid(rels_xmlfile, prefix);
//println("image_file = {}", image_file);
[rid, target] := class(TSXml).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);
class(TSXml).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');
content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddDefaultContentType(content_xml, picture.ExtFileName, 'image/' $ picture.ExtFileName);
sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_);
node := sheet_xml.FirstChildElement('worksheet');
picture_node := node.FirstChildElement('picture');
if not ifObj(picture_node) then
begin
prev_node := class(xlsxXml).GetWorkSheetPrevNode(node, 'picture');
prev_node := class(TSXml).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
Function AddPicture(topLeft, bottomRight, picture, format);
Function AddPicture(topLeft, bottomRight, pic, format);
Begin
if not ifBinary(picture.Image) or length(picture.Image) = 0 then
if not ifBinary(pic.Image) or length(pic.Image) = 0 then
return "Invalid Image Data.";
picture := new TSImage(pic.Image);
[err1, col1, row1] := excel_.CellNameToCoordinates(topLeft);
[err2, col2, row2] := excel_.CellNameToCoordinates(bottomRight);
if err1 or err2 then return 'Invalid params.';
@@ -55,26 +58,26 @@ Type xlsxImage = Class
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);
[rid, target] := class(TSXml).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);
class(TSXml).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');
content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddDefaultContentType(content_xml, picture.ExtFileName, 'image/' $ picture.ExtFileName);
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');
prev_node := class(TSXml).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);
[id, target] := class(TSXml).FindRelationshipRid(sheet_rels, drawing_file_name);
drawing_node.SetAttribute('r:id', 'rId' + inttostr(id));
// drawingN.xml
@@ -95,8 +98,7 @@ Type xlsxImage = Class
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.ID := class(TSXml).GetcNvPrID(drawing_xml);
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:"));
@@ -150,7 +152,7 @@ private
image_file := '';
for i:=0 to length(image_files)-1 do
begin
if zipfile_.Diff(image_files[i], picture.Image) = 0 then
if zipfile_.Diff(image_files[i], picture.Content) = 0 then
begin
image_file := image_files[i];
break;
@@ -159,8 +161,8 @@ private
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);
image_file := 'xl/media/image' $ image_count $ '.' $ picture.ExtFileName;
zipfile_.Add(image_file, picture.Content);
end
return image_file;
End
@@ -1,41 +0,0 @@
Type xlsxMargins = Class
Function Create(sheetobj, file, xml); overload;
Begin
sheet_ := sheetobj;
file_ := file;
xmlFile_ := xml;
End;
Function SetPageMargins(margins);
Begin
marshal := margins.Marshal();
work_node := xmlFile_.FirstChild('worksheet');
node := work_node.FirstChild('pageMargins');
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');
margins := TOfficeObj('tmargins');
margins.RootObj := node;
return margins;
End
class Function NewObject(sheetname, file);
Begin
o := file.WorkBook().GetSheetObj(sheetname);
xml := file.WorkBook().GetSheetXmlfile(sheetname);
if not ifObj(o) then return 0;
return new xlsxMargins(o, file, xml);
End;
private
file_; //TSExcelFile对象
sheet_;//XmlSheet对象
xmlFile_; //sheet对应的xml对象
End;
+8 -14
View File
@@ -8,28 +8,22 @@ 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);
arr := array('sheetData', 'mergeCells', 'phoneticPr', 'pageMargins');
for i:=length(arr)-1 to 0 do
node := work_node.FirstChild('pageSetup');
if not ifObj(node) then
begin
node := work_node.FirstChild(arr[i]);
if ifObj(node) then
begin
work_node.InsertAfterChild(node, marshal);
flag := 1;
end
prev_node := class(TSXml).GetWorkSheetPrevNode(work_node, 'pageSetup');
node := work_node.InsertAfterChild(prev_node, marshal);
end
else begin
class(TSXml).UpdateNode(node, marshal['attributes'], marshal['children']);
end
if not flag then
work_node.InsertEndChild(marshal);
End;
Function GetPageLayout();
Begin
node := xmlFile_.FirstChild('worksheet').FirstChild('pageSetUp');
node := xmlFile_.FirstChild('worksheet').FirstChild('pageSetup');
page_layout := TOfficeObj('TPageLayout');
page_layout.RootObj := node;
return page_layout;
+2 -10
View File
@@ -7,21 +7,13 @@ Type xlsxShape = Class
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存在
o := excel.WorkBook().GetSheetObj(sheet);//sheet存在
if not ifObj(o) then return 0;
return new xlsxShape(sheet, excel);
End;
@@ -68,7 +60,7 @@ private
Function setSpNvSpPr(obj, shapeType);
Begin
obj.NodeName := 'xdr:nvSpPr';
obj.CNvPr.ID := class(xlsxXml).GetcNvPrID(drawingXmlObj_);
obj.CNvPr.ID := class(TSXml).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';
+53 -10
View File
@@ -6,43 +6,86 @@ Type xlsxSheetView = Class
xmlFile_ := xml;
End;
Function SetSheetViewOptions(viewIndex, sheetView);
Function SetSheetViewOptions(windowsIndex, sheetView);
Begin
node := xmlFile_.FirstChild('worksheet').FirstChild('sheetViews');
sheet_view_node := node.FirstChild('sheetView');
while ifObj(sheet_view_node) do
Begin
id := sheet_view_node.GetAttribute('workbookViewId');
if trystrtoint(id, r) and r = viewIndex then
if trystrtoint(id, r) and r = windowsIndex then
Begin
marshal := SheetView.Marshal();
class(xlsxXml).UpdateNode(sheet_view_node, marshal['attributes'], array());
class(TSXml).UpdateNode(sheet_view_node, marshal['attributes'], array());
return '';
End
sheet_view_node := sheet_view_node.NextElement();
End
End;
Function GetSheetViewOptions(viewIndex, sheetView);
Function GetSheetViewOptions(windowsIndex, sheetView);
Begin
node := xmlFile_.FirstChild('worksheet').FirstChild('sheetViews');
sheet_view_node := node.FirstChild('sheetView');
while ifObj(sheet_view_node) do
Begin
id := sheet_view_node.GetAttribute('workbookViewId');
if trystrtoint(id, r) and r = viewIndex then
if trystrtoint(id, r) and r = windowsIndex then
Begin
marshal := sheet_view_node.Marshal()[0];
sheetview := TOfficeObj('TSheetView');
sheetview.ShowGridLines := marshal['attributes']['showGridLines'];
sheetview.ShowRowColHeaders := marshal['attributes']['showRowColHeaders'];
sheetview.ZoomScale := marshal['attributes']['zoomScale'];
sheetview.ZoomScaleNormal := marshal['attributes']['zoomScaleNormal'];
sheetview.RootObj := sheet_view_node;
return sheetview;
End
sheet_view_node := sheet_view_node.NextElement();
End
return nil;
End
Function SetPane(windowsIndex, Pane);
Begin
node := xmlFile_.FirstChild('worksheet').FirstChild('sheetViews');
sheet_view_node := node.FirstChild('sheetView');
while ifObj(sheet_view_node) do
Begin
id := sheet_view_node.GetAttribute('workbookViewId');
if trystrtoint(id, r) and r = windowsIndex then
Begin
sheet_view_node.DeleteChildren();
sheet_view_node.InsertFirstChild(Pane.Marshal());
if Pane.XSplit and Pane.YSplit then
begin
selection := tofficeobj('TSelection');
selection.pane := 'topRight';
selection.activecell := coordinatestocellname(pane.xsplit + 1, 1)[1];
selection.sqref := selection.activecell;
sheet_view_node.InsertEndChild(selection.Marshal());
selection.Pane := 'bottomLeft';
selection.ActiveCell := CoordinatesToCellName(1, Pane.YSplit + 1)[1];
selection.Sqref := selection.ActiveCell;
sheet_view_node.InsertEndChild(selection.Marshal());
selection := TOfficeObj('TSelection');
selection.Pane := 'bottomRight';
sheet_view_node.InsertEndChild(selection.Marshal());
end
else if Pane.XSplit then
begin
selection := tofficeobj('TSelection');
selection.pane := 'topRight';
selection.activecell := coordinatestocellname(pane.xsplit + 1, 2)[1];
selection.sqref := selection.activecell;
sheet_view_node.InsertEndChild(selection.Marshal());
end
else if Pane.YSplit then
begin
selection := tofficeobj('TSelection');
selection.pane := 'bottomLeft';
sheet_view_node.InsertEndChild(selection.Marshal());
end
End
sheet_view_node := sheet_view_node.NextElement();
End
End;
class Function NewObject(sheetname, file);
Begin
o := file.WorkBook().GetSheetObj(sheetname);
+208 -10
View File
@@ -7,7 +7,7 @@ Type xlsxStyles = Class
styleXmlFile_ := file_.WorkBook().GetXmlFileObj('xl/styles.xml');
End
Function GetStyleId(style);
Function GetStyleId(style);overload;
Begin
node := styleXmlFile_.FirstChildElement('styleSheet');
font_id := insertNode(node, 'fonts', style.Font);
@@ -43,7 +43,89 @@ Type xlsxStyles = Class
node.InsertEndChild(xf.Marshal());
node.SetAttribute('count', strtoint(count) + 1);
return count;
End
End;
Function GetStyleId(newStyle, oldStyleId);overload;
Begin
if oldStyleId = '' then return nil;
style_node := styleXmlFile_.FirstChildElement('styleSheet');
cellXfs_node := style_node.FirstChildElement('cellXfs');
count := strtoint(cellXfs_node.GetAttribute('count'));
Id := strtoint(oldStyleId);
if Id > count-1 then return nil;
xf := getNode(cellXfs_node, 'xf', Id);
marshal := xf.marshal()[0];
xf_node := cellXfs_node.InsertEndChild(marshal);
cellXfs_node.SetAttribute('count', count + 1);
attrs := marshal['attributes'];
style := newStyle;
numfmt_id := trystrtoint(attrs['numFmtId'], r) ? r : 0;
copyNode(style_node, xf_node, 'numFmts', 'numFmt', 'numFmtId', numfmt_id, style.NumberFormat);
font_id := trystrtoint(attrs['fontId'], r) ? r : 0;
copyNode(style_node, xf_node, 'fonts', 'font', 'fontId', font_id, style.Font);
border_id := trystrtoint(attrs['borderId'], r) ? r : 0;
copyNode(style_node, xf_node, 'borders', 'border', 'borderId', border_id, style.Border);
fill_id := trystrtoint(attrs['fillId'], r) ? r : 0;
copyNode(style_node, xf_node, 'fills', 'fill', 'fillId', fill_id, style.Fill);
marshal := style.Alignment.Marshal();
alignment := xf_node.FirstChildElement('alignment');
if ifObj(alignment) then class(TSXml).UpdateNode(alignment, marshal['attributes'], marshal['children']);
else begin
xf_node.InsertEndChild(marshal);
xf_node.SetAttribute('applyAlignment', 1);
end
marshal := style.Protection.Marshal();
protection := xf_node.FirstChildElement('protection');
if ifObj(protection) then class(TSXml).UpdateNode(protection, marshal['attributes'], marshal['children']);
else begin
xf_node.InsertEndChild(marshal);
xf_node.SetAttribute('applyProtection', 1);
end
return inttostr(count);
End;
Function GetStyle(styleId);
Begin
if styleId = '' then return nil;
style_node := styleXmlFile_.FirstChildElement('styleSheet');
cellXfs_node := style_node.FirstChildElement('cellXfs');
count := strtoint(cellXfs_node.GetAttribute('count'));
Id := strtoint(styleId);
if Id > count-1 then return nil;
xf := getNode(cellXfs_node, 'xf', Id);
attrs := xf.Attributes();
numfmt_id := trystrtoint(attrs['numFmtId'], r) ? r : 0;
font_id := trystrtoint(attrs['fontId'], r) ? r : 0;
border_id := trystrtoint(attrs['borderId'], r) ? r : 0;
fill_id := trystrtoint(attrs['fillId'], r) ? r : 0;
alignment := xf.FirstChildElement('alignment');
protection := xf.FirstChildElement('protection');
style := TOfficeObj('TStyle');
numFmts_node := style_node.FirstChildElement('numFmts');
fonts_node := style_node.FirstChildElement('fonts');
borders_node := style_node.FirstChildElement('borders');
fills_node := style_node.FirstChildElement('fills');
setRootObj(style.NumberFormat, getNode(numFmts_node, 'numFmt', numfmt_id));
setRootObj(style.Font, getNode(fonts_node, 'font', font_id));
setRootObj(style.Border, getNode(borders_node, 'border', border_id));
node := getNode(fills_node, 'fill', fill_id);
setRootObj(style.Fill, node);
setFillGradientObj(style.Fill.Gradient, node);
style.Alignment.RootObj := ifObj(alignment) ? alignment : nil;
style.Protection.RootObj := ifObj(protection) ? protection : nil;
setNodeUri(style);
return style;
End;
class Function NewObject(sheetname, file);
Begin
@@ -54,6 +136,126 @@ Type xlsxStyles = Class
End;
private
Function setFillGradientObj(obj, node);
Begin
gradient_node := node.FirstChildElement('gradientFill');
if not ifObj(gradient_node) then return;
stop_node := gradient_node.FirstChildElement('stop');
if ifObj(stop_node) then
begin
obj.Stop1.RootObj := stop_node;
obj.Stop1.NodeUri := '';
end
stop_node := stop_node.NextElement();
if ifObj(stop_node) then
begin
obj.Stop2.RootObj := stop_node;
obj.Stop2.NodeUri := '';
end
stop_node := stop_node.NextElement();
if ifObj(stop_node) then
begin
obj.Stop3.RootObj := stop_node;
obj.Stop3.NodeUri := '';
end
End;
Function setRootObj(obj, node);
Begin
obj.RootObj := node;
children := obj.GetChildren();
for i:=0 to length(children)-1 do
begin
val := children[i]['obj'];
if ifObj(val) then
begin
val.NodeUri := children[i]['name'];
val.RootObj := node;
end
end;
End;
Function setNodeUri(obj);
Begin
obj.NodeUri := '';
children := obj.GetChildren();
for i:=0 to length(children)-1 do
begin
val := children[i]['obj'];
if ifObj(val) then val.NodeUri := '';
end;
End;
Function getNode(rootNode, name, count);
Begin
if name = 'numFmt' then return getNodeNumFmts(rootNode, count);
if not ifObj(rootNode) then return nil;
node := rootNode.FirstChildElement(name);
times := count;
while times > 0 do
begin
node := node.NextElement();
times--;
end
return node;
End;
Function getNodeNumFmts(rootNode, id);
Begin
if not ifObj(rootNode) then return nil;
node := rootNode.FirstChildElement('numFmt');
num_id := inttostr(id);
while ifObj(node) do
begin
if num_id = node.GetAttribute('numFmtId') then return node;
node := node.NextElement();
end
return nil;
End;
Function copyNodeNumFmts(root, xf_node, id, obj);
Begin
if id = 0 then
begin
if ifnil(obj.FormatCode) then xf_node.SetAttribute('numFmtId', 0);
else begin
processNumFmtId(root, 'numFmts', obj);
insertNode(root, 'numFmts', obj);
xf_node.SetAttribute('numFmtId', obj.NumFmtId);
end
end
else begin
nodeName_node := root.FirstChildElement('numFmts');
num_node := getNodeNumFmts(nodeName_node, id);
processNumFmtId(root, 'numFmts', obj);
new_node := nodeName_node.InsertEndChild(num_node.Marshal()[0]);
count := strtoint(nodeName_node.GetAttribute('count'));
nodeName_node.SetAttribute('count', count + 1);
xf_node.SetAttribute('numFmtId', obj.NumFmtId);
marshal := obj.Marshal();
class(TSXml).UpdateNode(new_node, marshal['attributes'], marshal['children']);
end
End;
Function copyNode(root, xf_node, nodeName, name, idName, id, obj);
Begin
if nodeName = 'numFmts' then return copyNodeNumFmts(root, xf_node, id, obj);
nodeName_node := root.FirstChildElement(nodeName);
if not ifObj(nodeName_node) then return;
node := getNode(nodeName_node, name, id);
new_node := nodeName_node.InsertEndChild(node.Marshal()[0]);
count := strtoint(nodeName_node.GetAttribute('count'));
nodeName_node.SetAttribute('count', count + 1);
xf_node.SetAttribute(idName, count);
if ifObj(obj) then
begin
marshal := obj.Marshal();
class(TSXml).UpdateNode(new_node, marshal['attributes'], marshal['children']);
end;
End;
Function insertNode(rootNode, childName, obj);
Begin
marshal := obj.Marshal();
@@ -68,23 +270,19 @@ private
count := node.GetAttribute('count');
node.InsertEndChild(marshal);
node.SetAttribute('count', strtoint(count) + 1);
//node.Print;
return count;
End
Function processNumFmtId(rootNode, childName, obj);
Begin
if ifnil(obj.FormatCode) or not ifnil(obj.numFmtId) then return;
if ifnil(obj.FormatCode) then return;
node := rootNode.FirstChildElement(childName);
if not ifObj(node) then obj.numFmtId := '1';
if not ifObj(node) then id := 176;
else begin
node := node.LastChildElement('numFmt');
if not ifObj(node) then obj.numFmtId := '1';
else begin
id := node.GetAttribute('numFmtId');
obj.numFmtId := strtoint(id) + 1;
end
id := strtoint(node.GetAttribute('numFmtId')) + 1;
end
obj.numFmtId := id;
End
private
+30 -15
View File
@@ -27,7 +27,7 @@ Type xlsxTable = Class
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.DisplayName := class(xlsxTable).GenerateValidDisplayName(format.TableName, tableid);
table.Ref := topLeft $ ':' $ bottomRight;
table.HeaderRowCount := format.HeaderRowCount ? '1' : nil;
table.TotalsRowShown := format.TotalsRowShown ? '1' : '0';
@@ -45,7 +45,7 @@ Type xlsxTable = Class
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']);
class(TSXml).UpdateNode(table_node, marshal['attributes'], marshal['children']);
table_node.InsertEndChild(table_str);
table_node.InsertEndChild(format.Marshal());
@@ -59,7 +59,7 @@ Type xlsxTable = Class
count := 1;
end
else begin
count := inttostr(table_part.GetAttribute('count')) + 1;
count := strtoint(table_part.GetAttribute('count')) + 1;
end
node := table_part.InsertEndChild('element', 'tablePart');
node.SetAttribute('r:id', 'rId' $ rid);
@@ -67,26 +67,41 @@ Type xlsxTable = Class
End
class Function GenerateValidDisplayName(name, nameId);
Begin
if ifnil(name) then name := '表' $ nameId;
if TOfficeApi().Get('Table-' $ name) then
begin
new_name := '表' $ nameId;
while TOfficeApi().Get('Table-' $ new_name) do new_name := '表' $ ++nameId;
TOfficeApi().Set('Table-' $ new_name, true);
return new_name;
end
TOfficeApi().Set('Table-' $ name, true);
return name;
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
if not includeHeader then excel_.WorkBook().InsertRow(sheetName_, row);
for i:=begCol to endCol do
begin
[err, cell] := excel_.CoordinatesToCellName(i, row, false);
if includeHeader then
name := excel_.GetCellValue(sheetName_, cell)[1];
begin
[err, name] := excel_.WorkBook().GetCellValue(sheetName_, cell);
name := "列" $ col_index++;
if err then excel_.WorkBook().SetCellValue(sheetName_, cell, name);
end
else begin
name := "列" $ col_index++;
excel_.SetCellValue(sheetName_, cell, name);
excel_.WorkBook().SetCellValue(sheetName_, cell, name);
end
table_str += fmt('<tableColumn id="{}" name="{}" />', id++, name);
table_str += format('<tableColumn id="%d" name="%s" />', id, name);
end
table_str += "</tableColumns>";
@@ -96,15 +111,15 @@ private
Function addTableXmlFileAndRelation();
Begin
sheet_rels_file := excel_.WorkBook().GetSheetRelsFile(sheetName_);
[rid, target] := class(xlsxXml).FindRelationshipRid(sheet_rels_file, '');
[rid, target] := class(TSXml).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');
excel_.zip().Add(table_name, class(TSXml).XmlHeader() + "<table />");
class(TSXml).AddRelationshipRid(sheet_rels_file, table_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/table', 'rId' $ rid);
content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types'));
class(TSXml).AddOverrideContentType(content_xml, '/' + table_name, class(TSXml).GetTemplate('tableContentType'));
return array(rid, table_id, table_name);
End
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+401
View File
@@ -0,0 +1,401 @@
# 更新日志
## 2023-8-28
### V1.4.4
#### word
1. 修复`insertFile`样式错误问题
2. 修复`insertFile`后删除段落再新增段落位置错误问题
3. 修复生成目录中文编码未转换导致word打开失败问题
## 2023-8-22
### V1.4.3
#### word
支持段落判空`TParagraph.Empty()`
## 2023-8-18
### V1.4.2
#### word
支持插入另一个word内容`InsertFile(alias, fileName, posOpt)`
## 2023-8-11
### V1.4.1
#### word
修复插入表格后,设置样式ID无法全部生效问题
## 2023-8-10
### V1.4.0
#### word
支持三级以内目录设置字体,一级目录样式ID为`TOC1`,二级目录样式ID为`TOC2`,三级为`TOC3`,通过样式设置相关属性即可修改目录字体
## 2023-8-7
### V1.3.9
#### word
支持`AddHeading`时传入样式Id
## 2023-8-2
### V1.3.8
#### word
修复插入图片后,设置对齐失效问题
## 2023-7-26
### V1.3.7
#### word
新增表格获取高度和宽度方法`table.Height(row) table.Width(col)`
## 2023-7-19
### V1.3.6
#### word
新增对表格的行高设置`table.RowHeight(row, height)`
## 2023-7-14
### V1.3.5
#### word
段落字体大小设置调整,对齐VBA设置
## 2023-7-11
### V1.3.4
修复加密Bug
## 2023-7-4
### V1.3.3
word/excel 新增加密方法`SetPassword`,升级`OpenFile(alias, fileName, Password)`
## 2023-6-26
### V1.3.2
修复.net使用rdo2执行失败问题,使用rdo2时候,需调用`TOfficeInit()`初始化
#### word
1. 修复word模板`template.docx`执行失败问题
## 2023-6-20
更新部署方式,不再依赖`fmt_pubkrnl_plugin.dll`,详情见[README](./README.md)
## 2023-4-26
### V1.3.1
`office_plugin.dll``liboffice_plugin.sox86_64`动态库更新
## 2023-4-18
### V1.3.0
支持常用图片的高宽自动识别,支持图片格式有`gif, png, jpeg/jpeg, bmp`
#### excel
1. 支持excel程序设置字体样式粗体,斜体等此类问题的返回类型,如`style.Font.Bold`返回`true 或 false`
## 2023-4-4
### V1.2.9
#### excel
1. 修复超链接兼容性
## 2023-3-31
### V1.2.8
#### excel
1. 修复由.net客户端导出的excel兼容性问题,`SetColWidth``Set/GetDefaultSheet``SetSheetHeaderFooter`
## 2023-3-23
### V1.2.7
#### excel
1. `GetSheetDefaultColWidth`默认返回值改为`nil`
## 2023-3-22
### V1.2.6
#### excel
1. 修复`SetCellValue`值为`nil`未生效问题
## 2023-3-20
### V1.2.5
#### excel
1. 修复数字样式获取再赋值再获取失效问题
2. 支持单元格填入`nil`
3. `GetComment`获取不到批注时返回内容改为`array(nil,nil)`
4. 修复`Set/GetColWitdh`传入变量时会被修改问题
## 2023-3-16
### V1.2.4
#### excel
1. 修复样式获取数字样式失败问题
2. 修复边框样式对角线未生效问题
3. 修复获取属性未正确返回属性值问题
## 2023-3-9
### V1.2.3
#### excel
1. `GetComment`获取不到批注时返回内容改为`array(nil,nil)`
2. 新增`RemoveComment`
3. 新增`NewStyle-overload`
4. 修复`ClearCell`引起文件报错
## 2023-3-6
### V1.2.2
#### excel
1. 修复`InsertRow`之后原有单元格合并错误问题
2. 新增`GetCellValueType`
3. 新增`GetComment`
4. 新增`GetStyle`,获取的样式修改可通过`TStyle::Apply()`方法重新写入样式
5. 新增`SetRowOutlineLevel``GetRowOutlineLevel`
6. 新增`SetColOutlineLevel``GetColOutlineLevel`
## 2023-2-24
### V1.2.1
#### excel
1. Get相关方法重新Set后不再覆盖原有设置,影响方法如下`Set(Get)PageMargins`,`Set(Get)CellHyperLink`,`Set(Get)PageLayout`,`Set(Get)CalcOptions`,`Set(Get)DefaultFont`,`Set(Get)SheetViewOptions`
## 2023-2-23
### V1.2.0
#### excel
1. 修复`GetCaclOptions`名称错误,更改为`GetCaclOptions`
## 2023-2-22
### V1.1.9
#### excel
1. 新增`InsertSheet`
### V1.1.8
#### excel
1. 新增`GetCalcOptios`
## 2023-2-21
### V1.1.7
#### word
1. 新增`LoadFromMem`, `SavaToMem`
#### excel
1. 新增`LoadFromMem`, `SavaToMem`
2. 新增重载方法`NewSheet`
3. 新增`SetCalcOptions`
4. 修复删除sheet报错问题
## 2023-2-13
### V1.1.6
重大更新:移除了`template`文件夹
## 2023-2-3
### V1.1.5
#### excel
1. 修复`HSLToRGB`
2. 修复`CoordinatesToCellName`
## 2023-2-2
### V1.1.4
#### word
1. 修复文本框插入图片兼容性问题
2. 修复项目符号问题
#### excel
1. 新增`GetDefaultFont`
## 2023-2-1
### V1.1.3
#### word
1. 修复获取段落样式ID失败问题
2. 修复文本框添加图片失败问题
#### excel
1. 新增`SetDefaultFont`
## 2023-1-31
### V1.1.2
#### word
1. 完善帮助文档
#### excel
1. 新增`SetPane`
2. 新增`NewSheetView`
3. 单元格样式新增属性“文本方向”: `TAlignment::TextRotation`
## 2023-1-18
### V1.1.1
#### word
1. 兼容文本框`TextBox`
2. 修正`TParagraph::TabStops`
3. 修复获取图标列表失败问题
4. 修复`TDocxStyles::Default`
#### excel
1. 新增`ProtectSheet``UnProtectSheet`
2. 修复`SetSheetViewOptions``GetSheetViewOptions`
## 2023-1-16
### V1.1.0
#### word
1. 修复页眉页脚显示问题
2. 修复表格插入列宽失败问题
3. 优化`InsertTable`性能
#### excel
1. 新增`CopySheet`
## 2023-1-12
### V1.0.9
#### word
1. 新增ExecInnerTSl
2. 新增修改chart图(数据)
3. 修复`TNumbering::AddStyleByInnerXml`错误
4. 完善帮助文档
## 2023-1-11
### V1.0.8
#### word
1. 修复`copyFormat``AddTableContent`
## 2023-1-10
### V1.0.7
#### word
1. 修复chart图兼容性问题
### V1.0.6
中文自动转换API由`class(xlsxXml).CodePage('中文');`调整为`TOfficeApi().CodePage('中文');`
## 2023-1-5
### V1.0.5
❗ 部署方式发生变化,简化了环境部署,详见项目[README](./README.md)
#### word
1. 修复 Properties执行报错
2. 修复格式刷
#### excel
1. 移除API `JoinCellName`
2. 修改`RGBToHSL``HSLToRGB`返回值
3. 修复获取超链接`GetCellHyperLink`失败问题
4. 修复一个对象新建文件,打开文件之后引发的xlsx文件错误问题
5. 修复`GetCoreProps`,`GetAppProps`失败问题
## 2022-12-30
### V1.0.4
#### word
1. 初步支持中文
#### excel
1. 初步支持中文
2. `SetSheetName``NewSheet` 返回值不再是`[err, errinfo]`
3. 修复清除单元格`ClearCell`不正确问题
4. 修复`SetCellFormula``GetCellFormula`问题
5. 修复`SetRowVisible``GetRowVisible``SetSheetVisible`问题
如何设置字符集(中文支持)?
★用户的脚本可能是UFT8格式,或可能是GBK码格式,系统提供API自动设置当前字符集环境:`class(xlsxXml).CodePage('中文');` 在文件头设置该代码后,系统会自动检测当前的环境字符集