From 1af46fcaccaa49a54b77ca5372f6b0ffbfea12bc Mon Sep 17 00:00:00 2001 From: Mikhalkovich Stanislav Date: Fri, 2 Sep 2022 10:44:47 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20?= =?UTF-8?q?=D0=B2=20=5F=5FReadSignalOISystem.read=5Fsymbol=20-=20=D0=BE?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=87=D0=B0=D0=BD=D0=B8=D1=8F=20=D1=81=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D0=BA=20=D0=B2=20Linux=20=D0=BF=D1=80=D0=B8=20?= =?UTF-8?q?=D0=B2=D0=B2=D0=BE=D0=B4=D0=B5=20=D0=B2=20=D0=BE=D0=B1=D0=BE?= =?UTF-8?q?=D0=BB=D0=BE=D1=87=D0=BA=D0=B5=20=D1=82=D0=B5=D0=BF=D0=B5=D1=80?= =?UTF-8?q?=D1=8C=20=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=D1=8C=D0=BD=D0=BE?= =?UTF-8?q?=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=B0=D1=82=D1=8B=D0=B2=D0=B0?= =?UTF-8?q?=D1=8E=D1=82=D1=81=D1=8F=20XLSX=20-=20=D0=B4=D0=BE=D0=B1=D0=B0?= =?UTF-8?q?=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Configuration/GlobalAssemblyInfo.cs | 2 +- Configuration/Version.defs | 2 +- Release/pabcversion.txt | 2 +- ReleaseGenerators/PascalABCNET_version.nsh | 2 +- .../CompilationSamples/__RedirectIOMode.pas | 6 +- bin/Lib/XLSX.pas | 149 +++++++++++++++++- bin/Lib/__RedirectIOMode.pas | 6 +- 7 files changed, 153 insertions(+), 16 deletions(-) diff --git a/Configuration/GlobalAssemblyInfo.cs b/Configuration/GlobalAssemblyInfo.cs index a29e6016e..b85da25fb 100644 --- a/Configuration/GlobalAssemblyInfo.cs +++ b/Configuration/GlobalAssemblyInfo.cs @@ -15,7 +15,7 @@ internal static class RevisionClass public const string Major = "3"; public const string Minor = "8"; public const string Build = "3"; - public const string Revision = "3166"; + public const string Revision = "3168"; public const string MainVersion = Major + "." + Minor; public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision; diff --git a/Configuration/Version.defs b/Configuration/Version.defs index c266819c1..c833110d8 100644 --- a/Configuration/Version.defs +++ b/Configuration/Version.defs @@ -1,4 +1,4 @@ %COREVERSION%=3 -%REVISION%=3166 +%REVISION%=3168 %MINOR%=8 %MAJOR%=3 diff --git a/Release/pabcversion.txt b/Release/pabcversion.txt index ad79c5767..5ff62dc69 100644 --- a/Release/pabcversion.txt +++ b/Release/pabcversion.txt @@ -1 +1 @@ -3.8.3.3166 +3.8.3.3168 diff --git a/ReleaseGenerators/PascalABCNET_version.nsh b/ReleaseGenerators/PascalABCNET_version.nsh index 99b08a551..46bb726c3 100644 --- a/ReleaseGenerators/PascalABCNET_version.nsh +++ b/ReleaseGenerators/PascalABCNET_version.nsh @@ -1 +1 @@ -!define VERSION '3.8.3.3166' +!define VERSION '3.8.3.3168' diff --git a/TestSuite/CompilationSamples/__RedirectIOMode.pas b/TestSuite/CompilationSamples/__RedirectIOMode.pas index 2c46e22d4..45088b222 100644 --- a/TestSuite/CompilationSamples/__RedirectIOMode.pas +++ b/TestSuite/CompilationSamples/__RedirectIOMode.pas @@ -76,9 +76,9 @@ begin if not ReadlnSignalSended then SendReadlnRequest; c := inherited read_symbol; - if (LastReadSymbol=N) and (c=R) then + if {(LastReadSymbol=#13) and} (c=#10) then // Fix SSM 30.08.22 for Linux ReadlnSignalSended := false; - LastReadSymbol := c; + LastReadSymbol := c; // Не используется после Fix result := c; end; @@ -88,7 +88,7 @@ begin SendReadlnRequest; var s := inherited ReadLine; ReadlnSignalSended := false; - LastReadSymbol := R; + LastReadSymbol := #10; Result := s; end; diff --git a/bin/Lib/XLSX.pas b/bin/Lib/XLSX.pas index efd38bd15..cc318b6fa 100644 --- a/bin/Lib/XLSX.pas +++ b/bin/Lib/XLSX.pas @@ -2,10 +2,45 @@ interface +type + exCellBorder = class + IsLeft, IsRight, IsBottom, IsTop, IsDiagonal:boolean; + end; + + exCell = class + constructor(scheet:array of array of exCell;row,col:integer); + begin + _scheet := scheet; + Self.row := row; + Self.col := col; + end; + private + row,col:integer; + _scheet: array of array of exCell; + function getBorders:(boolean,boolean,boolean,boolean);// (left,top,right,bottom) + begin + var left := Border.IsLeft or (col>0) and _scheet[row,col-1].Border.IsRight; + var top := Border.IsTop or (row>0) and _scheet[row-1,col].Border.IsBottom; + var right := Border.IsRight or (col+1<_scheet.First.Length) + and (_scheet[row,col+1].Border<>nil) and _scheet[row,col+1].Border.IsLeft; + var bottom := Border.IsBottom or (row+1<_scheet.Length) + and _scheet[row+1,col].Border.IsTop; + Result := (left,top,right,bottom); + end; + public + Border : exCellBorder; + Value:string; + property AsInt:integer read Value.ToInteger; + property Index:(integer,integer) read (row,col); + property Scheet:array of array of exCell read _scheet; + property Borders:(boolean,boolean,boolean,boolean) read getBorders; + end; + function ReadXLSX(fileName: string): Dictionary; +function ReadXlsxAsCells(fileName: string;sheetNum: integer := 0): array of array of exCell; function ReadXlsxAsInts(fileName: string; sheetNum: integer := 0): array of array of integer; function ToDate(Self: string): DateTime; - + implementation {$reference System.IO.Compression.dll} @@ -16,7 +51,8 @@ uses System.IO.Compression; uses System.Xml,sf; var - numFmt := new List; + numFmt,numBrd : List; + brdStyles : List; arxiv: System.IO.Compression.ZipArchive; shStr := new List; DateTypeId := |14, 15, 16, 17, 22, 27, 30, 36, 50, 55, 57|.ToHS; @@ -48,11 +84,10 @@ begin end; end; -function LoadSheet(path: string): array of array of string; +function ShteetRange(elms:XmlElement):((int,int),(int,int)); begin - var elms := Load(path); + var LU, RD: (int,int); var dim := elms.Item['dimension']; - var LU, RD: (int, int); if dim = nil then begin // собираем габариты таблицы var (l, u) := (maxint, maxint); var (r, d) := (-1, -1); @@ -78,7 +113,14 @@ begin LU := RD; end; end; - + Result := (LU,RD); +end; + +function LoadSheet(path: string): array of array of string; +begin + var elms := Load(path); + var (LU, RD) := ShteetRange(elms); + var (w, h) := (RD[1] - LU[1] + 1, RD[0] - LU[0] + 1); var sheet: array of array of string; if (w<0)or(h<0) then @@ -114,6 +156,100 @@ begin Result := sheet; end; +function LoadSheetAsCells(path: string): array of array of exCell; +begin + var elms := Load(path); + var (LU, RD) := ShteetRange(elms); + + var (w, h) := (RD[1] - LU[1] + 1, RD[0] - LU[0] + 1); + var sheet: array of array of exCell; + if (w<0)or(h<0) then + setLength(sheet,0) + else begin + setLength(sheet, h); + for var i := 0 to h - 1 do sheet[i] := new exCell[w]; + + foreach var node: XmlNode in elms.Item['sheetData'].ChildNodes do + begin + foreach var cell: XmlNode in node.ChildNodes do + begin + var (i, j) := cell.Attributes.GetNamedItem('r').Value.ToCR; + i -= LU[0]; + j -= LU[1]; + var typ := cell.Attributes.GetNamedItem('t'); + var st := cell.Attributes.GetNamedItem('s'); + var shared := false; + if (typ <> nil) and (typ.Value = 's') then + shared := true; + + var value := ''; + foreach var vl: XmlNode in cell.ChildNodes do + if vl.Name = 'v' then + value := vl.InnerText; + + var cellValue := new exCell(sheet,i,j); + sheet[i, j] := cellValue; + if st <> nil then + cellValue.Border := brdStyles[numBrd[st.Value.ToI]]; + + if shared then + cellValue.Value := shStr[value.ToInteger] + else if (st <> nil) and (numFmt[st.Value.ToI] in DateTypeId) then + cellValue.Value := (new DateTime(1900, 1, 1)).AddDays(value.ToI - 2).ToString('dd.MM.yyyy') + else + cellValue.Value := value; + end; + end; + end; + Result := sheet; +end; + +function ReadXLSXAsCells(fileName: string;sheetNum: integer):array of array of exCell; +begin + arxiv := ZipFile.OpenRead(fileName); + + // общие строки + var elms := Load('xl/sharedStrings.xml'); + if elms <> nil then + foreach var node: XmlNode in elms.ChildNodes do + shStr.Add(node.Item['t'].InnerText.Trim); + + // бордюры + elms := Load('xl/styles.xml'); + brdStyles := new List; + foreach var node: XmlNode in elms.Item['borders'].ChildNodes do begin + var brd := new exCellBorder; + brd.IsLeft := node.Item['left'].Attributes.Count>0; + brd.IsRight := node.Item['right'].Attributes.Count>0; + brd.IsTop := node.Item['top'].Attributes.Count>0; + brd.IsBottom := node.Item['bottom'].Attributes.Count>0; + brd.IsDiagonal := node.Item['diagonal'].Attributes.Count>0; + brdStyles.Add(brd); + end; + + // стили + numFmt := new List; + numBrd := new List; + foreach var node: XmlNode in elms.Item['cellXfs'].ChildNodes do begin + numFmt.Add(node.Attributes.GetNamedItem('numFmtId').Value.ToI); + numBrd.Add(node.Attributes.GetNamedItem('borderId').Value.ToI); + end; + + elms := Load('xl/workbook.xml'); + foreach var node: XmlNode in elms.Item['sheets'].ChildNodes do + begin + var name := node.Attributes.GetNamedItem('name').Value; + var attrs := new List; + foreach var attr: XmlAttribute in node.Attributes do + attrs.Add(attr.Name); + var sheetId := node.Attributes.GetNamedItem('r:id').Value[4:]; + Result := LoadSheetAsCells($'xl/worksheets/sheet{sheetId}.xml'); + sheetNum -= 1; + if sheetNum=0 then + break; + end; +end; + function ReadXLSX(fileName: string): Dictionary; begin arxiv := ZipFile.OpenRead(fileName); @@ -143,6 +279,7 @@ begin end; end; + function ReadXlsxAsInts(fileName: string; sheetNum: integer) := ReadXLSX(fileName).Values.Skip(sheetNum).First.Select(r->r.Select(c->c.ToInteger).ToArray).ToArray; diff --git a/bin/Lib/__RedirectIOMode.pas b/bin/Lib/__RedirectIOMode.pas index 2c46e22d4..45088b222 100644 --- a/bin/Lib/__RedirectIOMode.pas +++ b/bin/Lib/__RedirectIOMode.pas @@ -76,9 +76,9 @@ begin if not ReadlnSignalSended then SendReadlnRequest; c := inherited read_symbol; - if (LastReadSymbol=N) and (c=R) then + if {(LastReadSymbol=#13) and} (c=#10) then // Fix SSM 30.08.22 for Linux ReadlnSignalSended := false; - LastReadSymbol := c; + LastReadSymbol := c; // Не используется после Fix result := c; end; @@ -88,7 +88,7 @@ begin SendReadlnRequest; var s := inherited ReadLine; ReadlnSignalSended := false; - LastReadSymbol := R; + LastReadSymbol := #10; Result := s; end;