v1.5.8
This commit is contained in:
parent
a774f57335
commit
522e52ed46
|
|
@ -1,4 +1,4 @@
|
|||
// Version 1.5.7
|
||||
// Version 1.5.8
|
||||
Function TOfficeObj(n);
|
||||
Begin
|
||||
case lowercase(n) of
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Version 1.5.7
|
||||
// Version 1.5.8
|
||||
Type TSDocxFile = Class
|
||||
///Version: V1.0 2022-09-20
|
||||
///适用于 Microsoft Word docx格式文件
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// Version 1.5.7
|
||||
// Version 1.5.8
|
||||
Type TSXlsxFile = Class
|
||||
///Version: V1.0 2022-08-08
|
||||
///适用于 Microsoft Excel? 2007 及以上版本创建的电子表格文档。支持 XLSX / XLSM / XLTM / XLTX 等多种文档格式。
|
||||
|
|
@ -8,7 +8,7 @@ Type TSXlsxFile = Class
|
|||
///缺省构造函数
|
||||
Function Create(); overload;
|
||||
Begin
|
||||
init();
|
||||
Init();
|
||||
End;
|
||||
|
||||
///构造函数,打开已经存在的excel文件
|
||||
|
|
@ -16,7 +16,7 @@ Type TSXlsxFile = Class
|
|||
///fname: string,文件名
|
||||
Function Create(alias, fname); overload;
|
||||
Begin
|
||||
init();
|
||||
Init();
|
||||
OpenFile(alias, fname, nil);
|
||||
End;
|
||||
|
||||
|
|
@ -26,17 +26,12 @@ Type TSXlsxFile = Class
|
|||
///passwd: string,密码
|
||||
Function Create(alias, fname, passwd); overload;
|
||||
Begin
|
||||
init();
|
||||
Init();
|
||||
OpenFile(alias, fname, passwd);
|
||||
End;
|
||||
|
||||
//析构函数
|
||||
Function Destory();
|
||||
Begin
|
||||
End;
|
||||
|
||||
//初始化
|
||||
Function init();
|
||||
Function Init();
|
||||
Begin
|
||||
zipfile_ := new ZipFile();
|
||||
End;
|
||||
|
|
@ -51,24 +46,17 @@ Type TSXlsxFile = Class
|
|||
if not ifObj(zipfile_) then return array(-1, 'Create ZipFile object fail.');
|
||||
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();
|
||||
End;
|
||||
if err=0 then InitVars();
|
||||
return array(err, errmsg);
|
||||
End;
|
||||
|
||||
///新建excel文件
|
||||
///返回: [err, info]
|
||||
///返回: [err, errmsg]
|
||||
Function NewFile();
|
||||
Begin
|
||||
def := TOfficeTemplate('default.xlsx', true);
|
||||
[err, errmsg] := zipfile_.LoadFromMem(def);
|
||||
if err = 0 then
|
||||
begin
|
||||
workbook_ := new xlsxWorkBook(zipfile_);
|
||||
workbook_.Load();
|
||||
end
|
||||
if err = 0 then InitVars();
|
||||
return array(err, errmsg);
|
||||
End;
|
||||
|
||||
|
|
@ -91,11 +79,7 @@ Type TSXlsxFile = Class
|
|||
Function LoadFromMem(data);
|
||||
Begin
|
||||
[err, errmsg] := zipfile_.LoadFromMem(data);
|
||||
if err = 0 then
|
||||
begin
|
||||
workbook_ := new xlsxWorkBook(zipfile_);
|
||||
workbook_.Load();
|
||||
end
|
||||
if err = 0 then InitVars();
|
||||
return array(err, errmsg);
|
||||
End;
|
||||
|
||||
|
|
@ -128,9 +112,7 @@ Type TSXlsxFile = Class
|
|||
Begin
|
||||
sheets := workbook_.GetSheets();
|
||||
for i:=0 to length(sheets)-1 do
|
||||
begin
|
||||
sheets[i] := class(TSXml).Utf8ToCurCodePage(sheets[i]);
|
||||
end
|
||||
return sheets;
|
||||
End;
|
||||
|
||||
|
|
@ -238,6 +220,8 @@ Type TSXlsxFile = Class
|
|||
Begin
|
||||
sheet_name := class(TSXml).CurCodePageToUtf8(sheet);
|
||||
value := class(TSXml).CurCodePageToUtf8(val);
|
||||
// 处理cell设定的样式
|
||||
SetCellType(sheet, axis, value, opt);
|
||||
return workbook_.SetCellValue(sheet_name, axis, value, opt);
|
||||
End;
|
||||
|
||||
|
|
@ -1012,6 +996,22 @@ Type TSXlsxFile = Class
|
|||
End;
|
||||
|
||||
private
|
||||
Function InitVars();
|
||||
Begin
|
||||
workbook_ := new xlsxWorkBook(zipfile_);
|
||||
workbook_.Load();
|
||||
style_ := new xlsxStyles(self);
|
||||
End;
|
||||
|
||||
Function SetCellType(sheet, axis, val, opt);
|
||||
Begin
|
||||
if not ifarray(opt) then opt := array();
|
||||
if not ifnil(opt['t']) then return;
|
||||
styleid := GetCellStyle(sheet, axis);
|
||||
[t, val] := style_.GetType(styleid, val);
|
||||
if t then opt['t'] := t;
|
||||
End;
|
||||
|
||||
Function getOj(sheet, objname);
|
||||
Begin
|
||||
sheetname := class(TSXml).CurCodePageToUtf8(sheet);
|
||||
|
|
@ -1020,12 +1020,8 @@ private
|
|||
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':
|
||||
|
|
@ -1052,5 +1048,6 @@ private
|
|||
zipfile_; //压缩文件对象
|
||||
workbook_; //WorkBook对象
|
||||
objMgr_; //各种对象缓存、管理
|
||||
style_;
|
||||
End;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,15 +1,29 @@
|
|||
Type xlsxStyles = Class
|
||||
|
||||
Function Create(sheetobj, file);
|
||||
Function Create(file);
|
||||
Begin
|
||||
sheet_ := sheetobj;
|
||||
file_ := file;
|
||||
styleXmlFile_ := file_.WorkBook().GetXmlFileObj('xl/styles.xml');
|
||||
style_xml_file_ := file_.WorkBook().GetXmlFileObj('xl/styles.xml');
|
||||
style_ := array();
|
||||
Init();
|
||||
End
|
||||
|
||||
Function Init();
|
||||
Begin
|
||||
style_node := style_xml_file_.FirstChildElement("styleSheet");
|
||||
xfs_node := style_node.FirstChildElement("cellXfs");
|
||||
xf_node := xfs_node.FirstChildElement("xf");
|
||||
count := 0;
|
||||
while ifObj(xf_node) do
|
||||
begin
|
||||
style_[inttostr(count++)] := xf_node;
|
||||
xf_node := xf_node.NextElement("xf");
|
||||
end
|
||||
End
|
||||
|
||||
Function GetStyleId(style);overload;
|
||||
Begin
|
||||
node := styleXmlFile_.FirstChildElement('styleSheet');
|
||||
node := style_xml_file_.FirstChildElement('styleSheet');
|
||||
font_id := insertNode(node, 'fonts', style.Font);
|
||||
border_id := insertNode(node, 'borders', style.Border);
|
||||
fill_id := insertNode(node, 'fills', style.Fill);
|
||||
|
|
@ -40,15 +54,16 @@ Type xlsxStyles = Class
|
|||
|
||||
node := node.FirstChildElement('cellXfs');
|
||||
count := node.GetAttribute('count');
|
||||
node.InsertEndChild(xf.Marshal());
|
||||
node.SetAttribute('count', strtoint(count) + 1);
|
||||
xf_node := node.InsertEndChild(xf.Marshal());
|
||||
style_[count] := xf_node;
|
||||
return count;
|
||||
End;
|
||||
|
||||
Function GetStyleId(newStyle, oldStyleId);overload;
|
||||
Begin
|
||||
if oldStyleId = '' then return nil;
|
||||
style_node := styleXmlFile_.FirstChildElement('styleSheet');
|
||||
style_node := style_xml_file_.FirstChildElement('styleSheet');
|
||||
cellXfs_node := style_node.FirstChildElement('cellXfs');
|
||||
count := strtoint(cellXfs_node.GetAttribute('count'));
|
||||
Id := strtoint(oldStyleId);
|
||||
|
|
@ -89,19 +104,14 @@ Type xlsxStyles = Class
|
|||
xf_node.SetAttribute('applyProtection', 1);
|
||||
end
|
||||
|
||||
style_[inttostr(count)] := xf_node;
|
||||
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);
|
||||
xf := style_[styleId];
|
||||
if not ifObj(xf) then return nil;
|
||||
attrs := xf.Attributes();
|
||||
numfmt_id := trystrtoint(attrs['numFmtId'], r) ? r : 0;
|
||||
font_id := trystrtoint(attrs['fontId'], r) ? r : 0;
|
||||
|
|
@ -110,6 +120,7 @@ Type xlsxStyles = Class
|
|||
|
||||
alignment := xf.FirstChildElement('alignment');
|
||||
protection := xf.FirstChildElement('protection');
|
||||
style_node := style_xml_file_.FirstChildElement('styleSheet');
|
||||
style := TOfficeObj('TStyle');
|
||||
numFmts_node := style_node.FirstChildElement('numFmts');
|
||||
fonts_node := style_node.FirstChildElement('fonts');
|
||||
|
|
@ -127,12 +138,51 @@ Type xlsxStyles = Class
|
|||
return style;
|
||||
End;
|
||||
|
||||
class Function NewObject(sheetname, file);
|
||||
Function GetNumFmtId(styleId);
|
||||
Begin
|
||||
o := file.WorkBook().GetSheetObj(sheetname);
|
||||
if not ifObj(o) then return 0;
|
||||
styles := new xlsxStyles(o, file);
|
||||
return styles;
|
||||
node := style_[styleId];
|
||||
if ifnil(node) then return '0';
|
||||
numfmt := node.GetAttribute("numFmtId");
|
||||
return numfmt = '' ? '' : numfmt;
|
||||
End;
|
||||
|
||||
Function GetType(styleId, value);
|
||||
Begin
|
||||
numfmt_id := GetNumFmtId(styleId);
|
||||
if numfmt_id = '' then return array(nil, value);
|
||||
numfmt_id := strtoint(numfmt_id);
|
||||
if numfmt_id = 0 then return array(nil, value);
|
||||
if numfmt_id >= 1 and numfmt_id <= 10 then return array('n', value);
|
||||
if numfmt_id >= 11 and numfmt_id <= 26 then
|
||||
begin
|
||||
if ifstring(value) and (trystrtodate(value, r) or trystrtodatetime(value, r)) then return array('n', r);
|
||||
t := ifstring(value) ? 's' : 'n';
|
||||
return array(t, value);
|
||||
end
|
||||
if numfmt_id >= 27 and numfmt_id <= 34 then return array('e', value);
|
||||
if numfmt_id >= 35 and numfmt_id <= 48 then return array('n', trystrtofloat(value, r) ? r : value);
|
||||
if numfmt_id = 49 then return array('s', value);
|
||||
if numfmt_id >= 50 and numfmt_id <= 55 then
|
||||
begin
|
||||
if ifstring(value) and trystrtodate(value, r) then return array('n', r);
|
||||
t := ifstring(value) ? 's' : 'n';
|
||||
return array(t, value);
|
||||
end
|
||||
if numfmt_id >= 56 and numfmt_id <= 58 then
|
||||
begin
|
||||
if ifstring(value) and trystrtodatetime(value, r) then return array('n', r);
|
||||
t := ifstring(value) ? 's' : 'n';
|
||||
return array(t, value);
|
||||
end
|
||||
else begin
|
||||
if ifstring(value) then
|
||||
begin
|
||||
if trystrtodatetime(value, r) or trystrtodate(value, r) then return array('n', r);
|
||||
if trystrtofloat(value, r) then return array("n", value);
|
||||
return array("s", value);
|
||||
end
|
||||
return array("n", value);
|
||||
end
|
||||
End;
|
||||
|
||||
private
|
||||
|
|
@ -286,7 +336,65 @@ private
|
|||
End
|
||||
|
||||
private
|
||||
sheet_; //XmlSheet对象
|
||||
file_; //TSExcelFile对象
|
||||
styleXmlFile_; //xmlFile对象
|
||||
file_; //TSXlsxFile对象
|
||||
style_xml_file_;
|
||||
style_; // 缓存style
|
||||
End;
|
||||
|
||||
// {*
|
||||
// 也可参考: https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.wordprocessing.numberingformat?view=openxml-3.0.1
|
||||
// numfmtid为1表示数值格式,即显示为整数或小数,且根据系统设置或区域设置来决定小数点、千位分隔符和负数的显示方式。
|
||||
// numfmtid为2表示货币格式,即显示为带有货币符号的数值,且根据系统设置或区域设置来决定货币符号、小数点、千位分隔符和负数的显示方式。
|
||||
// numfmtid为3表示会计格式,即显示为带有货币符号和千位分隔符的数值,且根据系统设置或区域设置来决定货币符号、小数点和负数的显示方式。会计格式的特点是货币符号和数值之间有一定的空格,且小数位数固定为2。
|
||||
// numfmtid为4表示百分比格式,即显示为带有百分号的数值,且根据系统设置或区域设置来决定小数点和负数的显示方式。
|
||||
// numfmtid为5表示千位分隔符格式,即显示为带有千位分隔符的数值。
|
||||
// numfmtid为6表示负数红色格式,即显示为带有负号和红色字体的数值。
|
||||
// numfmtid为7表示千位分隔符格式,即显示为带有千位分隔符的数值,且根据系统设置或区域设置来决定小数点和负数的显示方式。
|
||||
// numfmtid为8表示负数红色格式,即显示为带有负号和红色字体的数值,且根据系统设置或区域设置来决定小数点和千位分隔符的显示方式。
|
||||
// numfmtid为9表示分数格式,即显示为分数形式的数值,且根据系统设置或区域设置来决定负数的显示方式。分数格式的特点是分子和分母都是一位数,例如1/2。
|
||||
// numfmtid为10表示指数格式,即显示为带有小数点和指数的数值。
|
||||
// numfmtid为11表示日期时间格式,即显示为年/月/日 时:分的形式。
|
||||
// numfmtid为12表示时间格式,即显示为时:分:秒的形式。
|
||||
// numfmtid为13表示时间格式,即显示为上午/下午 时:分的形式。
|
||||
// numfmtid为16表示日期格式,即显示为月/日/年的形式。
|
||||
// numfmtid为17表示日期格式,即显示为日-月-年的形式。
|
||||
// numfmtid为18表示日期格式,即显示为年-月-日的形式。
|
||||
// numfmtid为19表示日期格式,即显示为月-年的形式。
|
||||
// numfmtid为20表示日期格式,即显示为年-月的形式。
|
||||
// numfmtid为21表示日期时间格式,即显示为年/月/日 时:分:秒的形式。
|
||||
// numfmtid为22表示日期时间格式,即显示为年/月/日 上午/下午 时:分的形式。
|
||||
// numfmtid为23表示时间格式,即显示为时:分的形式,带有前导零。
|
||||
// numfmtid为24表示时间格式,即显示为时:分:秒的形式,带有前导零。
|
||||
// numfmtid为25表示时间格式,即显示为上午/下午 时:分的形式,带有前导零。
|
||||
// numfmtid为26表示时间格式,即显示为上午/下午 时:分:秒的形式,带有前导零。
|
||||
// numfmtid为27表示错误值格式,即显示为#NULL!。
|
||||
// numfmtid为28表示错误值格式,即显示为#DIV/0!。
|
||||
// numfmtid为29表示错误值格式,即显示为#VALUE!。
|
||||
// numfmtid为30表示错误值格式,即显示为#REF!。
|
||||
// numfmtid为31表示错误值格式,即显示为#NAME?。
|
||||
// numfmtid为32表示错误值格式,即显示为#NUM!。
|
||||
// numfmtid为33表示错误值格式,即显示为#N/A。
|
||||
// numfmtid为34表示错误值格式,即显示为#GETTING_DATA。
|
||||
// numfmtid为36表示货币格式,即显示为带有货币符号和负数红色的数值。
|
||||
// numfmtid为38表示会计格式,即显示为带有货币符号和负数红色的数值,且小数位数为2。
|
||||
// numfmtid为39表示会计格式,即显示为带有货币符号和负数红色的数值,且小数位数为0。
|
||||
// numfmtid为40表示会计格式,即显示为带有货币符号和负数红色的数值,且小数位数为4。
|
||||
// numfmtid为41表示货币格式,即显示为带有货币符号和千位分隔符的数值,且小数位数为2。
|
||||
// numfmtid为42表示货币格式,即显示为带有货币符号和千位分隔符的数值,且小数位数为0。
|
||||
// numfmtid为43表示货币格式,即显示为带有货币符号和千位分隔符的数值,且小数位数为4。
|
||||
// numfmtid为44表示货币格式,即显示为带有货币符号和千位分隔符的数值,且负数红色,且小数位数为2。
|
||||
// numfmtid为45表示货币格式,即显示为带有货币符号和千位分隔符的数值,且负数红色,且小数位数为0。
|
||||
// numfmtid为46表示货币格式,即显示为带有货币符号和千位分隔符的数值,且负数红色,且小数位数为4。
|
||||
// numfmtid为47表示会计格式,即显示为带有货币符号和千位分隔符的数值,且小数位数为2。
|
||||
// numfmtid为48表示会计格式,即显示为带有货币符号和千位分隔符的数值,且小数位数为0。
|
||||
// numfmtid为49表示文本格式,即显示为文本。
|
||||
// numfmtid为50表示日期格式,即显示为年/月/日的形式,带有前导零。
|
||||
// numfmtid为51表示日期格式,即显示为月/日/年的形式,带有前导零。
|
||||
// numfmtid为52表示日期格式,即显示为日-月-年的形式,带有前导零。
|
||||
// numfmtid为53表示日期格式,即显示为年-月-日的形式,带有前导零。
|
||||
// numfmtid为54表示日期格式,即显示为月-年的形式,带有前导零。
|
||||
// numfmtid为55表示日期格式,即显示为年-月的形式,带有前导零。
|
||||
// numfmtid为56表示日期时间格式,即显示为年/月/日 时:分:秒的形式,带有前导零。
|
||||
// numfmtid为57表示日期时间格式,即显示为年/月/日 上午/下午 时:分的形式,带有前导零。
|
||||
// numfmtid为58表示日期时间格式,即显示为年/月/日 上午/下午 时:分:秒的形式,带有前导零。
|
||||
// *}
|
||||
|
|
|
|||
14
更新日志.md
14
更新日志.md
|
|
@ -1,12 +1,20 @@
|
|||
# 更新日志
|
||||
|
||||
## 2023-1-18
|
||||
|
||||
### V1.5.8
|
||||
|
||||
#### excel
|
||||
|
||||
1. 支持写入单元格内容时判断当前单元格的数据类型,并以单元格数据类型为准
|
||||
|
||||
## 2023-1-17
|
||||
|
||||
### V1.5.7
|
||||
|
||||
#### excel
|
||||
|
||||
1. 修复单元格写入浮点数数据bug,如写入0.0,excel某些版本打开会显示0.00000000000000000
|
||||
1. 修复单元格写入浮点数数据 bug,如写入 0.0,excel 某些版本打开会显示 0.00000000000000000
|
||||
|
||||
## 2023-1-11
|
||||
|
||||
|
|
@ -42,7 +50,7 @@
|
|||
|
||||
#### excel
|
||||
|
||||
1. 支持写入单元格时且单元格不存在时,新的单元格会沿用设置的样式ID(若有设置)
|
||||
1. 支持写入单元格时且单元格不存在时,新的单元格会沿用设置的样式 ID(若有设置)
|
||||
|
||||
## 2023-12-1
|
||||
|
||||
|
|
@ -56,7 +64,7 @@
|
|||
|
||||
### V1.5.1
|
||||
|
||||
1. 支持识别图片中含有`0xffc2`段的jpg格式的大小
|
||||
1. 支持识别图片中含有`0xffc2`段的 jpg 格式的大小
|
||||
|
||||
## 2023-11-14
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue