You've already forked lazarus-ccr
fpspreadsheet: Add (intermediate) copy of csvdocument to component and use its parser and builder from the csv reader/writer of fpspreadsheet.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3683 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -6,7 +6,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
fpspreadsheet;
|
fpspreadsheet, fpsCsvDocument;
|
||||||
|
|
||||||
type
|
type
|
||||||
TsCSVReader = class(TsCustomSpreadReader)
|
TsCSVReader = class(TsCustomSpreadReader)
|
||||||
@ -32,6 +32,7 @@ type
|
|||||||
|
|
||||||
TsCSVWriter = class(TsCustomSpreadWriter)
|
TsCSVWriter = class(TsCustomSpreadWriter)
|
||||||
private
|
private
|
||||||
|
FCSVBuilder: TCSVBuilder;
|
||||||
FLineEnding: String;
|
FLineEnding: String;
|
||||||
protected
|
protected
|
||||||
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
@ -82,6 +83,8 @@ var
|
|||||||
FalseText: 'FALSE';
|
FalseText: 'FALSE';
|
||||||
{%H-});
|
{%H-});
|
||||||
|
|
||||||
|
function LineEndingAsString(ALineEnding: TsCSVLineEnding): String;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
@ -174,6 +177,16 @@ begin
|
|||||||
AFormatSettings.TwoDigitYearCenturyWindow := ADefaultFormats.TwoDigitYearCenturyWindow;
|
AFormatSettings.TwoDigitYearCenturyWindow := ADefaultFormats.TwoDigitYearCenturyWindow;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function LineEndingAsString(ALineEnding: TsCSVLineEnding): String;
|
||||||
|
begin
|
||||||
|
case ALineEnding of
|
||||||
|
leSystem: Result := LineEnding;
|
||||||
|
leCR : Result := #13;
|
||||||
|
leLF : Result := #10;
|
||||||
|
leCRLF : Result := #13#10;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ -----------------------------------------------------------------------------}
|
{ -----------------------------------------------------------------------------}
|
||||||
{ TsCSVReader }
|
{ TsCSVReader }
|
||||||
@ -317,6 +330,8 @@ begin
|
|||||||
Unused(AStream);
|
Unused(AStream);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ Determines content types from/for the text read from the csv file and writes
|
||||||
|
the corresponding data to the worksheet. }
|
||||||
procedure TsCSVReader.ReadCellValue(ARow, ACol: Cardinal; AText: String);
|
procedure TsCSVReader.ReadCellValue(ARow, ACol: Cardinal; AText: String);
|
||||||
var
|
var
|
||||||
dblValue: Double;
|
dblValue: Double;
|
||||||
@ -338,22 +353,6 @@ begin
|
|||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// Remove quotes
|
|
||||||
if (AText[1] = CSVParams.QuoteChar) and (AText[Length(AText)] = CSVParams.QuoteChar) then
|
|
||||||
begin
|
|
||||||
Delete(AText, Length(AText), 1);
|
|
||||||
Delete(AText, 1, 1);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{
|
|
||||||
// Quoted text is a TEXT cell
|
|
||||||
if IsQuotedText(AText) then
|
|
||||||
begin
|
|
||||||
FWorksheet.WriteUTF8Text(ARow, ACol, AText);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for a NUMBER or CURRENCY cell
|
// Check for a NUMBER or CURRENCY cell
|
||||||
if IsNumber(AText, dblValue, nf, decs, currSym, warning) then
|
if IsNumber(AText, dblValue, nf, decs, currSym, warning) then
|
||||||
begin
|
begin
|
||||||
@ -403,6 +402,28 @@ begin
|
|||||||
inherited;
|
inherited;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TsCSVReader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
||||||
|
var
|
||||||
|
parser: TCSVParser;
|
||||||
|
begin
|
||||||
|
FWorkbook := AData;
|
||||||
|
FWorksheet := AData.AddWorksheet(FWorksheetName);
|
||||||
|
|
||||||
|
parser := TCSVParser.Create;
|
||||||
|
try
|
||||||
|
parser.Delimiter := CSVParams.Delimiter;
|
||||||
|
parser.LineEnding := LineEndingAsString(CSVParams.LineEnding);
|
||||||
|
parser.QuoteChar := CSVParams.QuoteChar;
|
||||||
|
parser.EqualColCountPerRow := false;
|
||||||
|
parser.SetSource(AStream);
|
||||||
|
while parser.ParseNextCell do
|
||||||
|
ReadCellValue(parser.CurrentRow, parser.CurrentCol, parser.CurrentCellText);
|
||||||
|
|
||||||
|
finally
|
||||||
|
parser.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{
|
||||||
procedure TsCSVReader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
procedure TsCSVReader.ReadFromStream(AStream: TStream; AData: TsWorkbook);
|
||||||
var
|
var
|
||||||
n: Int64;
|
n: Int64;
|
||||||
@ -452,7 +473,7 @@ begin
|
|||||||
cellValue := cellValue + ch;
|
cellValue := cellValue + ch;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
procedure TsCSVReader.ReadFromStrings(AStrings: TStrings; AData: TsWorkbook);
|
procedure TsCSVReader.ReadFromStrings(AStrings: TStrings; AData: TsWorkbook);
|
||||||
var
|
var
|
||||||
stream: TStringStream;
|
stream: TStringStream;
|
||||||
@ -503,19 +524,28 @@ end;
|
|||||||
procedure TsCSVWriter.WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure TsCSVWriter.WriteBool(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: Boolean; ACell: PCell);
|
const AValue: Boolean; ACell: PCell);
|
||||||
begin
|
begin
|
||||||
|
Unused(AStream);
|
||||||
Unused(ARow, ACol, ACell);
|
Unused(ARow, ACol, ACell);
|
||||||
|
if AValue then
|
||||||
|
FCSVBuilder.AppendCell(CSVParams.TrueText)
|
||||||
|
else
|
||||||
|
FCSVBuilder.AppendCell(CSVParams.FalseText);
|
||||||
|
{
|
||||||
if AValue then
|
if AValue then
|
||||||
AppendToStream(AStream, CSVParams.TrueText)
|
AppendToStream(AStream, CSVParams.TrueText)
|
||||||
else
|
else
|
||||||
AppendToStream(AStream, CSVParams.FalseText);
|
AppendToStream(AStream, CSVParams.FalseText);
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ Write date/time values in the same way they are displayed in the sheet }
|
{ Write date/time values in the same way they are displayed in the sheet }
|
||||||
procedure TsCSVWriter.WriteDateTime(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure TsCSVWriter.WriteDateTime(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
const AValue: TDateTime; ACell: PCell);
|
const AValue: TDateTime; ACell: PCell);
|
||||||
begin
|
begin
|
||||||
|
Unused(AStream);
|
||||||
Unused(ARow, ACol, AValue);
|
Unused(ARow, ACol, AValue);
|
||||||
AppendToStream(AStream, FWorksheet.ReadAsUTF8Text(ACell));
|
FCSVBuilder.AppendCell(FWorksheet.ReadAsUTF8Text(ACell));
|
||||||
|
// AppendToStream(AStream, FWorksheet.ReadAsUTF8Text(ACell));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ CSV does not support formulas, but we have to write the formula results to
|
{ CSV does not support formulas, but we have to write the formula results to
|
||||||
@ -541,13 +571,15 @@ procedure TsCSVWriter.WriteLabel(AStream: TStream; const ARow, ACol: Cardinal;
|
|||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
|
Unused(AStream);
|
||||||
Unused(ARow, ACol, AValue);
|
Unused(ARow, ACol, AValue);
|
||||||
if ACell = nil then
|
if ACell = nil then
|
||||||
exit;
|
exit;
|
||||||
s := ACell^.UTF8StringValue;
|
s := ACell^.UTF8StringValue;
|
||||||
if CSVParams.QuoteChar <> #0 then
|
if CSVParams.QuoteChar <> #0 then
|
||||||
s := CSVParams.QuoteChar + s + CSVParams.QuoteChar;
|
s := CSVParams.QuoteChar + s + CSVParams.QuoteChar;
|
||||||
AppendToStream(AStream, s);
|
FCSVBuilder.AppendCell(s);
|
||||||
|
// AppendToStream(AStream, s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsCSVWriter.WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
|
procedure TsCSVWriter.WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
|
||||||
@ -555,6 +587,7 @@ procedure TsCSVWriter.WriteNumber(AStream: TStream; const ARow, ACol: Cardinal;
|
|||||||
var
|
var
|
||||||
s: String;
|
s: String;
|
||||||
begin
|
begin
|
||||||
|
Unused(AStream);
|
||||||
Unused(ARow, ACol);
|
Unused(ARow, ACol);
|
||||||
if ACell = nil then
|
if ACell = nil then
|
||||||
exit;
|
exit;
|
||||||
@ -562,7 +595,8 @@ begin
|
|||||||
s := Format(CSVParams.NumberFormat, [AValue], CSVParams.FormatSettings)
|
s := Format(CSVParams.NumberFormat, [AValue], CSVParams.FormatSettings)
|
||||||
else
|
else
|
||||||
s := FWorksheet.ReadAsUTF8Text(ACell, CSVParams.FormatSettings);
|
s := FWorksheet.ReadAsUTF8Text(ACell, CSVParams.FormatSettings);
|
||||||
AppendToStream(AStream, s);
|
FCSVBuilder.AppendCell(s);
|
||||||
|
// AppendToStream(AStream, s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet);
|
procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet);
|
||||||
@ -572,8 +606,29 @@ var
|
|||||||
cell: PCell;
|
cell: PCell;
|
||||||
begin
|
begin
|
||||||
FWorksheet := AWorksheet;
|
FWorksheet := AWorksheet;
|
||||||
lastRow := FWorksheet.GetLastOccupiedRowIndex;
|
|
||||||
lastCol := FWorksheet.GetLastOccupiedColIndex;
|
FCSVBuilder := TCSVBuilder.Create;
|
||||||
|
try
|
||||||
|
FCSVBuilder.Delimiter := CSVParams.Delimiter;
|
||||||
|
FCSVBuilder.LineEnding := LineEndingAsString(CSVParams.LineEnding);
|
||||||
|
FCSVBuilder.QuoteChar := CSVParams.QuoteChar;
|
||||||
|
FCSVBuilder.SetOutput(AStream);
|
||||||
|
|
||||||
|
lastRow := FWorksheet.GetLastOccupiedRowIndex;
|
||||||
|
lastCol := FWorksheet.GetLastOccupiedColIndex;
|
||||||
|
for r := 0 to lastRow do
|
||||||
|
for c := 0 to lastCol do
|
||||||
|
begin
|
||||||
|
cell := FWorksheet.FindCell(r, c);
|
||||||
|
if cell <> nil then
|
||||||
|
WriteCellCallback(cell, AStream);
|
||||||
|
if c = lastCol then
|
||||||
|
FCSVBuilder.AppendRow;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeAndNil(FCSVBuilder);
|
||||||
|
end;
|
||||||
|
{
|
||||||
for r := 0 to lastRow do
|
for r := 0 to lastRow do
|
||||||
for c := 0 to lastCol do begin
|
for c := 0 to lastCol do begin
|
||||||
cell := FWorksheet.FindCell(r, c);
|
cell := FWorksheet.FindCell(r, c);
|
||||||
@ -584,6 +639,7 @@ begin
|
|||||||
else
|
else
|
||||||
AppendToStream(AStream, CSVParams.Delimiter);
|
AppendToStream(AStream, CSVParams.Delimiter);
|
||||||
end;
|
end;
|
||||||
|
}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TsCSVWriter.WriteToStream(AStream: TStream);
|
procedure TsCSVWriter.WriteToStream(AStream: TStream);
|
||||||
|
1041
components/fpspreadsheet/fpscsvdocument.pas
Normal file
1041
components/fpspreadsheet/fpscsvdocument.pas
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@
|
|||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<PathDelim Value="\"/>
|
<PathDelim Value="\"/>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
|
<OtherUnitFiles Value="."/>
|
||||||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Parsing>
|
<Parsing>
|
||||||
@ -25,7 +26,7 @@
|
|||||||
This package is all you need if you don't want graphical components (like grids and charts)."/>
|
This package is all you need if you don't want graphical components (like grids and charts)."/>
|
||||||
<License Value="LGPL with static linking exception. This is the same license as is used in the LCL (Lazarus Component Library)."/>
|
<License Value="LGPL with static linking exception. This is the same license as is used in the LCL (Lazarus Component Library)."/>
|
||||||
<Version Major="1" Minor="2"/>
|
<Version Major="1" Minor="2"/>
|
||||||
<Files Count="26">
|
<Files Count="27">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="fpolestorage.pas"/>
|
<Filename Value="fpolestorage.pas"/>
|
||||||
<UnitName Value="fpolestorage"/>
|
<UnitName Value="fpolestorage"/>
|
||||||
@ -120,7 +121,7 @@ This package is all you need if you don't want graphical components (like grids
|
|||||||
</Item23>
|
</Item23>
|
||||||
<Item24>
|
<Item24>
|
||||||
<Filename Value="fpsrpn.pas"/>
|
<Filename Value="fpsrpn.pas"/>
|
||||||
<UnitName Value="fpsrpn"/>
|
<UnitName Value="fpsRPN"/>
|
||||||
</Item24>
|
</Item24>
|
||||||
<Item25>
|
<Item25>
|
||||||
<Filename Value="fpsstrings.pas"/>
|
<Filename Value="fpsstrings.pas"/>
|
||||||
@ -130,6 +131,10 @@ This package is all you need if you don't want graphical components (like grids
|
|||||||
<Filename Value="fpscsv.pas"/>
|
<Filename Value="fpscsv.pas"/>
|
||||||
<UnitName Value="fpscsv"/>
|
<UnitName Value="fpscsv"/>
|
||||||
</Item26>
|
</Item26>
|
||||||
|
<Item27>
|
||||||
|
<Filename Value="fpscsvdocument.pas"/>
|
||||||
|
<UnitName Value="fpsCsvDocument"/>
|
||||||
|
</Item27>
|
||||||
</Files>
|
</Files>
|
||||||
<RequiredPkgs Count="2">
|
<RequiredPkgs Count="2">
|
||||||
<Item1>
|
<Item1>
|
||||||
|
@ -12,7 +12,7 @@ uses
|
|||||||
fpsutils, fpszipper, uvirtuallayer_types, uvirtuallayer, uvirtuallayer_ole,
|
fpsutils, fpszipper, uvirtuallayer_types, uvirtuallayer, uvirtuallayer_ole,
|
||||||
uvirtuallayer_ole_helpers, uvirtuallayer_ole_types, uvirtuallayer_stream,
|
uvirtuallayer_ole_helpers, uvirtuallayer_ole_types, uvirtuallayer_stream,
|
||||||
fpolebasic, wikitable, fpsNumFormatParser, fpsfunc, fpsRPN, fpsStrings,
|
fpolebasic, wikitable, fpsNumFormatParser, fpsfunc, fpsRPN, fpsStrings,
|
||||||
fpscsv;
|
fpscsv, fpsCsvDocument;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user