Исправлена ошибка в __ReadSignalOISystem.read_symbol - окончания строк в Linux при вводе в оболочке теперь правильно обрабатываются

XLSX - добавление
This commit is contained in:
Mikhalkovich Stanislav 2022-09-02 10:44:47 +03:00
parent f4aa263a9a
commit 1af46fcacc
7 changed files with 153 additions and 16 deletions

View file

@ -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;

View file

@ -1,4 +1,4 @@
%COREVERSION%=3
%REVISION%=3166
%REVISION%=3168
%MINOR%=8
%MAJOR%=3

View file

@ -1 +1 @@
3.8.3.3166
3.8.3.3168

View file

@ -1 +1 @@
!define VERSION '3.8.3.3166'
!define VERSION '3.8.3.3168'

View file

@ -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;

View file

@ -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<string, array of array of string>;
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<int>;
numFmt,numBrd : List<int>;
brdStyles : List<exCellBorder>;
arxiv: System.IO.Compression.ZipArchive;
shStr := new List<string>;
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<exCellBorder>;
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<int>;
numBrd := new List<int>;
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<string>;
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<string, array of array of string>;
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;

View file

@ -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;