dev 1.0.1
This commit is contained in:
parent
d6939071b3
commit
2674ab8eb3
Binary file not shown.
12
README.md
12
README.md
|
|
@ -1,3 +1,15 @@
|
|||
# OfficePlugin
|
||||
|
||||
TSOffice 项目:纯 TSL 代码实现 excel、word 文件读写
|
||||
|
||||
## 部署
|
||||
|
||||
### windows
|
||||
|
||||
- [fmt_pubkrnl_plugin](./Windows-X64/fmt_pubkrnl_plugin.dll) 放入 tsl 安装根目录下 Plugin 文件夹
|
||||
- [office_plugin](./Windows-X64/office_plugin.dll) 放入 tsl 安装根目录下 Plugin 文件夹
|
||||
- [tsxlsx.dll](./Windows-X64/tsxlsx.dll) 放入 tsl 安装根目录
|
||||
|
||||
## 帮助文档
|
||||
|
||||
- [Excel 帮助文档](./ExcelFile%E4%BD%BF%E7%94%A8%E5%B8%AE%E5%8A%A9.xlsx)
|
||||
|
|
|
|||
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,882 @@
|
|||
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,文件名
|
||||
Function Create(alias, fname); overload;
|
||||
Begin
|
||||
init();
|
||||
OpenFile(alias, fname);
|
||||
End;
|
||||
|
||||
//析构函数
|
||||
Function Destory();
|
||||
Begin
|
||||
End;
|
||||
|
||||
//初始化
|
||||
Function init();
|
||||
Begin
|
||||
zipfile_ := new ZipFile();
|
||||
xml_ := new xlsxXml();
|
||||
End;
|
||||
|
||||
///打开excel文件
|
||||
///alias: string,文件目录别名
|
||||
///fname: string,文件名
|
||||
///返回:[err, errmsg]
|
||||
Function OpenFile(alias, fname);
|
||||
Begin
|
||||
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
|
||||
[err, errmsg] := zipfile_.Open(alias, fname);
|
||||
if err=0 then Begin
|
||||
workbook_ := new xlsxWorkBook(zipfile_, xml_);
|
||||
workbook_.Load();
|
||||
End;
|
||||
return array(err, errmsg);
|
||||
End;
|
||||
|
||||
///新建excel文件
|
||||
///返回:[err, info]
|
||||
Function NewFile();
|
||||
Begin
|
||||
path := ExtractFileDir(ExtractFileDir(PluginPath()));
|
||||
{$IFNDEF Win32}
|
||||
defaultFileName := path + '\\funcext\\TSOffice\\default.xlsx';
|
||||
{$ELSE}
|
||||
defaultFileName := path + '/funcext/TSOffice/default.xlsx';
|
||||
{$ENDIF}
|
||||
[err, errinfo] := OpenFile('', defaultFileName);
|
||||
if not err then return array(err, errinfo);
|
||||
|
||||
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
|
||||
zipfile_.Add(xml_.GetFileName('rels'), xml_.XmlHeader() + xml_.GetTemplate('rels'));
|
||||
zipfile_.Add(xml_.GetFileName('docProps_app'), xml_.XmlHeader() + xml_.GetTemplate('docProps_app'));
|
||||
zipfile_.Add(xml_.GetFileName('docProps_core'), xml_.XmlHeader() + xml_.GetTemplate('docProps_core'));
|
||||
zipfile_.Add(xml_.GetFileName('workbook_rels'), xml_.XmlHeader() + xml_.GetTemplate('workbook_rels'));
|
||||
zipfile_.Add(xml_.GetFileName('theme1'), xml_.XmlHeader() + xml_.GetTemplate('theme1'));
|
||||
zipfile_.Add(xml_.GetFileName('sheet1'), xml_.XmlHeader() + xml_.GetTemplate('sheet1'));
|
||||
zipfile_.Add(xml_.GetFileName('styles'), xml_.XmlHeader() + xml_.GetTemplate('styles'));
|
||||
zipfile_.Add(xml_.GetFileName('workbook'), xml_.XmlHeader() + xml_.GetTemplate('workbook'));
|
||||
zipfile_.Add(xml_.GetFileName('Content_Types'), xml_.XmlHeader() + xml_.GetTemplate('Content_Types'));
|
||||
workbook_ := new xlsxWorkBook(zipfile_, xml_);
|
||||
workbook_.Load();
|
||||
return array(0, 'ok');
|
||||
End;
|
||||
|
||||
///保存文件
|
||||
///返回: [err, info]
|
||||
Function Save();
|
||||
Begin
|
||||
return zipfile_.Save();
|
||||
End;
|
||||
|
||||
///另存为
|
||||
///alias: string,文件目录别名
|
||||
///fname: string,文件名
|
||||
///返回: [err, info]
|
||||
Function SaveAs(alias, fname);
|
||||
Begin
|
||||
return zipfile_.Save(alias, fname);
|
||||
End;
|
||||
|
||||
///真实文件名
|
||||
///返回:string
|
||||
Function FileName();
|
||||
Begin
|
||||
return zipfile_.FileName();
|
||||
End;
|
||||
|
||||
///获取工作表列表
|
||||
///返回: arry('Sheet1','Sheet2')
|
||||
Function GetSheets();
|
||||
Begin
|
||||
return workbook_.GetSheets();
|
||||
End;
|
||||
|
||||
///获取工作表数
|
||||
///返回: integer
|
||||
Function GetSheetsCount();
|
||||
Begin
|
||||
return workbook_.GetSheetsCount();
|
||||
End;
|
||||
|
||||
///获取工作表名
|
||||
///index: int,工作表索引
|
||||
///返回: [err, sheetname:string]
|
||||
Function GetSheetName(index);
|
||||
Begin
|
||||
return workbook_.GetSheets()[index];
|
||||
End;
|
||||
|
||||
///设置工作表名
|
||||
///sourceName: string, 原工作表名
|
||||
///destName: string,目标工作表名
|
||||
///返回:[err, errinfo]
|
||||
Function SetSheetName(sourceName, destName);
|
||||
Begin
|
||||
return workbook_.SetSheetName(sourceName, destName);
|
||||
End;
|
||||
|
||||
///创建新sheet
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, info]
|
||||
Function NewSheet(sheet);
|
||||
Begin
|
||||
return workbook_.NewSheet(sheet);
|
||||
End;
|
||||
|
||||
///删除sheet
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, info]
|
||||
Function DeleteSheet(sheet);
|
||||
Begin
|
||||
return workbook_.DeleteSheet(sheet);
|
||||
End;
|
||||
|
||||
///获取总列数
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, TotalCols:int]
|
||||
Function TotalCols(sheet);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return array(0, o.TotalCols());
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///获取总行数
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, TotalRows:int]
|
||||
Function TotalRows(sheet);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return array(0, o.TotalRows());
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///获取单元格的值
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格坐标,如: "A6"
|
||||
///返回: [err, value:string]
|
||||
Function GetCellValue(sheet, axis);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return o.GetCellValue(axis);
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///设置单元格的值
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格坐标,如: "A6"
|
||||
///val: Var,可以是整数、字符串、数值型等;nil 不设置值(可以调用ClearCell方法清空单元格),只设置属性
|
||||
///[opt:Tany],可选参数,单元格属性,可以是xml字符串或天软数组
|
||||
/// xml串:opt := '<c t="s" s="1"></c>';
|
||||
/// 数组: opt := array('t':'s', 's':'1');
|
||||
/// 属性t:单元格数据类型,不设置的话,数据类型为val的数据类型;
|
||||
/// t ->('s' 共享字符串、'b' bool 类型、'e' 错误类型、'inlineStr' 内联字符串类型、nil 数字类型、'str' 公式类型)
|
||||
/// 属性s:单元格样式
|
||||
///返回: [err, info]
|
||||
Function SetCellValue(sheet, axis, val, opt);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return array(0, o.SetCellValue(axis, val, opt));
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///获取富文本格式
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///返回: [err, richtxt:string],参见SetCellRichText
|
||||
Function GetCellRichText(sheet, axis);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return o.GetCellValue(axis, 'RichText');
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///设置富文本格式
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///richtext: string,xml串或富文本对象TSOffice('TRichText')
|
||||
///返回: [err, info]
|
||||
Function SetCellRichText(sheet, axis, richtext);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then Begin
|
||||
if ifObj(richtext) then
|
||||
richtext := class(xlsxXml).Dom2Xml(richtext.Marshal());
|
||||
return array(0, o.SetCellValue(axis, richtext, array('t':'s'), 'RichText'));
|
||||
End;
|
||||
return array(-1, 'The Sheet is not exist.');
|
||||
End;
|
||||
|
||||
///清空单元格
|
||||
///sheet: string,工作表名称
|
||||
///[TopLeft: string],左上角坐标,可选参数
|
||||
///[BottomRight: string],右下角坐标,可选参数,
|
||||
/// 用法1:ClearCell(); //Clear整个sheet
|
||||
/// 用法2:ClearCell('A2'); //Clear 'A2'单元格
|
||||
/// 用法3:ClearCell('A5', 'D8'); //Clear矩形区间所有单元格
|
||||
///返回: [err, info]
|
||||
Function ClearCell(sheet, TopLeft, BottomRight);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return array(0, o.ClearCell(TopLeft, BottomRight));
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///设置公式
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///formula: string,公式
|
||||
///返回: [err, info]
|
||||
Function SetCellFormula(sheet, axis, formula);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return o.SetCellFormula(axis, formula);
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///获取公式
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///返回: [err, formula:string]
|
||||
Function GetCellFormula(sheet, axis);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return o.GetCellFormula(axis);
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///按行赋值
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,起始坐标,如: "A4"
|
||||
///slice: array(),一维数组array(1,2,3,2,1,"hello")
|
||||
///返回: [err, info]
|
||||
Function SetSheetRow(sheet, axis, slice);
|
||||
Begin
|
||||
[err, col, row] := CellNameToCoordinates(axis);
|
||||
if err then
|
||||
return array(err, col);
|
||||
for i:=0 to length(slice)-1 do Begin
|
||||
[err, cell] := CoordinatesToCellName(col + i, row);
|
||||
//println('{}->{}',cell,slice[i]);
|
||||
SetCellValue(sheet, cell, slice[i]);
|
||||
End;
|
||||
return array(0, 'ok');
|
||||
End;
|
||||
|
||||
///插入数据表
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,左上角坐标,如: "A4"
|
||||
///data: table,数据表
|
||||
///[IncludeHeader: bool] 是否包括表头,默认FALSE
|
||||
///[IncludeIndex: bool] 是否自动添加索引号,默认FALSE
|
||||
///返回: [err, info]
|
||||
Function InsertTable(sheet, axis, data, IncludeHeader, IncludeIndex);
|
||||
Begin
|
||||
if not ifarray(data) or length(data)=0 then
|
||||
return array(-1, "Invalid Data.");
|
||||
if FieldCount(data)=0 then Begin //数据是一维数组
|
||||
return SetSheetRow(sheet, axis, data);
|
||||
End;
|
||||
[err, colNum, rowNum] := CellNameToCoordinates(axis);
|
||||
if err then
|
||||
return array(err, colNum);
|
||||
if IncludeHeader then Begin
|
||||
fields := FieldNames(data);
|
||||
if IncludeIndex then Begin
|
||||
fields := array("Index") union fields;
|
||||
End;
|
||||
[err, info] := SetSheetRow(sheet, axis, fields);
|
||||
if err then
|
||||
return array(err, info);
|
||||
rowNum ++;
|
||||
End;
|
||||
if IncludeIndex then Begin
|
||||
for i:=0 to length(data)-1 do Begin
|
||||
[err, cell] := CoordinatesToCellName(colNum, rowNum + i);
|
||||
if err then
|
||||
return array(err, cell);
|
||||
SetCellValue(sheet, cell, i+1);
|
||||
End;
|
||||
colNum ++;
|
||||
End;
|
||||
for i:=0 to length(data)-1 do Begin
|
||||
[err, cell] := CoordinatesToCellName(colNum, rowNum + i);
|
||||
if err then
|
||||
return array(err, cell);
|
||||
t := sselect * from data where thisrowindex = i End;
|
||||
//PrintLn("cell={},data={}->{}",cell, data[i],t);
|
||||
[err, info] := SetSheetRow(sheet, cell, t);
|
||||
if err then
|
||||
return array(err, info);
|
||||
End;
|
||||
return array(0, "OK");
|
||||
End;
|
||||
|
||||
///读取数据表
|
||||
///sheet: string,工作表名称
|
||||
///TopLeft: string,左上角坐标,如: "A4"
|
||||
///BottomRight: string,右下角坐标,如: "B8",为空获取从TopLeft开始的整张表
|
||||
///返回: [err, data:table]
|
||||
Function GetTable(sheet, TopLeft, BottomRight);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return array(0, o.Import(TopLeft, BottomRight));
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///插入列,在指定列前插入空白列
|
||||
///sheet: string,工作表名称
|
||||
///col: string 列名,如: "D"
|
||||
///返回: [err, info]
|
||||
Function InsertCol(sheet, col);
|
||||
Begin
|
||||
return workbook_.InsertCol(sheet, col);
|
||||
End;
|
||||
|
||||
///插入行,在指定列前插入空白行
|
||||
///sheet: string,工作表名称
|
||||
///row: int
|
||||
///返回: [err, info]
|
||||
Function InsertRow(sheet, row);
|
||||
Begin
|
||||
return workbook_.InsertRow(sheet, row);
|
||||
End;
|
||||
|
||||
///删除列
|
||||
///sheet: string,工作表名称
|
||||
///col: string,如: "D"
|
||||
///返回: [err, info]
|
||||
Function RemoveCol(sheet, col);
|
||||
Begin
|
||||
return workbook_.RemoveCol(sheet, col);
|
||||
End;
|
||||
|
||||
///删除行
|
||||
///sheet: string,工作表名称
|
||||
///row: int
|
||||
///返回: [err, info]
|
||||
Function RemoveRow(sheet, row);
|
||||
Begin
|
||||
return workbook_.RemoveRow(sheet, row);
|
||||
End;
|
||||
|
||||
///设置行高度
|
||||
///sheet: string,工作表
|
||||
///row: int,行
|
||||
///height: double
|
||||
///返回: [err, info]
|
||||
Function SetRowHeight(sheet, row, height);
|
||||
Begin
|
||||
return workbook_.SetRowHeight(sheet, row, height);
|
||||
End;
|
||||
|
||||
///获取行高度
|
||||
///sheet: string,工作表
|
||||
///row: int,行
|
||||
///返回: [err, info]
|
||||
Function GetRowHeight(sheet, row);
|
||||
Begin
|
||||
return workbook_.GetRowHeight(sheet, row);
|
||||
End;
|
||||
|
||||
///设置列宽度
|
||||
///sheet: string,工作表
|
||||
///startcol: string,开始列,如: "A"
|
||||
///endcol: string,结束列,如: "D"
|
||||
///width: double
|
||||
///返回: [err, info]
|
||||
Function SetColWidth(sheet, startCol, endCol, width);
|
||||
Begin
|
||||
return workbook_.SetColWidth(sheet, startCol, endCol, width);
|
||||
End;
|
||||
|
||||
///获取列宽度
|
||||
///sheet: string,工作表
|
||||
///col: int,列
|
||||
///返回: [err, info]
|
||||
Function GetColWidth(sheet, col);
|
||||
Begin
|
||||
return workbook_.GetColWidth(sheet, col);
|
||||
End;
|
||||
|
||||
///设置工作表默认列宽
|
||||
///sheet: string,工作表
|
||||
///width:double
|
||||
///返回: [err, info]
|
||||
Function SetSheetDefaultColWidth(sheet, width);
|
||||
Begin
|
||||
return workbook_.SetSheetDefaultColWidth(sheet, width);
|
||||
End
|
||||
|
||||
///获取工作表默认列宽
|
||||
///sheet: string,工作表
|
||||
///返回: [err, width]
|
||||
Function GetSheetDefaultColWidth(sheet);
|
||||
Begin
|
||||
return workbook_.GetSheetDefaultColWidth(sheet);
|
||||
End
|
||||
|
||||
///添加批注
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///Author:string
|
||||
///comment: string
|
||||
///返回: [err, info]
|
||||
Function AddComment(sheet, axis, Author, comment);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxComment');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist.');
|
||||
return o.AddComment(axis, Author, comment);
|
||||
End;
|
||||
|
||||
///添加图表
|
||||
///sheet: string,工作表名称
|
||||
///range:string,图表所处矩形区域,"A5:F10"
|
||||
///chart:TChart对象
|
||||
///返回: [err, info]
|
||||
Function AddChart(sheet, range, chart);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxChart');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist.');
|
||||
if not ifObj(chart) then return array(2, 'Invalid chart param.');
|
||||
return o.AddChart(range, chart);
|
||||
End;
|
||||
|
||||
///获取图表列表
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, ChartList]
|
||||
Function GetCharts(sheet);
|
||||
Begin
|
||||
return workbook_.GetCharts(sheet);
|
||||
End;
|
||||
|
||||
///单元格坐标切分
|
||||
///cell: string,单元格坐标
|
||||
///返回: [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);
|
||||
End;
|
||||
|
||||
///列名转索引
|
||||
///name: string
|
||||
///返回 [err, index:int],"AK" -> return array(0, 37);
|
||||
Function ColumnNameToNumber(name);
|
||||
Begin
|
||||
return xlsx_call("ColumnNameToNumber", name);
|
||||
End;
|
||||
|
||||
///索引转列名
|
||||
///index: int
|
||||
///返回 [err, name:string],37 -> return array(0, "AK");
|
||||
Function ColumnNumberToName(index);
|
||||
Begin
|
||||
return xlsx_call("ColumnNumberToName", index);
|
||||
End;
|
||||
|
||||
///单元格坐标转索引
|
||||
///cell: string
|
||||
///返回 [err, col:int, row: int] "A2" -> [1,2]
|
||||
Function CellNameToCoordinates(cell);
|
||||
Begin
|
||||
return xlsx_call("CellNameToCoordinates", cell);
|
||||
End;
|
||||
|
||||
///索引转单元格坐标
|
||||
///col: int
|
||||
///row: int
|
||||
///abs: bool ,true返回"$A$1"格式,false返回"A1"格式
|
||||
///返回 [err, cell:string] [1,2,true] -> "$A$2"
|
||||
Function CoordinatesToCellName(col, row, abs);
|
||||
Begin
|
||||
return xlsx_call("CoordinatesToCellName", col, row, abs);
|
||||
End;
|
||||
|
||||
///RGB与HSL色彩空间色值转换
|
||||
///r: int
|
||||
///g: int
|
||||
///b: int
|
||||
///返回: [err, h:double, s:double, l:double]
|
||||
Function RGBToHSL(r, g, b);
|
||||
Begin
|
||||
return xlsx_call("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);
|
||||
Begin
|
||||
return xlsx_call("HSLToRGB", h, s, l);
|
||||
End;
|
||||
|
||||
///新建样式对象
|
||||
///style: TStyle对象
|
||||
///返回: styleid
|
||||
Function NewStyle(style);
|
||||
Begin
|
||||
styleObj := new xlsxStyles('', self);
|
||||
return array(0, styleObj.GetStyleId(style));
|
||||
End
|
||||
|
||||
///设置单元格样式
|
||||
///sheet: string,工作表名称
|
||||
///TopLeft: string,左上角坐标
|
||||
///BottomRight: string,右下角坐标
|
||||
///styleid: string,样式Id
|
||||
///返回: [err, info]
|
||||
Function SetCellStyle(sheet, TopLeft, BottomRight, styleid);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return array(0, o.SetCellStyle(TopLeft, BottomRight, styleid));
|
||||
return array(-1, '');
|
||||
End;
|
||||
|
||||
///获取单元格样式Id,获取到的Id可以在复制单元格样式时,作为调用 SetCellValue、或SetCellStyle 函数的参数使用。
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///返回: [err, datastyle: int]
|
||||
Function GetCellStyle(sheet, axis);
|
||||
Begin
|
||||
o := workbook_.GetSheetObj(sheet);
|
||||
if ifObj(o) then return array(0, o.GetCellStyle(axis));
|
||||
return array(-1, 'The sheet is not exist.');
|
||||
End;
|
||||
|
||||
///设置工作表页眉页脚
|
||||
///sheet:string,工作表名称
|
||||
///headerFooter: xlsxHeaderFooter对象
|
||||
///返回:[err, info]
|
||||
Function SetSheetHeaderFooter(sheet, headerFooter);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxHeaderFooter');
|
||||
if not ifObj(o) then return array(0, 'HeaderFooter对象不存在');
|
||||
o.SetHeaderFooter(headerFooter);
|
||||
return array(1, '');
|
||||
End
|
||||
|
||||
///设置工作表可见性
|
||||
///sheet: string, 工作表名称
|
||||
///visible: bool
|
||||
///返回:[err, info]
|
||||
Function SetSheetVisible(sheet, visible);
|
||||
Begin
|
||||
return workbook_.SetSheetVisible(sheet, visible);
|
||||
End
|
||||
|
||||
///获取工作表可见性
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, visibility: bool]
|
||||
Function GetSheetVisible(sheet);
|
||||
Begin
|
||||
return workbook_.GetSheetVisible(sheet);
|
||||
End;
|
||||
|
||||
///设置行可见性
|
||||
///sheet: string,工作表
|
||||
///row: int,行
|
||||
///visible: bool
|
||||
///返回: [err, info]
|
||||
Function SetRowVisible(sheet, row, visible)
|
||||
Begin
|
||||
return workbook_.SetRowVisible(sheet, row, visible);
|
||||
End
|
||||
|
||||
///获取工作表行可见性
|
||||
///sheet: string,工作表名称
|
||||
///row: int, 行
|
||||
///返回: [err, visible:int]
|
||||
Function GetRowVisble(sheet, row);
|
||||
Begin
|
||||
return workbook_.GetRowVisble(sheet, row);
|
||||
End
|
||||
|
||||
///设置列可见性
|
||||
///sheet: string,工作表
|
||||
///col: string,列,如:'A'
|
||||
///visible: bool
|
||||
///返回: [err, info]
|
||||
Function SetColVisible(sheet, col, visible)
|
||||
Begin
|
||||
[err, col] := ColumnNameToNumber(col);
|
||||
if err then return array(-1, col);
|
||||
return workbook_.SetColVisible(sheet, col, visible);
|
||||
End
|
||||
|
||||
///获取工作表列可见性
|
||||
///sheet: string,工作表名称
|
||||
///col: string,列
|
||||
///返回: [err, visible:int]
|
||||
Function GetColVisble(sheet, col);
|
||||
Begin
|
||||
[err, col] := ColumnNameToNumber(col);
|
||||
if err then return array(-1, col);
|
||||
return workbook_.GetColVisble(sheet, col);
|
||||
End
|
||||
|
||||
///设置工作表页边距
|
||||
///sheet: string,工作表名称
|
||||
///margins: TMargins 对象
|
||||
///返回: [err, info]
|
||||
Function SetPageMargins(sheet, margins);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxMargins');
|
||||
if not ifObj(o) then return array(0, 'The sheet is not exist');
|
||||
o.SetPageMargins(margins);
|
||||
return array(0, '');
|
||||
End;
|
||||
|
||||
///获取工作表页边距
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, info]
|
||||
///无错误时返回TMargins对象
|
||||
Function GetPageMargins(sheet);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxMargins');
|
||||
if not ifObj(o) then return array(0, 'The sheet is not exist');
|
||||
return o.GetPageMargins();
|
||||
End;
|
||||
|
||||
///合并单元格
|
||||
///sheet: string,工作表名称
|
||||
///hcell: string,左上角坐标
|
||||
///vcell: string,右下角坐标
|
||||
///返回: [err, info]
|
||||
Function MergeCell(sheet, hcell, vcell);
|
||||
Begin
|
||||
return workbook_.MergeCell(sheet, hcell, vcell);
|
||||
End;
|
||||
|
||||
///取消合并单元格
|
||||
///sheet: string,工作表名称
|
||||
///hcell: string,左上角坐标
|
||||
///vcell: string,右下角坐标
|
||||
///返回: [err, info]
|
||||
Function UnMergeCell(sheet, hcell, vcell);
|
||||
Begin
|
||||
return workbook_.UnMergeCell(sheet, hcell, vcell);
|
||||
End;
|
||||
|
||||
///设置工作表视图属性
|
||||
///sheet: string,工作表名称
|
||||
///viewIndex: int,视图索引
|
||||
///sheet: object,TSheetView对象
|
||||
///返回: [err, info]
|
||||
Function SetSheetViewOptions(sheet, viewIndex, sheetView);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxSheetView');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist');
|
||||
return o.SetSheetViewOptions(viewIndex, sheetView);
|
||||
End;
|
||||
|
||||
///获取工作表视图属性
|
||||
///sheet: string,工作表名称
|
||||
///viewindex: int,视图索引,viewIndex 可以是负数,如果是这样,则向后计数(-1 代表最后一个视图)
|
||||
///返回: [err, SheetView]
|
||||
Function GetSheetViewOptions(sheet, viewIndex);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxSheetView');
|
||||
if not ifObj(o) then return array(0, 'The sheet is not exist');
|
||||
return o.GetSheetViewOptions(viewIndex);
|
||||
End;
|
||||
|
||||
///设置工作表页面布局
|
||||
///sheet: string,工作表名称
|
||||
///pageLayout: pageLayout对象,属性:
|
||||
/// BlackAndWhite bool //BlackAndWhite specified print black and white.
|
||||
/// FirstPageNumber int //FirstPageNumber specified the first printed page number. If no value is specified, then 'automatic' is assumed.
|
||||
/// PageLayoutOrientation string //PageLayoutOrientation defines the orientation of page layout for a worksheet.
|
||||
/// PageLayoutPaperSize int //PageLayoutPaperSize defines the paper size of the worksheet.
|
||||
/// FitToHeight int //FitToHeight specified the number of vertical pages to fit on.
|
||||
/// FitToWidth int //FitToWidth specified the number of horizontal pages to fit on.
|
||||
/// PageLayoutScale int //PageLayoutScale defines the print scaling. This attribute is restricted to values ranging from 10 (10%) to 400 (400%). This setting is overridden when fitToWidth and/or fitToHeight are in use.
|
||||
///返回: [err, info]
|
||||
Function SetPageLayout(sheet, pageLayout);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxPageLayout');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist');
|
||||
return o.SetPageLayout(sheet, pageLayout);
|
||||
End;
|
||||
|
||||
///获取工作表页面布局
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, option:pageLayout对象]
|
||||
Function GetPageLayout(sheet);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxPageLayout');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist');
|
||||
return o.GetPageLayout();
|
||||
End;
|
||||
|
||||
///设置工作簿应用程序属性
|
||||
///appProps: TAppProperty对象,属性:
|
||||
/// Application string
|
||||
/// ScaleCrop bool
|
||||
/// DocSecurity int
|
||||
/// Company string
|
||||
/// LinksUpToDate bool
|
||||
/// HyperlinksChanged bool
|
||||
/// AppVersion string
|
||||
///返回: [err, info]
|
||||
Function SetAppProps(appProps);
|
||||
Begin
|
||||
o := getOj('', 'xlsxAppProperty');
|
||||
if not ifObj(o) then return array(1, 'AppProperty error!');
|
||||
return o.SetAppProps(appProps);
|
||||
End;
|
||||
|
||||
///获取应用程序属性
|
||||
///返回: [err, props:TAppProperty对象]
|
||||
Function GetAppProps();
|
||||
Begin
|
||||
o := getOj('', 'xlsxAppProperty');
|
||||
if not ifObj(o) then return array(1, 'AppProperty error!');
|
||||
return o.GetAppProps();
|
||||
End;
|
||||
|
||||
///sheet: string,工作表名称
|
||||
///返回: [err, info]
|
||||
Function SetDefaultSheet(sheet);
|
||||
Begin
|
||||
return workbook_.SetDefaultSheet(sheet);
|
||||
End
|
||||
|
||||
///返回:[err, sheet]
|
||||
Function GetDefaultSheet();
|
||||
Begin
|
||||
return workbook_.GetDefaultSheet();
|
||||
End
|
||||
|
||||
///设置工作表背景图片
|
||||
///pictrue: 图片对象
|
||||
///返回: [err, info]
|
||||
Function SetSheetBackground(sheet, pictrue);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxImage');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist.');
|
||||
return o.SetSheetBackground(sheet);
|
||||
End;
|
||||
|
||||
///设置超链接
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///hyplink:THyperLink对象
|
||||
///返回: [err, info]
|
||||
Function SetCellHyperLink(sheet, axis, hyperlink);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxHyperLink');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist.');
|
||||
return o.SetCellHyperLink(axis, hyperlink);
|
||||
End;
|
||||
|
||||
///获取超链接
|
||||
///sheet: string,工作表名称
|
||||
///axis: string,单元格,如"A7"
|
||||
///返回: [err, hyperlink: THyperLink对象]
|
||||
Function GetCellHyperLink(sheet, axis);
|
||||
Begin
|
||||
o := getOj(sheet, 'xlsxHyperLink');
|
||||
if not ifObj(o) then return array(1, 'The sheet is not exist.');
|
||||
return o.GetCellHyperLink(axis);
|
||||
End;
|
||||
|
||||
Function WorkBook();
|
||||
Begin
|
||||
return workbook_;
|
||||
End;
|
||||
|
||||
Function XmlObj();
|
||||
Begin
|
||||
return xml_;
|
||||
End;
|
||||
|
||||
Function Zip();
|
||||
Begin
|
||||
return zipfile_;
|
||||
End;
|
||||
|
||||
private
|
||||
Function getOj(sheetname, objname);
|
||||
Begin
|
||||
if not ifarray(objMgr_) then objMgr_:= array();
|
||||
k := sheetname + '.' + objname;
|
||||
o := objMgr_[ k ];
|
||||
if not ifnil(o) then return o;
|
||||
case objname of
|
||||
'xlsxMargin':
|
||||
o := class(xlsxMargin).NewObject(sheetname, self);
|
||||
'xlsxComment':
|
||||
o := class(xlsxComment).NewObject(sheetname, self);
|
||||
'xlsxStyles':
|
||||
o := class(xlsxStyles).NewObject(sheetname, self);
|
||||
'xlsxChart':
|
||||
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':
|
||||
o := class(xlsxPageLayout).NewObject(sheetname, self);
|
||||
'xlsxAppProperty':
|
||||
return class(xlsxAppProperty).NewObject(self);
|
||||
'xlsxImage':
|
||||
o := class(xlsxImage).NewObject(sheetname, self);
|
||||
'xlsxHyperLink':
|
||||
o := class(xlsxHyperLink).NewObject(sheetname, self);
|
||||
End;
|
||||
if ifObj(o) then objMgr_[k] := o;
|
||||
return o;
|
||||
End;
|
||||
|
||||
{
|
||||
TODO// 需要移除,待完成
|
||||
///设置工作表默认行高
|
||||
///sheet: string,工作表
|
||||
///height:double
|
||||
///返回: [err, info]
|
||||
Function SetSheetDefaultRowHeight(sheet, height);
|
||||
Begin
|
||||
return workbook_.SetSheetDefaultRowHeight(sheet, height);
|
||||
End
|
||||
|
||||
///获取工作表默认行高
|
||||
///sheet: string,工作表
|
||||
///返回: [err, height]
|
||||
Function GetSheetDefaultRowHeight(sheet);
|
||||
Begin
|
||||
return workbook_.GetSheetDefaultRowHeight(sheet);
|
||||
End
|
||||
}
|
||||
|
||||
|
||||
zipfile_; //压缩文件对象
|
||||
workbook_; //WorkBook对象
|
||||
xml_; //xlsxXml对象
|
||||
objMgr_; //各种对象缓存、管理
|
||||
End;
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
Type NodeInfo = class
|
||||
|
||||
public
|
||||
Function Create(name);
|
||||
Begin
|
||||
NodeName := name;
|
||||
ExtAttr := array();
|
||||
ExtNodes := array();
|
||||
End
|
||||
|
||||
Function GetAttrs(); virtual;
|
||||
Begin
|
||||
return ExtAttr;
|
||||
End
|
||||
|
||||
Function GetChildren(); virtual;
|
||||
Begin
|
||||
return ExtNodes;
|
||||
End
|
||||
|
||||
Function GetNode(index); // 返回的index的对象
|
||||
Begin
|
||||
return ExtNodes[index]['obj'];
|
||||
End
|
||||
|
||||
Function GetCount(); // 返回当前节点的个数
|
||||
Begin
|
||||
return length(ExtAttr);
|
||||
End
|
||||
|
||||
// arr := array('sz': 15, 'style': 'line');
|
||||
Function AddAttr(arr); // 添加属性
|
||||
Begin
|
||||
if not istable(arr) then return;
|
||||
ExtAttr union= arr;
|
||||
return 1;
|
||||
End
|
||||
|
||||
Function Marshal();
|
||||
Begin
|
||||
children := getChildrenEx();
|
||||
child_arr := array();
|
||||
len := 0;
|
||||
for i:=0 to length(children)-1 do
|
||||
begin
|
||||
node_type := children[i]['nodeType'];
|
||||
obj := children[i]['obj'];
|
||||
|
||||
if ifnil(obj) then continue;
|
||||
find := select thisrowindex as "rowindex_", * from child_arr where ['name'] = children[i]['name'] end;
|
||||
if not ifnil(obj) and not ifObj(obj) and istable(find) and ifstring(children[i]['attrEx']) and children[i]['attrEx'] <> '' then
|
||||
begin
|
||||
if not ifarray(find[0]['attributes']) then find[0]['attributes'] := array();
|
||||
key := children[i]['attrEx'];
|
||||
find[0]['attributes'] union= array(key : obj);
|
||||
child_arr[find[0]['rowindex_']]['attributes'] := find[0]['attributes'];
|
||||
continue;
|
||||
end
|
||||
|
||||
arr := array('type': 'element', 'name': children[i]['name'], 'attributes': array());
|
||||
if node_type = 'empty' then // <b/>
|
||||
begin
|
||||
// child_arr[len] := arr;
|
||||
// ++len;
|
||||
// continue;
|
||||
end
|
||||
else if node_type = 'pcdata' then
|
||||
begin
|
||||
arr['children'] := array(('type': 'pcdata', 'value': obj));
|
||||
end
|
||||
else if ifObj(obj) then
|
||||
begin
|
||||
marshal := obj.Marshal();
|
||||
if length(marshal['children'])=0 and length(marshal['attributes'])=0 then continue;
|
||||
arr['children'] := marshal['children'];
|
||||
arr['attributes'] union= marshal['attributes'];
|
||||
end
|
||||
else
|
||||
begin
|
||||
key := children[i]['attrName'] ? children[i]['attrName'] : children[i]['attrEx'] ? children[i]['attrEx'] : 'val';
|
||||
arr['attributes'] := array(key : obj);
|
||||
end
|
||||
|
||||
child_arr[len++] := arr;
|
||||
end
|
||||
|
||||
name_arr := str2array(NodeName, '/');
|
||||
tmp_arr := array('type': 'element', 'name': name_arr[length(name_arr)-1], 'children': child_arr);
|
||||
for i:=length(name_arr)-2 downto 0 do
|
||||
begin
|
||||
tmp_arr := array('type': 'element', 'name': name_arr[i], 'children': array(tmp_arr));
|
||||
end
|
||||
|
||||
attrs_arr := GetAttrs();
|
||||
valid_arr := array();
|
||||
for k, v in attrs_arr do
|
||||
begin
|
||||
if not ifnil(v) then valid_arr[k] := v;
|
||||
end
|
||||
tmp_arr['attributes'] := valid_arr;
|
||||
return tmp_arr;
|
||||
End
|
||||
|
||||
Function NewChildNode(nodeArr);
|
||||
Begin
|
||||
if not ifarray(nodeArr) then return 0;
|
||||
if not ifstring(nodeArr['name']) then return 0;
|
||||
arr := array(
|
||||
'name': nodeArr['name'],
|
||||
'obj': nodeArr['obj'],
|
||||
'attrEx': nodeArr['attrEx'],
|
||||
'nodeType': nodeArr['nodeType'],
|
||||
);
|
||||
ExtNodes union= arr;
|
||||
return 1;
|
||||
End
|
||||
private
|
||||
Function getChildrenEx();
|
||||
Begin
|
||||
r := GetChildren();
|
||||
a := array();
|
||||
for i:=0 to length(r)-1 do Begin
|
||||
if ifarray(r[i]['obj']) then Begin
|
||||
a union= r[i]['obj'];
|
||||
End
|
||||
else
|
||||
a[ length(a) ] := r[i];
|
||||
end;
|
||||
return a;
|
||||
End;
|
||||
public
|
||||
NodeName;
|
||||
ExtAttr;
|
||||
ExtNodes;
|
||||
|
||||
End
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
Type TSImage = Class
|
||||
Function Create(stream); overload;
|
||||
Begin
|
||||
content_ := stream;
|
||||
imageDef := array(('Png', 0, (0x89, 'P', 'N', 'G', 0x0d, 0x0a, 0x1a, 0x0a)),
|
||||
('Jfif',6,'JFIF'),
|
||||
('Exif',6,'Exif'),
|
||||
('Gif',0,'GIF87a'),
|
||||
('Gif',0,'GIF89a'),
|
||||
('Tiff',0,('M','M',0x00,'*')),
|
||||
('Tiff',0,('I', 'I', '*', 0x00)),
|
||||
('Bmp',0,'BM'));
|
||||
ind := getImageDef(stream, imageDef);
|
||||
if ind >= 0 then Begin
|
||||
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;
|
||||
|
||||
Function Width();
|
||||
Begin
|
||||
return integer((px_width / horz_dpi) * 914400);
|
||||
End;
|
||||
|
||||
Function Height();
|
||||
Begin
|
||||
return integer((px_height / vert_dpi) * 914400);
|
||||
End;
|
||||
(*
|
||||
Function exif_dimensions(stream, r);
|
||||
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;
|
||||
End;
|
||||
|
||||
Function _exif_next(start);
|
||||
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);
|
||||
End;
|
||||
|
||||
Function _offset_of_next_ff_byte(start);
|
||||
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);
|
||||
End;
|
||||
|
||||
Function _next_non_ff_byte(start);
|
||||
Begin
|
||||
for i:=start to length(content_)-1 do Begin
|
||||
byte_ := ord(content_[i]);
|
||||
if byte_ = 0xff then return start - 1;
|
||||
return start;
|
||||
End;
|
||||
*)
|
||||
Function tiff_dimensions(stream, r);
|
||||
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);
|
||||
End;
|
||||
|
||||
Function _read_int(stream, off, t, size);
|
||||
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;
|
||||
End;
|
||||
|
||||
Function bmp_dimensions(stream);
|
||||
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);
|
||||
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;
|
||||
End;
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
|
|
@ -0,0 +1,50 @@
|
|||
Type xlsxAppProperty = Class
|
||||
Function Create(file); overload;
|
||||
Begin
|
||||
file_ := file;
|
||||
End;
|
||||
|
||||
Function SetAppProps(appProps);
|
||||
Begin
|
||||
app_xml := file_.WorkBook().GetXmlFileObj('docProps/app.xml');
|
||||
node := app_xml.FirstChildElement('Properties');
|
||||
if not ifObj(node) then return array(1, "node::Properties can't be found");
|
||||
children_arr := appProps.Marshal()['children'];
|
||||
for i:=0 to length(children_arr)-1 do
|
||||
Begin
|
||||
if children_arr[i]['name'] in array('ScaleCrop', 'LinksUpToDate', 'SharedDoc', 'HyperlinksChanged') then
|
||||
Begin
|
||||
children_arr[i]['children'][0]['value'] := children_arr[i]['children'][0]['value'] ? "true" : "false";
|
||||
End
|
||||
delete_node := node.FirstChildElement(children_arr[i]['name']);
|
||||
node.InsertAfterChild(delete_node, children_arr[i]);
|
||||
node.DeleteChild(delete_node);
|
||||
End
|
||||
return array(0, '');
|
||||
End;
|
||||
|
||||
Function GetAppProps();
|
||||
Begin
|
||||
app_xml := file_.WorkBook().GetXmlFileObj('docProps/app.xml');
|
||||
node := app_xml.FirstChildElement('Properties');
|
||||
marshal := node.Marshal()[0]['children'];
|
||||
reindex(marshal, marshal[:,'name']);
|
||||
app_props := TOfficeObj('TAppProperty');
|
||||
app_props.Application := marshal['Application']['children'][0]['value'];
|
||||
app_props.DocSecurity := marshal['DocSecurity']['children'][0]['value'];
|
||||
app_props.ScaleCrop := marshal['DocSecurity']['children'][0]['value'] = "false" ? 0 : 1;
|
||||
app_props.Company := marshal['Company']['children'][0]['value'];
|
||||
app_props.LinksUpToDate := marshal['LinksUpToDate']['children'][0]['value'] = "false" ? 0 : 1;
|
||||
app_props.SharedDoc := marshal['SharedDoc']['children'][0]['value'] = "false" ? 0 : 1;
|
||||
app_props.AppVersion := marshal['AppVersion']['children'][0]['value'];
|
||||
return array(0, app_props);
|
||||
End
|
||||
|
||||
class Function NewObject(file);
|
||||
Begin
|
||||
return new xlsxAppProperty(file);
|
||||
End;
|
||||
|
||||
private
|
||||
file_; //TSExcelFile对象
|
||||
End;
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,170 @@
|
|||
Type xlsxComment = Class
|
||||
///缺省构造函数
|
||||
Function Create(sheet,excel); overload;
|
||||
Begin
|
||||
authors_ := array();
|
||||
excel_ := excel;
|
||||
sheetName_ := sheet;
|
||||
[rid, commentFileName_, sheetFileName_, relsfile] := excel_.WorkBook().GetRelationshipRid(sheet, '../comments');
|
||||
if commentFileName_ = '' then Begin
|
||||
rid++;
|
||||
rId_ := 'rId' + inttostr(rid);
|
||||
commentId_ := excel_.WorkBook().GetFilesCount('xl/comments') + 1;
|
||||
commentFileName_ := '../comments' + inttostr(commentId_) + '.xml';
|
||||
xlCommentFileName := 'xl/comments' + inttostr(commentId_) + '.xml';
|
||||
excel_.Zip().Add(xlCommentFileName, excel_.XmlObj().XmlHeader() + '<comments xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main"></comments>');
|
||||
excel_.WorkBook().AddRelationshipRid(relsfile, commentFileName_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments', rId_);
|
||||
rid ++;
|
||||
drawingVML_ := '../drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
||||
drawingVMLFile := 'xl/drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
||||
excel_.Zip().Remove(drawingVMLFile);
|
||||
excel_.Zip().Add(drawingVMLFile, '<xml
|
||||
xmlns:oa="urn:schemas-microsoft-com:office:activation"
|
||||
xmlns:p="urn:schemas-microsoft-com:office:powerpoint"
|
||||
xmlns:x="urn:schemas-microsoft-com:office:excel"
|
||||
xmlns:o="urn:schemas-microsoft-com:office:office"
|
||||
xmlns:v="urn:schemas-microsoft-com:vml">
|
||||
<o:shapelayout v:ext="edit">
|
||||
<o:idmap v:ext="edit" data="' + inttostr(commentId_) + '"/>
|
||||
</o:shapelayout>
|
||||
<v:shapetype id="_x0000_t202" coordsize="21600,21600" o:spt="202" path="m0,0l0,21600,21600,21600,21600,0xe">
|
||||
<v:stroke joinstyle="miter"/>
|
||||
<v:path gradientshapeok="t" o:connecttype="rect"/>
|
||||
</v:shapetype>
|
||||
</xml>');
|
||||
excel_.WorkBook().AddRelationshipRid(relsfile, drawingVML_, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing', 'rId' + inttostr(rid));
|
||||
excel_.WorkBook().AddContentType('application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml', '/' + xlCommentFileName);
|
||||
excel_.WorkBook().AddContentVml();
|
||||
|
||||
sheetXml := excel_.WorkBook().GetSheetXmlfile(sheetName_).FirstChildElement('worksheet');
|
||||
legacy := sheetXml.FirstChildElement('legacyDrawing');
|
||||
if not ifObj(legacy) then legacy := sheetXml.InsertEndChild('element', 'legacyDrawing');
|
||||
legacy.SetAttribute('r:id', 'rId' + inttostr(rid));
|
||||
End
|
||||
else Begin
|
||||
rId_ := 'rId' + inttostr(rid);
|
||||
xlCommentFileName := 'xl/' + ExtractFileName(commentFileName_);
|
||||
s := RightStr(xlCommentFileName, length(xlCommentFileName) - 11);
|
||||
commentId_ := strtoint(leftstr(s, length(s) - 4));
|
||||
drawingVML_ := './drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
||||
End;
|
||||
commentXmlFile_ := excel_.WorkBook().GetXmlFileObj(xlCommentFileName);
|
||||
authors := commentXmlFile_.FirstChildElement('comments').FirstChildElement('authors');
|
||||
if not ifObj(authors) then
|
||||
authors := commentXmlFile_.FirstChildElement('comments').InsertEndChild('element', 'authors');
|
||||
node := authors.FirstChildElement();
|
||||
i := 0;
|
||||
while ifObj(node) do Begin
|
||||
author := node.GetText();
|
||||
authors_[ author ] := i ++;
|
||||
node := node.NextElement();
|
||||
End;
|
||||
//println('sheet={},commentfile={},vmlfile={}',sheet, commentXmlFile_, drawingVML_);
|
||||
End;
|
||||
|
||||
class Function NewObject(sheet, excel);
|
||||
Begin
|
||||
excel_ := excel;
|
||||
o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在
|
||||
if not ifObj(o) then return 0;
|
||||
return new xlsxComment(sheet, excel);
|
||||
End;
|
||||
|
||||
Function AddComment(cell, author, comment);
|
||||
Begin
|
||||
authorId := authors_[author];
|
||||
if not ifint(authorId) then Begin
|
||||
authorId := length(authors_);
|
||||
commentXmlFile_.FirstChildElement('comments').FirstChildElement('authors').InsertEndChild('element', 'author', author);//添加作者
|
||||
authors_[author] := authorId;
|
||||
End;
|
||||
if not ifstring(comment) then return array(1, 'comment is not a string');
|
||||
comments := TOfficeObj('TComments');
|
||||
comments.Ref := cell;
|
||||
comments.AuthorId := authorId;
|
||||
authorObj := comments.AddComment(author + ':');
|
||||
arr := str2array(comment, '\n');
|
||||
colCount := length(author)+1;
|
||||
for i:=0 to length(arr)-1 do Begin
|
||||
line := TrimRight(arr[i]);
|
||||
if length(line) > colCount then colCount := length(line);
|
||||
End;
|
||||
lineCount := length(arr);
|
||||
commentObj := comments.AddComment('\n' + comment);
|
||||
commentObj.Font.Bold := nil;
|
||||
commentObj.Space := 'preserve';
|
||||
domData := comments.Marshal();
|
||||
node := getComment(cell);
|
||||
if ifObj(node) then
|
||||
node.DeleteChildren();
|
||||
else
|
||||
node := commentXmlFile_.FirstChildElement('comments').FirstChildElement('commentList').InsertEndChild('element', 'comment');
|
||||
node.UnMarshal(domData);
|
||||
//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/>
|
||||
<v:fill on="t" color2="#FFFFFF" focussize="0,0"/>
|
||||
<v:stroke color="#000000"/>
|
||||
<v:imagedata o:title=""/>
|
||||
<o:lock v:ext="edit" aspectratio="f"/>
|
||||
<v:textbox style="direction:context;layout-flow:horizontal;mso-rotate:0;">
|
||||
<div style="text-align:left"/>
|
||||
</v:textbox>
|
||||
<x:ClientData />
|
||||
</v:shape>';
|
||||
drawingVMLFile := 'xl/drawings/vmlDrawing' + inttostr(commentId_) + '.vml';
|
||||
xmlObj := excel_.WorkBook().GetXmlFileObj(drawingVMLFile);
|
||||
if ifObj(xmlObj) then Begin
|
||||
node := xmlObj.LastChildElement('xml').InsertEndChild('element','v:shape');
|
||||
node.UnMarshal(innerxml);
|
||||
node := node.FirstChildElement('x:ClientData');
|
||||
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.Row := row - 1;
|
||||
ClientData.Column := col - 1;
|
||||
node.UnMarshal(clientData.Marshal());
|
||||
commentObjs_[ length(commentObjs_) ] := array(cell, node);
|
||||
//xmlObj.Print;
|
||||
End;
|
||||
End;
|
||||
return array(0, 'ok');
|
||||
End;
|
||||
|
||||
Function getComment(cell);
|
||||
Begin
|
||||
if not ifarray(commentObjs_) then Begin
|
||||
commentObjs_ := array();
|
||||
node := commentXmlFile_.FirstChildElement('comments').FirstChildElement('commentList');
|
||||
if not ifObj(node) then
|
||||
node := commentXmlFile_.FirstChildElement('comments').InsertEndChild('element','commentList');
|
||||
node := node.FirstChildElement('comment');
|
||||
while ifObj(node) do Begin
|
||||
ref := node.GetAttribute('ref');
|
||||
commentObjs_[index++] := array(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'
|
||||
drawingVML_:string;//'../drawings/vmlDrawing1.xml'
|
||||
rId_:string;
|
||||
sheetName_:string;//sheet名称
|
||||
sheetFileName_;//xl/worksheets/sheetN.xml
|
||||
excel_;//TSExcelFile对象
|
||||
commentXmlFile_;//XmlFile对象
|
||||
commentObjs_;
|
||||
End;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Type xlsxHeaderFooter = Class
|
||||
|
||||
Function Create(sheetobj, file, xml);
|
||||
Begin
|
||||
sheet_ := sheetobj;
|
||||
file_ := file;
|
||||
xmlFile_ := xml;
|
||||
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 xlsxHeaderFooter(o, file, xml);
|
||||
End;
|
||||
|
||||
// 设置sheet的页面页脚
|
||||
Function SetHeaderFooter(headerFooter);
|
||||
Begin
|
||||
node := xmlFile_.FirstChildElement('worksheet');
|
||||
header_node := node.FirstChildElement('headerFooter');
|
||||
if ifObj(header_node) then
|
||||
node.DeleteChild(header_node);
|
||||
node.InsertEndChild(headerFooter.Marshal());
|
||||
End
|
||||
|
||||
private
|
||||
sheet_; //XmlSheet对象
|
||||
file_; //TSExcelFile对象
|
||||
xmlFile_; //sheet对应的xml对象
|
||||
End;
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
Type xlsxHyperLink = Class
|
||||
Function Create(sheetName, file, xmlFile); overload;
|
||||
Begin
|
||||
sheetName_ := sheetName;
|
||||
file_ := file;
|
||||
xmlFile_ := xmlFile;
|
||||
End;
|
||||
|
||||
class Function NewObject(sheetname, file);
|
||||
Begin
|
||||
xmlFile := file.WorkBook().GetSheetXmlfile(sheetname);
|
||||
return new xlsxHyperLink(sheetname, file, xmlFile);
|
||||
End;
|
||||
|
||||
Function SetCellHyperLink(axis, hyperlink);
|
||||
Begin
|
||||
work_node := xmlFile_.FirstChildElement('worksheet');
|
||||
hyperlinks := work_node.FirstChildElement('hyperlinks');
|
||||
if not ifObj(hyperlinks) then begin
|
||||
phone_node := work_node.FirstChildElement('phoneticPr');
|
||||
hyperlinks := work_node.InsertAfterChild(phone_node, 'element', 'hyperlinks');
|
||||
end;
|
||||
node := hyperlinks.FirstChildElement('hyperlink');
|
||||
while ifObj(node) do begin
|
||||
ref := node.GetAttribute('ref');
|
||||
if ref = axis then begin
|
||||
node := hyperlinks.DeleteChild(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
|
||||
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");
|
||||
End
|
||||
reindex(attrs, array('linkType': nil, 'linkUrl': nil));
|
||||
attrs['r:id'] := 'rId' + inttostr(rid);
|
||||
End
|
||||
marshal['attributes'] := attrs;
|
||||
hyperlinks.InsertEndChild(marshal);
|
||||
return array(0,'ok');
|
||||
End;
|
||||
|
||||
Function GetCellHyperLink(axis);
|
||||
Begin
|
||||
data := array();
|
||||
hyperlinks := xmlFile_.FirstChildElement('worksheet').FirstChildElement('hyperlinks');
|
||||
if not ifObj(hyperlinks) then return array(-1, 'Node::hyperlinks is not exist.');
|
||||
node := hyperlinks.FirstChildElement('hyperlink');
|
||||
while ifObj(node) do begin
|
||||
marshal := node.marshal()[0];
|
||||
attrs := marshal['attributes'];
|
||||
if attrs['ref'] = axis then
|
||||
begin
|
||||
link := TOfficeObj('THyperLink');
|
||||
link.LinkType := ifnil(attrs['location']) ? "External" : "Location";
|
||||
if not ifnil(attrs['location']) then
|
||||
link.LinkUrl := attrs['location'];
|
||||
else Begin
|
||||
rid := attrs['r:id'];
|
||||
file := 'xl/worksheets/_rels/' + ExtractFileName(LowerCase(sheetName_)) + '.xml.rels';
|
||||
xmlfile := file_.WorkBook().GetXmlFileObj(file);
|
||||
relnode := class(xlsxXml).FindRelationship(xmlfile, rid);
|
||||
if ifObj(relnode) then link.LinkUrl := relnode.GetAttribute('Target');
|
||||
End
|
||||
link.Display := attrs['display'];
|
||||
link.Tooltip := attrs['tooltip'];
|
||||
return array(0, link);
|
||||
end;
|
||||
node := node.NextElement();
|
||||
end;
|
||||
return array(-2, "The cell has no hyperlink.");
|
||||
End;
|
||||
|
||||
private
|
||||
file_; //TSExcelFile对象
|
||||
xmlFile_;//XmlFile对象
|
||||
sheetName_;
|
||||
|
||||
End;
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
Type xlsxImage = Class
|
||||
///缺省构造函数
|
||||
Function Create(sheet,excel); overload;
|
||||
Begin
|
||||
excel_ := excel;
|
||||
sheetName_ := sheet;
|
||||
[rid_, imageFileName_, sheetFileName_, xmlRelsFile_] := excel_.WorkBook().GetRelationshipRid(sheet, '../media/image');
|
||||
End;
|
||||
|
||||
class Function NewObject(sheet, excel);
|
||||
Begin
|
||||
excel_ := excel;
|
||||
o := excel_.WorkBook().GetSheetObj(sheet);//sheet存在
|
||||
if not ifObj(o) then return 0;
|
||||
return new xlsxImage(sheet, excel);
|
||||
End;
|
||||
|
||||
Function SetSheetBackground(pictrue);
|
||||
Begin
|
||||
//if not ifBinary(picture.Image) or length(picture.Image) = 0 then
|
||||
// raise "Invalid Image Data.";
|
||||
if imageFileName_ = '' then
|
||||
Begin
|
||||
rid_++;
|
||||
imageId := excel_.WorkBook().GetFilesCount('xl/media/') + 1;
|
||||
imageName := "../media/image" + inttostr(imageId);
|
||||
type := 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image';
|
||||
excel_.WorkBook().AddRelationshipRid(xmlRelsFile_, imageName, type, 'rId' + inttostr(rid_));
|
||||
End
|
||||
sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_);
|
||||
node := sheet_xml.FirstChildElement('worksheet');
|
||||
picture_node := node.FirstChildElement('picture');
|
||||
if ifObj(picture_node) then
|
||||
Begin
|
||||
node.DeleteChild(picture_node);
|
||||
End
|
||||
node := node.InsertEndChild('element', 'picture');
|
||||
node.SetAttribute('r:id', 'rId' + inttostr(rId_));
|
||||
End
|
||||
|
||||
private
|
||||
sheetName_:string; //sheet名称
|
||||
sheetFileName_; //xl/worksheets/sheetN.xml
|
||||
excel_;//TSExcelFile对象
|
||||
xmlRelsFile_;
|
||||
imageFileName_;
|
||||
rid_;
|
||||
End;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
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');
|
||||
work_node.DeleteChild(node);
|
||||
prev_node := work_node.FirstChild('phoneticPr');
|
||||
work_node.InsertAfterChild(prev_node, marshal);
|
||||
End;
|
||||
|
||||
Function GetPageMargins();
|
||||
Begin
|
||||
node := xmlFile_.FirstChild('worksheet').FirstChild('pageMargins');
|
||||
marshal := node.Marshal()[0];
|
||||
margins := TOfficeObj('tmargins');
|
||||
margins.Bottom := marshal['attributes']['bottom'];
|
||||
margins.Footer := marshal['attributes']['footer'];
|
||||
margins.Header := marshal['attributes']['header'];
|
||||
margins.Left := marshal['attributes']['left'];
|
||||
margins.Right := marshal['attributes']['right'];
|
||||
margins.Top := marshal['attributes']['top'];
|
||||
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;
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
Type xlsxPageLayout = Class
|
||||
Function Create(sheetobj, file, xml); overload;
|
||||
Begin
|
||||
sheet_ := sheetobj;
|
||||
file_ := file;
|
||||
xmlFile_ := xml;
|
||||
End;
|
||||
|
||||
Function SetPageLayout(sheet, pageLayout);
|
||||
Begin
|
||||
marshal := pageLayout.Marshal();
|
||||
work_node := xmlFile_.FirstChild('worksheet');
|
||||
node := work_node.FirstChild('pageSetUp');
|
||||
if ifObj(node) then work_node.DeleteChild(node);
|
||||
workbook_xml := file_.WorkBook().GetXmlFileObj('xl/workbook.xml');
|
||||
workbook := workbook_xml.FirstChildElement('workbook').FirstChildElement('sheets').FirstChildElement('sheet');
|
||||
if not ifObj(workbook) then return array(1, 'workbook error!');
|
||||
while ifObj(workbook) do
|
||||
Begin
|
||||
sheet_name := workbook.GetAttribute('name');
|
||||
if sheet_name = sheet then
|
||||
Begin
|
||||
rid := workbook.GetAttribute('r:id');
|
||||
break;
|
||||
End
|
||||
workbook := workbook.NextElement();
|
||||
End
|
||||
if not ifnil(marshal['attributes']['firstPageNumber']) then marshal['attributes']['useFirstPageNumber'] := 1;
|
||||
marshal['attributes']['r:id'] := rid;
|
||||
work_node.InsertEndChild(marshal);
|
||||
return array(0, '');
|
||||
End;
|
||||
|
||||
Function GetPageLayout();
|
||||
Begin
|
||||
node := xmlFile_.FirstChild('worksheet').FirstChild('pageSetUp');
|
||||
if not ifObj(node) then return array(1, '<node>: pageSetUp not found');
|
||||
marshal := node.Marshal()[0];
|
||||
page_layout := TOfficeObj('TPageLayout');
|
||||
page_layout.Scale := marshal['attributes']['scale'];
|
||||
page_layout.FitToWidth := marshal['attributes']['fitToWidth'];
|
||||
page_layout.FitToHeight := marshal['attributes']['fitToHeight'];
|
||||
page_layout.PaperSize := marshal['attributes']['paperSize'];
|
||||
page_layout.Orientation := marshal['attributes']['orientation'];
|
||||
page_layout.BlackAndWhite := marshal['attributes']['blackAndWhite'];
|
||||
page_layout.FirstPageNumber := marshal['attributes']['firstPageNumber'];
|
||||
page_layout.CellError := marshal['attributes']['errors'];
|
||||
page_layout.CellComments := marshal['attributes']['cellComments'];
|
||||
page_layout.Draft := marshal['attributes']['draft'];
|
||||
return page_layout;
|
||||
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 xlsxPageLayout(o, file, xml);
|
||||
End;
|
||||
|
||||
private
|
||||
file_; //TSExcelFile对象
|
||||
sheet_;//XmlSheet对象
|
||||
xmlFile_; //sheet对应的xml对象
|
||||
End;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
Type xlsxRichText = Class
|
||||
file_; //TSExcelFile对象
|
||||
sheet_;//XmlSheet对象
|
||||
Function Create(); overload;
|
||||
Begin
|
||||
End;
|
||||
|
||||
class Function NewObject(sheetname, self);
|
||||
Begin
|
||||
file_ := file;
|
||||
o = file_.WorkBook().GetSheetObj(sheetname);
|
||||
if not ifObj(o) then return 0;
|
||||
richTxt := new xlsxRichText();
|
||||
richTxt.sheet_ = o;
|
||||
richTxt.file_ := file;
|
||||
return richTxt;
|
||||
End;
|
||||
End;
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
Type xlsxSheetView = Class
|
||||
Function Create(sheetobj, file, xml); overload;
|
||||
Begin
|
||||
sheet_ := sheetobj;
|
||||
file_ := file;
|
||||
xmlFile_ := xml;
|
||||
End;
|
||||
|
||||
Function SetSheetViewOptions(viewIndex, 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
|
||||
Begin
|
||||
marshal := SheetView.Marshal();
|
||||
class(xlsxXml).UpdateNode(sheet_view_node, marshal['attributes'], array());
|
||||
return array(0, '');
|
||||
End
|
||||
sheet_view_node := sheet_view_node.NextElement();
|
||||
End
|
||||
return array(1, 'viewIndex not found : ' $ viewIndex);
|
||||
End;
|
||||
|
||||
Function GetSheetViewOptions(viewIndex, 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
|
||||
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'];
|
||||
return array(0, sheetView);
|
||||
End
|
||||
End
|
||||
return array(1, 'viewIndex not found : ' $ viewIndex);
|
||||
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 xlsxSheetView(o, file, xml);
|
||||
End;
|
||||
|
||||
private
|
||||
file_; //TSExcelFile对象
|
||||
sheet_;//XmlSheet对象
|
||||
xmlFile_; //sheet对应的xml对象
|
||||
End;
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
Type xlsxStyles = Class
|
||||
|
||||
Function Create(sheetobj, file);
|
||||
Begin
|
||||
sheet_ := sheetobj;
|
||||
file_ := file;
|
||||
styleXmlFile_ := file_.WorkBook().GetXmlFileObj('xl/styles.xml');
|
||||
End
|
||||
|
||||
Function GetStyleId(style);
|
||||
Begin
|
||||
node := styleXmlFile_.FirstChildElement('styleSheet');
|
||||
font_id := insertNode(node, 'fonts', style.Font);
|
||||
border_id := insertNode(node, 'borders', style.Border);
|
||||
fill_id := insertNode(node, 'fills', style.Fill);
|
||||
|
||||
processNumFmtId(node, 'numFmts', style.NumberFormat);
|
||||
numfmt_id := insertNode(node, 'numFmts', style.NumberFormat);
|
||||
|
||||
// 整理插入节点内容
|
||||
child_arr := array();
|
||||
alignment_marshal := style.Alignment.Marshal();
|
||||
if istable(alignment_marshal['children']) or istable(alignment_marshal['attributes']) then
|
||||
begin
|
||||
alignment_flag := 1;
|
||||
child_arr union= array(alignment_marshal);
|
||||
end
|
||||
protection_marshal := style.Protection.Marshal();
|
||||
if istable(protection_marshal['children']) or istable(protection_marshal['attributes']) then
|
||||
begin
|
||||
protection_flag := 1;
|
||||
child_arr union= array(protection_marshal);
|
||||
end
|
||||
|
||||
attr_arr := array(
|
||||
'numFmtId': style.NumberFormat.NumFmtId ? : "0",
|
||||
'fontId': font_id,
|
||||
'fillId': fill_id,
|
||||
'borderId': border_id,
|
||||
'xfId': 0,
|
||||
);
|
||||
if font_id <> '0' then attr_arr['applyFont'] := '1';
|
||||
if border_id <> '0' then attr_arr['applyBorder'] := '1';
|
||||
if numfmt_id <> '0' then attr_arr['applyNumberFormat'] := '1';
|
||||
if fill_id <> '0' then attr_arr['applyFill'] := '1';
|
||||
if alignment_flag then attr_arr['applyAlignment'] := '1';
|
||||
if protection_flag then attr_arr['applyProtection'] := '1';
|
||||
|
||||
arr := array('name': 'xf', 'type': 'element',
|
||||
'attributes': attr_arr,
|
||||
'children': child_arr,
|
||||
);
|
||||
node := node.FirstChildElement('cellXfs');
|
||||
count := node.GetAttribute('count');
|
||||
node.InsertEndChild(arr);
|
||||
node.SetAttribute('count', strtoint(count) + 1);
|
||||
//node.print;
|
||||
return count;
|
||||
End
|
||||
|
||||
class Function NewObject(sheetname, file);
|
||||
Begin
|
||||
o := file.WorkBook().GetSheetObj(sheetname);
|
||||
if not ifObj(o) then return 0;
|
||||
styles := new xlsxStyles(o, file);
|
||||
return styles;
|
||||
End;
|
||||
|
||||
private
|
||||
Function insertNode(rootNode, childName, obj);
|
||||
Begin
|
||||
marshal := obj.Marshal();
|
||||
if not istable(marshal['children']) and not istable(marshal['attributes']) then return '0';
|
||||
node := rootNode.FirstChildElement(childName);
|
||||
if not ifObj(node) then
|
||||
begin
|
||||
info := array('name': childName, 'type': 'element', 'attributes': ('count': '0'));
|
||||
rootNode.InsertFirstChild(info);
|
||||
node := rootNode.FirstChildElement(childName);
|
||||
end
|
||||
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;
|
||||
node := rootNode.FirstChildElement(childName);
|
||||
if not ifObj(node) then obj.numFmtId := '1';
|
||||
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
|
||||
end
|
||||
End
|
||||
|
||||
private
|
||||
sheet_; //XmlSheet对象
|
||||
file_; //TSExcelFile对象
|
||||
styleXmlFile_; //xmlFile对象
|
||||
End;
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue