From 77762ce275feeb6526eaed2abf40b0acca8e167c Mon Sep 17 00:00:00 2001 From: csh Date: Tue, 18 Apr 2023 15:34:45 +0800 Subject: [PATCH] v1.3.0 --- Demo/excel_demo.tsl | 125 ++++++--- Windows-X64/office_plugin.dll | Bin 226816 -> 226816 bytes funcext/TSOffice/TOfficeObj.tsf | 2 +- funcext/TSOffice/TSDocxFile.tsf | 2 +- funcext/TSOffice/TSExcelFile.tsf | 2 +- funcext/TSOffice/TSUtils/NodeInfo.tsf | 2 + funcext/TSOffice/TSUtils/TSImage.tsf | 323 +++++++++-------------- funcext/TSOffice/worksheet/xlsxImage.tsf | 21 +- 更新日志.md | 10 + 9 files changed, 244 insertions(+), 243 deletions(-) diff --git a/Demo/excel_demo.tsl b/Demo/excel_demo.tsl index e03bb94..db0ce06 100644 --- a/Demo/excel_demo.tsl +++ b/Demo/excel_demo.tsl @@ -6,7 +6,7 @@ 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 @@ -14,14 +14,13 @@ 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(); @@ -43,6 +42,14 @@ println("[success] GetSheetName = {}", Name); 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); @@ -93,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 @@ -134,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 @@ -165,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), @@ -219,6 +229,12 @@ 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 [h, s, l] := excel.RGBToHSL(255, 15, 33); println("[success] {} = {}, {}, {}", "RGBToHSL", h, s, l); @@ -259,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; @@ -274,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"); @@ -290,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); @@ -332,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); @@ -345,6 +377,7 @@ println("[success] MergeCell"); excel.UnMergeCell(sheetName2, "A4", "C4"); println("[success] UnMergeCell"); + // SetSheetViewOptions sheetView := TOfficeObj('TSheetView'); sheetView.ShowGridLines := false; @@ -372,6 +405,7 @@ println("[success] SetPane"); pageLayout := TOfficeObj('TPageLayout'); pageLayout.FitToWidth := 10; pageLayout.FitToHeight := 10; +pageLayout.UseFirstPageNumber := true; pageLayout.FirstPageNumber := 5; pageLayout.Orientation := "portrait"; pageLayout.BlackAndWhite := true; @@ -412,9 +446,10 @@ hyperlink := excel.GetCellHyperLink(sheetName2, 'A2'); 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"); @@ -528,30 +563,50 @@ 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 - diff --git a/Windows-X64/office_plugin.dll b/Windows-X64/office_plugin.dll index 8fb3c481008d5703afac5d0635d2a0075bc97f54..bee3d4cf9cc754c831a835057377b3c89958a68f 100644 GIT binary patch delta 500 zcmYk0JxClu7=~wWS3$*I5HW(NW&8mfqnJG}2>x93w4a&%^hS4Q&u?eZ1K}ja6(XV_ z2y3B5iuAHxEu=`Q6d`@$!Chl379wVLlLL$4nfLvE-tXYP`{2I&WXgDR`p&M5RFB@e z%{$(DaJj?xwf=e0&%KmQR!P}lPRc*5n6l2cG>0$iOlp2Vt}|cLZPxiW%{XeLeR0%G z>v43)l6`U1m+pMNk zU6Z>)I)pUNN0-cA(xd8 delta 508 zcmYk0u}d656vp4)ZqkUsK9Mw{5ChRBRf6d1iEuHex!BLlzUbiI?D=L^JuU7`VHH9` zit7TBD$51}0WWR-fDkN9ER6?Bz$TS~MKZg3;K1;k?|X0F_nN1@&C}jDkDR`@kNw8O z&#y*k??`m-=EoJmt^WS$uFyG8ILmp=H*)^wt2sN|Snho2@S5eXuN}T(NqZgf(=thq z^S&fK$?Hja#It!x+Mmx&(!)&O5%W?kW#Mpj%2NQr_D#6e9Q-ou>=)jRxP33ZZO_^D z3Ii9ewcA7g3O^>C*X^@$_pHbN)v)+ttYc?f8$1jn`OJ*#Vj)rzd*xGu^NvlrZVCZ%TFs=T=*IWemHEDSYlwa1>i-v<8!0glzs diff --git a/funcext/TSOffice/TOfficeObj.tsf b/funcext/TSOffice/TOfficeObj.tsf index c276b93..1e5edfa 100644 --- a/funcext/TSOffice/TOfficeObj.tsf +++ b/funcext/TSOffice/TOfficeObj.tsf @@ -1,4 +1,4 @@ -// Version 1.2.9 +// Version 1.3.0 Function TOfficeObj(n); Begin diff --git a/funcext/TSOffice/TSDocxFile.tsf b/funcext/TSOffice/TSDocxFile.tsf index 46d8da6..b8d8b1f 100644 --- a/funcext/TSOffice/TSDocxFile.tsf +++ b/funcext/TSOffice/TSDocxFile.tsf @@ -1,4 +1,4 @@ -// Version 1.2.9 +// Version 1.3.0 Type TSDocxFile = Class ///Version: V1.0 2022-09-20 diff --git a/funcext/TSOffice/TSExcelFile.tsf b/funcext/TSOffice/TSExcelFile.tsf index 19b0d41..4cb1e79 100644 --- a/funcext/TSOffice/TSExcelFile.tsf +++ b/funcext/TSOffice/TSExcelFile.tsf @@ -1,4 +1,4 @@ -// Version 1.2.9 +// Version 1.3.0 Type TSExcelFile = Class ///Version: V1.0 2022-08-08 diff --git a/funcext/TSOffice/TSUtils/NodeInfo.tsf b/funcext/TSOffice/TSUtils/NodeInfo.tsf index 5846c73..f8a40e7 100644 --- a/funcext/TSOffice/TSUtils/NodeInfo.tsf +++ b/funcext/TSOffice/TSUtils/NodeInfo.tsf @@ -176,6 +176,7 @@ public if istable(r) then Begin r := r[0]; 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'] = 'pcdata' then //返回文本串 return node.GetText(); @@ -183,6 +184,7 @@ public return node.Data(); key := r['attrName'] ? r['attrName'] : r['attrEx'] ? r['attrEx'] : 'val'; value := node.GetAttribute(key); + if r['nodeType'] = 'empty' and value = '' then return true; return trystrtofloat(value, r) ? r : value; End; return nil; diff --git a/funcext/TSOffice/TSUtils/TSImage.tsf b/funcext/TSOffice/TSUtils/TSImage.tsf index 43bb742..2c9f8d5 100644 --- a/funcext/TSOffice/TSUtils/TSImage.tsf +++ b/funcext/TSOffice/TSUtils/TSImage.tsf @@ -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; \ No newline at end of file + Name:string; + content_; + stringObj_; + width_:integer; + height_:integer; +End; diff --git a/funcext/TSOffice/worksheet/xlsxImage.tsf b/funcext/TSOffice/worksheet/xlsxImage.tsf index a22542a..68a8821 100644 --- a/funcext/TSOffice/worksheet/xlsxImage.tsf +++ b/funcext/TSOffice/worksheet/xlsxImage.tsf @@ -15,14 +15,16 @@ 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/', '../'); + //println("image_file = {}", image_file); [rid, target] := class(TSXml).FindRelationshipRid(rels_xmlfile, prefix); if target = '' then begin @@ -30,7 +32,7 @@ Type xlsxImage = Class class(TSXml).AddRelationshipRid(rels_xmlfile, prefix, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); end content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types')); - class(TSXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg'); + class(TSXml).AddDefaultContentType(content_xml, picture.ExtFileName, 'image/' $ picture.ExtFileName); sheet_xml := excel_.WorkBook().GetSheetXmlfile(sheetName_); node := sheet_xml.FirstChildElement('worksheet'); @@ -44,10 +46,11 @@ Type xlsxImage = Class 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.'; @@ -62,7 +65,7 @@ Type xlsxImage = Class class(TSXml).AddRelationshipRid(drawing_rels, image_target, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', 'rId' $ rid); end content_xml := excel_.WorkBook().GetXmlFileObj(class(TSXml).GetFileName('Content_Types')); - class(TSXml).AddDefaultContentType(content_xml, 'jpeg', 'image/jpeg'); + 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'); @@ -149,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; @@ -158,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 diff --git a/更新日志.md b/更新日志.md index e9dd8b3..79184f1 100644 --- a/更新日志.md +++ b/更新日志.md @@ -1,5 +1,15 @@ # 更新日志 +## 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