diff --git a/components/fpspreadsheet/examples/csvdemo/csvread.lpi b/components/fpspreadsheet/examples/csvdemo/csvread.lpi new file mode 100644 index 000000000..5d808975b --- /dev/null +++ b/components/fpspreadsheet/examples/csvdemo/csvread.lpi @@ -0,0 +1,66 @@ + + + + + + + + + + + + + <UseAppBundle Value="False"/> + </General> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <BuildModes Count="1"> + <Item1 Name="default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="LazUtils"/> + </Item1> + </RequiredPackages> + <Units Count="1"> + <Unit0> + <Filename Value="csvread.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="csvread"/> + </Target> + <SearchPaths> + <OtherUnitFiles Value="..\.."/> + <UnitOutputDirectory Value="..\lib\$(TargetCPU)-$(TargetOS)"/> + </SearchPaths> + <Parsing> + <SyntaxOptions> + <UseAnsiStrings Value="False"/> + </SyntaxOptions> + </Parsing> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf2Set"/> + </Debugging> + </Linking> + </CompilerOptions> +</CONFIG> diff --git a/components/fpspreadsheet/examples/csvdemo/csvread.lpr b/components/fpspreadsheet/examples/csvdemo/csvread.lpr new file mode 100644 index 000000000..a4cc1a4fc --- /dev/null +++ b/components/fpspreadsheet/examples/csvdemo/csvread.lpr @@ -0,0 +1,62 @@ +{ +csvread.dpr + +Demonstrates how to read a CSV file using the fpspreadsheet library +} + +program myexcel2read; + +{$mode delphi}{$H+} + +uses + Classes, SysUtils, fpspreadsheet, fpscsv; + +var + MyWorkbook: TsWorkbook; + MyWorksheet: TsWorksheet; + InputFilename: string; + MyDir: string; + i: Integer; + CurCell: PCell; +begin + // Open the input file + MyDir := ExtractFilePath(ParamStr(0)); + InputFileName := MyDir + 'test' + STR_COMMA_SEPARATED_EXTENSION; + if not FileExists(InputFileName) then begin + WriteLn('Input file ', InputFileName, ' does not exist. Please run excel2write first.'); + Halt; + end; + + WriteLn('Opening input file ', InputFilename); + + CSVParams.ColDelimiter := #9; + + // Create the spreadsheet + MyWorkbook := TsWorkbook.Create; + MyWorkbook.Options := MyWorkbook.Options + [boReadFormulas]; + MyWorkbook.ReadFromFile(InputFilename, sfCSV); + + MyWorksheet := MyWorkbook.GetFirstWorksheet; + + // Write all cells with contents to the console + WriteLn(''); + WriteLn('Contents of the first worksheet of the file:'); + WriteLn(''); + + CurCell := MyWorkSheet.GetFirstCell(); + for i := 0 to MyWorksheet.GetCellCount - 1 do + begin + if HasFormula(CurCell) then + WriteLn('Row: ', CurCell^.Row, ' Col: ', CurCell^.Col, ' Formula: ', MyWorksheet.ReadFormulaAsString(CurCell)) + else + WriteLn('Row: ', CurCell^.Row, + ' Col: ', CurCell^.Col, + ' Value: ', UTF8ToAnsi(MyWorkSheet.ReadAsUTF8Text(CurCell^.Row, CurCell^.Col)) + ); + CurCell := MyWorkSheet.GetNextCell(); + end; + + // Finalization + MyWorkbook.Free; +end. + diff --git a/components/fpspreadsheet/examples/csvdemo/csvwrite.lpi b/components/fpspreadsheet/examples/csvdemo/csvwrite.lpi new file mode 100644 index 000000000..1967c5dff --- /dev/null +++ b/components/fpspreadsheet/examples/csvdemo/csvwrite.lpi @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="UTF-8"?> +<CONFIG> + <ProjectOptions> + <Version Value="9"/> + <PathDelim Value="\"/> + <General> + <Flags> + <LRSInOutputDirectory Value="False"/> + </Flags> + <SessionStorage Value="InProjectDir"/> + <MainUnit Value="0"/> + <Title Value="csvwrite"/> + <UseAppBundle Value="False"/> + </General> + <VersionInfo> + <StringTable ProductVersion=""/> + </VersionInfo> + <BuildModes Count="1"> + <Item1 Name="default" Default="True"/> + </BuildModes> + <PublishOptions> + <Version Value="2"/> + <IgnoreBinaries Value="False"/> + <IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/> + <ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/> + </PublishOptions> + <RunParams> + <local> + <FormatVersion Value="1"/> + <LaunchingApplication PathPlusParams="\usr\X11R6\bin\xterm -T 'Lazarus Run Output' -e $(LazarusDir)\tools\runwait.sh $(TargetCmdLine)"/> + </local> + </RunParams> + <RequiredPackages Count="1"> + <Item1> + <PackageName Value="LazUtils"/> + </Item1> + </RequiredPackages> + <Units Count="2"> + <Unit0> + <Filename Value="csvwrite.lpr"/> + <IsPartOfProject Value="True"/> + </Unit0> + <Unit1> + <Filename Value="..\..\fpscsv.pas"/> + <IsPartOfProject Value="True"/> + <UnitName Value="fpscsv"/> + </Unit1> + </Units> + </ProjectOptions> + <CompilerOptions> + <Version Value="11"/> + <PathDelim Value="\"/> + <Target> + <Filename Value="csvwrite"/> + </Target> + <SearchPaths> + <OtherUnitFiles Value="..\.."/> + <UnitOutputDirectory Value="..\lib\$(TargetCPU)-$(TargetOS)"/> + <SrcPath Value=".."/> + </SearchPaths> + <Linking> + <Debugging> + <DebugInfoType Value="dsDwarf2Set"/> + </Debugging> + </Linking> + </CompilerOptions> +</CONFIG> diff --git a/components/fpspreadsheet/examples/csvdemo/csvwrite.lpr b/components/fpspreadsheet/examples/csvdemo/csvwrite.lpr new file mode 100644 index 000000000..f51a5d126 --- /dev/null +++ b/components/fpspreadsheet/examples/csvdemo/csvwrite.lpr @@ -0,0 +1,322 @@ +{ +csvwrite.dpr + +Demonstrates how to write a CSV file using the fpspreadsheet library + +} +program csvwrite; + +{$mode delphi}{$H+} + +uses + Classes, SysUtils, fpspreadsheet, fpscsv; + +var + MyWorkbook: TsWorkbook; + MyWorksheet: TsWorksheet; + MyRPNFormula: TsRPNFormula; + MyDir: string; + number: Double; + lCol: TCol; + lRow: TRow; + r: Integer; + fmt: String; +begin + // Open the output file + MyDir := ExtractFilePath(ParamStr(0)); + + // Create the spreadsheet + MyWorkbook := TsWorkbook.Create; + MyWorksheet := MyWorkbook.AddWorksheet('My Worksheet'); + + //MyWorksheet.WriteColWidth(0, 5); + //MyWorksheet.WriteColWidth(1, 30); + + MyWorksheet.WriteRowHeight(0, 3); // 3 lines + + // Turn off grid lines and hide headers + //MyWorksheet.Options := MyWorksheet.Options - [soShowGridLines, soShowHeaders]; + +// -- currently not working + MyWorksheet.Options := MyWorksheet.Options + [soHasFrozenPanes]; + MyWorksheet.LeftPaneWidth := 1; + MyWorksheet.TopPaneHeight := 3; + + // Write some number cells + MyWorksheet.WriteUsedFormatting(0, 0, [uffBold, uffNumberFormat]); + MyWorksheet.WriteNumber(0, 1, 2.0); + MyWorksheet.WriteNumber(0, 2, 3.0); + MyWorksheet.WriteNumber(0, 3, 4.0); + + // Write some string cells + MyWorksheet.WriteUTF8Text(1, 0, 'First'); + MyWorksheet.WriteFont (1, 0, 'Arial', 12, [fssBold, fssItalic, fssUnderline], scRed); + MyWorksheet.WriteUTF8Text(1, 1, 'Second'); + MyWorksheet.WriteUTF8Text(1, 2, 'Third'); + MyWorksheet.WriteUTF8Text(1, 3, 'Fourth'); + + // Write current date/time + MyWorksheet.WriteDateTime(2, 0, now); + + // Write cell with background color + MyWorksheet.WriteUTF8Text(3, 0, 'Text'); + MyWorksheet.WriteBackgroundColor(3, 0, scSilver); + + // Empty cell with background color + MyWorksheet.WriteBackgroundColor(3, 1, scGrey); + + // Cell2 with top and bottom borders + MyWorksheet.WriteUTF8Text(4, 0, 'Text'); + MyWorksheet.WriteBorders(4, 0, [cbNorth, cbSouth]); + MyWorksheet.WriteBorders(4, 1, [cbNorth, cbSouth]); + MyWorksheet.WriteBorders(4, 2, [cbNorth, cbSouth]); + + // Left, center, right aligned texts + MyWorksheet.WriteUTF8Text(5, 0, 'L'); + MyWorksheet.WriteUTF8Text(5, 1, 'C'); + MyWorksheet.WriteUTF8Text(5, 2, 'R'); + MyWorksheet.WriteHorAlignment(5, 0, haLeft); + MyWorksheet.WriteHorAlignment(5, 1, haCenter); + MyWorksheet.WriteHorAlignment(5, 2, haRight); + + // Red font, italic + MyWorksheet.WriteNumber(6, 0, 2014); + MyWorksheet.WriteFont(6, 0, 'Calibri', 15, [fssItalic], scRed); + MyWorksheet.WriteNumber(6, 1, 2015); + MyWorksheet.WriteFont(6, 1, 'Times New Roman', 9, [fssUnderline], scBlue); + MyWorksheet.WriteNumber(6, 2, 2016); + MyWorksheet.WriteFont(6, 2, 'Courier New', 8, [], scBlue); + MyWorksheet.WriteNumber(6, 3, 2017); + MyWorksheet.WriteFont(6, 3, 'Arial', 18, [fssBold], scBlue); + + r:= 10; + // Write current date/time and test numbers for various formatting options + + inc(r, 2); + MyWorksheet.WriteUTF8Text(r, 0, 'nfShortDate'); + MyWorksheet.WriteDateTime(r, 1, now, nfShortDate); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfLongDate'); + MyWorksheet.WriteDateTime(r, 1, now, nfLongDate); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfShortTime'); + MyWorksheet.WriteDateTime(r, 1, now, nfShortTime); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfLongTime'); + MyWorksheet.WriteDateTime(r, 1, now, nfLongTime); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfShortDateTime'); + MyWorksheet.WriteDateTime(r, 1, now, nfShortDateTime); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, ''dd/mmm'''); + MyWorksheet.WriteDateTime(r, 1, now, nfCustom, 'dd/mmm'''); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, ''mmm/yy'''); + MyWorksheet.WriteDateTime(r, 1, now, nfCustom, 'mmm/yy'); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfShortTimeAM'); + MyWorksheet.WriteDateTime(r, 1, now, nfShortTimeAM); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfLongTimeAM'); + MyWorksheet.WriteDateTime(r, 1, now, nfLongTimeAM); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, nn:ss'); + MyWorksheet.WriteDateTime(r, 1, now, nfCustom, 'nn:ss'); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, nn:ss.z'); + MyWorksheet.WriteDateTime(r, 1, now, nfCustom, 'nn:ss.z'); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, mm:ss.zzz'); + MyWorksheet.WriteDateTime(r, 1, now, nfCustom, 'mm:ss.zzz'); + MyWorksheet.WriteFontColor(r, 1, scGray); + + // Write formatted numbers + number := 12345.67890123456789; + inc(r, 2); + MyWorksheet.WriteUTF8Text(r, 1, '12345.67890123456789'); + MyWorksheet.WriteUTF8Text(r, 2, '-12345.67890123456789'); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfGeneral'); + MyWorksheet.WriteNumber(r, 1, number, nfGeneral); + MyWorksheet.WriteNumber(r, 2, -number, nfGeneral); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixed, 0 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixed, 0); + MyWorksheet.WriteNumber(r, 2, -number, nfFixed, 0); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixed, 1 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixed, 1); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number, nfFixed, 1); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixed, 2 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixed, 2); + MyWorksheet.WriteNumber(r, 2, -number, nfFixed, 2); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixed, 3 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixed, 3); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number, nfFixed, 3); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixedTh, 0 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 0); + MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 0); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixedTh, 1 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 1); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 1); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixedTh, 2 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 2); + MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 2); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfFixedTh, 3 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfFixedTh, 3); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number, nfFixedTh, 3); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 1 dec'); + MyWorksheet.WriteNumber(r, 1, number, nfExp, 1); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number, nfExp, 1); + MyWorksheet.WriteFontColor(r, 2, scGray); + MyWorksheet.WriteNumber(r, 3, 1.0/number, nfExp, 1); + MyWorksheet.WriteFontColor(r, 3, scGray); + MyWorksheet.WriteNumber(r, 4, -1.0/number, nfExp, 1); + MyWorksheet.WriteFontColor(r, 4, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 2 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfExp, 2); + MyWorksheet.WriteNumber(r, 2, -number, nfExp, 2); + MyWorksheet.WriteNumber(r, 3, 1.0/number, nfExp, 2); + MyWorksheet.WriteNumber(r, 4, -1.0/number, nfExp, 2); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfExp, 3 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfExp, 3); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number, nfExp, 3); + MyWorksheet.WriteFontColor(r, 2, scGray); + MyWorksheet.WriteNumber(r, 3, 1.0/number, nfExp, 3); + MyWorksheet.WriteFontColor(r, 3, scGray); + MyWorksheet.WriteNumber(r, 4, -1.0/number, nfExp, 3); + MyWorksheet.WriteFontColor(r, 4, scGray); + inc(r,2); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCurrency, 0 decs'); + MyWorksheet.WriteCurrency(r, 1, number, nfCurrency, 0, '$'); + MyWorksheet.WriteCurrency(r, 2, -number, nfCurrency, 0, '$'); + MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrency, 0, '$'); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCurrencyRed, 0 decs'); + MyWorksheet.WriteCurrency(r, 1, number, nfCurrencyRed, 0, 'USD'); + MyWorksheet.WriteCurrency(r, 2, -number, nfCurrencyRed, 0, 'USD'); + MyWorksheet.WriteCurrency(r, 3, 0.0, nfCurrencyRed, 0, 'USD'); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0_);("$"#,##0)'); + MyWorksheet.WriteNumber(r, 1, number); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumberFormat(r, 1, nfCustom, '"$"#,##0_);("$"#,##0)'); + MyWorksheet.WriteNumber(r, 2, -number); + MyWorksheet.WriteNumberFormat(r, 2, nfCustom, '"$"#,##0_);("$"#,##0)'); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, "$"#,##0.0_);[Red]("$"#,##0.0)'); + MyWorksheet.WriteNumber(r, 1, number); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumberFormat(r, 1, nfCustom, '"$"#,##0.0_);[Red]("$"#,##0.0)'); + MyWorksheet.WriteNumber(r, 2, -number); + MyWorksheet.WriteNumberFormat(r, 2, nfCustom, '"$"#,##0.0_);[Red]("$"#,##0.0)'); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + fmt := '"€"#,##0.0_);[Red]("€"#,##0.0)'; + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, '+fmt); + MyWorksheet.WriteNumber(r, 1, number); + MyWorksheet.WriteNumberFormat(r, 1, nfCustom, UTF8ToAnsi(fmt)); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number); + MyWorksheet.WriteNumberFormat(r, 2, nfCustom, UTF8ToAnsi(fmt)); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + fmt := '[Green]"¥"#,##0.0_);[Red]-"¥"#,##0.0'; + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, '+fmt); + MyWorksheet.WriteNumber(r, 1, number); + MyWorksheet.WriteNumberFormat(r, 1, nfCustom, UTF8ToAnsi(fmt)); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumber(r, 2, -number); + MyWorksheet.WriteNumberFormat(r, 2, nfCustom, UTF8ToAnsi(fmt)); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfCustom, _("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)'); + MyWorksheet.WriteNumber(r, 1, number); + MyWorksheet.WriteFontColor(r, 1, scGray); + MyWorksheet.WriteNumberFormat(r, 1, nfCustom, '_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)'); + MyWorksheet.WriteNumber(r, 2, -number); + MyWorksheet.WriteNumberFormat(r, 2, nfCustom, '_("$"* #,##0_);_("$"* (#,##0);_("$"* "-"_);_(@_)'); + MyWorksheet.WriteFontColor(r, 2, scGray); + inc(r, 2); + number := 1.333333333; + MyWorksheet.WriteUTF8Text(r, 0, 'nfPercentage, 0 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfPercentage, 0); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfPercentage, 1 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfPercentage, 1); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfPercentage, 2 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfPercentage, 2); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfPercentage, 3 decs'); + MyWorksheet.WriteNumber(r, 1, number, nfPercentage, 3); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfTimeInterval, hh:mm:ss'); + MyWorksheet.WriteDateTime(r, 1, number, nfTimeInterval); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfTimeInterval, h:m:s'); + MyWorksheet.WriteDateTime(r, 1, number, nfTimeInterval, 'H:M:s'); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfTimeInterval, hh:mm'); + MyWorksheet.WriteDateTime(r, 1, number, nfTimeInterval, 'hh:mm'); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfTimeInterval, h:m'); + MyWorksheet.WriteDateTime(r, 1, number, nfTimeInterval, 'h:m'); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + MyWorksheet.WriteUTF8Text(r, 0, 'nfTimeInterval, h'); + MyWorksheet.WriteDateTime(r, 1, number, nfTimeInterval, 'h'); + MyWorksheet.WriteFontColor(r, 1, scGray); + inc(r); + + // Set width of columns 0 to 3 + MyWorksheet.WriteColWidth(0, 48); // 48 characters, default is 12 --> 4x default width + lCol.Width := 24; // 24 characters, default is 12 --> 2x default width + MyWorksheet.WriteColInfo(1, lCol); + MyWorksheet.WriteColInfo(2, lCol); + MyWorksheet.WriteColInfo(3, lCol); + + // Set height of rows 5 and 6 + lRow.Height := 4; // 4 lines + MyWorksheet.WriteRowInfo(5, lRow); + lRow.Height := 2; // 2 lines + MyWorksheet.WriteRowInfo(6, lRow); + + CSVParams.ColDelimiter := #9; + CSVParams.DecimalSeparator := '.'; + CSVParams.DateTimeFormat := 'YYYYMMDD-HHNNSS'; + CSVParams.NumberFormat := '%.9f'; + CSVParams.QuoteChar := ''''; + + // Save the spreadsheet to a file + MyWorkbook.WriteToFile(MyDir + 'test' + STR_COMMA_SEPARATED_EXTENSION, sfCSV, true); + MyWorkbook.Free; +end. + diff --git a/components/fpspreadsheet/examples/spready/mainform.lfm b/components/fpspreadsheet/examples/spready/mainform.lfm index 51d03ba73..e64b0770a 100644 --- a/components/fpspreadsheet/examples/spready/mainform.lfm +++ b/components/fpspreadsheet/examples/spready/mainform.lfm @@ -516,14 +516,14 @@ object MainFrm: TMainFrm end object OpenDialog: TOpenDialog DefaultExt = '.xls' - Filter = 'Excel spreadsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Wikitable (pipes) (.wikitable_pipes)|*.wikitable_pipes|All files (*.*)|*.*' + Filter = 'Excel spreadsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Comma-delimited files (*.csv)|*.csv|Wikitable (pipes) (.wikitable_pipes)|*.wikitable_pipes|All files (*.*)|*.*' Options = [ofExtensionDifferent, ofEnableSizing, ofViewDetail] left = 184 top = 200 end object SaveDialog: TSaveDialog DefaultExt = '.xls' - Filter = 'Excel spreadsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Wikitable (wikimedia) (.wikitable_wikimedia)|*.wikitable_wikimedia' + Filter = 'Excel spreadsheet (*.xls)|*.xls|Excel XML spreadsheet (*.xlsx)|*.xlsx|LibreOffice/OpenOffice spreadsheet (*.ods)|*.ods|Comma-delimited file (*.csv)|*.csv|Wikitable (wikimedia) (.wikitable_wikimedia)|*.wikitable_wikimedia' Options = [ofOverwritePrompt, ofExtensionDifferent, ofEnableSizing, ofViewDetail] left = 184 top = 264 diff --git a/components/fpspreadsheet/fpsallformats.pas b/components/fpspreadsheet/fpsallformats.pas index fd4719b9c..2cf2c860a 100755 --- a/components/fpspreadsheet/fpsallformats.pas +++ b/components/fpspreadsheet/fpsallformats.pas @@ -10,7 +10,7 @@ unit fpsallformats; interface uses - xlsbiff2, xlsbiff5, xlsbiff8, fpsopendocument, xlsxooxml, wikitable; + xlsbiff2, xlsbiff5, xlsbiff8, fpsopendocument, xlsxooxml, wikitable, fpscsv; implementation diff --git a/components/fpspreadsheet/fpscsv.pas b/components/fpspreadsheet/fpscsv.pas new file mode 100644 index 000000000..5cbec9649 --- /dev/null +++ b/components/fpspreadsheet/fpscsv.pas @@ -0,0 +1,346 @@ +unit fpscsv; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + fpspreadsheet; + +type + TsCSVReader = class(TsCustomSpreadReader) + private + FFormatSettings: TFormatSettings; + FRow, FCol: Cardinal; + FCellValue: String; + FWorksheetName: String; + protected + procedure ProcessCellValue(AStream: TStream); + procedure ReadBlank(AStream: TStream); override; + procedure ReadFormula(AStream: TStream); override; + procedure ReadLabel(AStream: TStream); override; + procedure ReadNumber(AStream: TStream); override; + public + constructor Create(AWorkbook: TsWorkbook); override; + procedure ReadFromFile(AFileName: String; AData: TsWorkbook); override; + procedure ReadFromStream(AStream: TStream; AData: TsWorkbook); override; + procedure ReadFromStrings(AStrings: TStrings; AData: TsWorkbook); override; + end; + + TsCSVWriter = class(TsCustomSpreadWriter) + private + FFormatSettings: TFormatSettings; + + protected + procedure WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; + ACell: PCell); override; + procedure WriteDateTime(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: TDateTime; ACell: PCell); override; + procedure WriteFormula(AStream: TStream; const ARow, ACol: Cardinal; + ACell: PCell); override; + procedure WriteLabel(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: string; ACell: PCell); override; + procedure WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: double; ACell: PCell); override; + + procedure WriteSheet(AStream: TStream; AWorksheet: TsWorksheet); + + public + constructor Create(AWorkbook: TsWorkbook); override; + procedure WriteToStream(AStream: TStream); override; + procedure WriteToStrings(AStrings: TStrings); override; + end; + + TsCSVParams = record + LineDelimiter: String; // LineEnding + ColDelimiter: Char; // ';', ',', TAB (#9) + QuoteChar: Char; // use #0 if strings are not quoted + NumberFormat: String; // if empty, numbers are formatted as in sheet + DateTimeFormat: String; // if empty, date/times are formatted as in sheet + DecimalSeparator: Char; // '.', ',', #0 if using workbook's formatsetting + SheetIndex: Integer; // -1 for all sheets + end; + +var + CSVParams: TsCSVParams = ( + LineDelimiter: ''; // is replaced by LineEnding at runtime + ColDelimiter: ';'; + QuoteChar: '"'; + NumberFormat: ''; // Use number format of worksheet + DateTimeFormat: ''; // Use DateTime format of worksheet + DecimalSeparator: '.'; + SheetIndex: 0; // Store sheet #0 + ); + +implementation + +uses + StrUtils, DateUtils, fpsutils; + +{ -----------------------------------------------------------------------------} +{ TsCSVReader } +{------------------------------------------------------------------------------} +constructor TsCSVReader.Create(AWorkbook: TsWorkbook); +begin + inherited Create(AWorkbook); + FFormatSettings := AWorkbook.FormatSettings; + FWorksheetName := 'Sheet1'; +end; + +procedure TsCSVReader.ProcessCellValue(AStream: TStream); +begin + if FCellValue = '' then + ReadBlank(AStream) + else + if (Length(FCellValue) > 1) and ( + ((FCellValue[1] = '"') and (FCellValue[Length(FCellValue)] = '"')) + or + (not (CSVParams.QuoteChar in [#0, '"']) and (FCellValue[1] = CSVParams.QuoteChar) + and (FCellValue[Length(FCellValue)] = CSVParams.QuoteChar)) + ) then + begin + Delete(FCellValue, Length(FCellValue), 1); + Delete(FCellValue, 1, 1); + ReadLabel(AStream); + end else + ReadNumber(AStream); +end; + +procedure TsCSVReader.ReadBlank(AStream: TStream); +begin + // We could write a blank cell, but since CSV does not support formatting + // this would be a waste of memory. --> Just do nothing +end; + +procedure TsCSVReader.ReadFormula(AStream: TStream); +begin + // Nothing to do - CSV does not support formulas +end; + +procedure TsCSVReader.ReadFromFile(AFileName: String; AData: TsWorkbook); +begin + FWorksheetName := ChangeFileExt(ExtractFileName(AFileName), ''); + inherited; +end; + +procedure TsCSVReader.ReadFromStream(AStream: TStream; AData: TsWorkbook); +var + n: Int64; + ch: Char; + nextch: Char; +begin + FWorkbook := AData; + FWorksheet := AData.AddWorksheet(FWorksheetName); + n := AStream.Size; + FCellValue := ''; + FRow := 0; + FCol := 0; + while AStream.Position < n do begin + ch := char(AStream.ReadByte); + if ch = CSVParams.ColDelimiter then begin + // End of column reached + ProcessCellValue(AStream); + inc(FCol); + FCellValue := ''; + end else + if (ch = #13) or (ch = #10) then begin + // End of row reached + ProcessCellValue(AStream); + inc(FRow); + FCol := 0; + FCellValue := ''; + + // look for CR+LF: if true, skip next byte + if AStream.Position+1 < n then begin + nextch := char(AStream.ReadByte); + if ((ch = #13) and (nextch <> #10)) then + AStream.Position := AStream.Position - 1; // re-read nextchar in next loop + end; + end else + FCellValue := FCellValue + ch; + end; +end; + +procedure TsCSVReader.ReadFromStrings(AStrings: TStrings; AData: TsWorkbook); +var + stream: TStringStream; +begin + stream := TStringStream.Create(AStrings.Text); + try + ReadFromStream(stream, AData); + finally + stream.Free; + end; +end; + +procedure TsCSVReader.ReadLabel(AStream: TStream); +begin + Unused(AStream); + FWorksheet.WriteUTF8Text(FRow, FCol, FCellValue); +end; + +procedure TsCSVReader.ReadNumber(AStream: TStream); +var + dbl: Double; + dt: TDateTime; + fs: TFormatSettings; +begin + Unused(AStream); + + // Try as float + fs := FFormatSettings; + if CSVParams.DecimalSeparator <> #0 then + fs.DecimalSeparator := CSVParams.DecimalSeparator; + if TryStrToFloat(FCellValue, dbl, fs) then + begin + FWorksheet.WriteNumber(FRow, FCol, dbl); + FWorkbook.FormatSettings.DecimalSeparator := fs.DecimalSeparator; + exit; + end; + if fs.DecimalSeparator = '.' + then fs.DecimalSeparator := ',' + else fs.DecimalSeparator := '.'; + if TryStrToFloat(FCellValue, dbl, fs) then + begin + FWorksheet.WriteNumber(FRow, FCol, dbl); + FWorkbook.FormatSettings.DecimalSeparator := fs.DecimalSeparator; + exit; + end; + + // Try as date/time + fs := FFormatSettings; + if TryStrToDateTime(FCellValue, dt, fs) then + begin + FWorksheet.WriteDateTime(FRow, FCol, dt); + exit; + end; + + // Could not convert to float or date/time. Show at least as label. + FWorksheet.WriteUTF8Text(FRow, FCol, FCellValue); +end; + + +{ -----------------------------------------------------------------------------} +{ TsCSVWriter } +{------------------------------------------------------------------------------} +constructor TsCSVWriter.Create(AWorkbook: TsWorkbook); +begin + inherited Create(AWorkbook); + FFormatSettings := AWorkbook.FormatSettings; + if CSVParams.DecimalSeparator <> #0 then + FFormatSettings.DecimalSeparator := CSVParams.DecimalSeparator; + if CSVParams.LineDelimiter = '' then + CSVParams.LineDelimiter := LineEnding; +end; + +procedure TsCSVWriter.WriteBlank(AStream: TStream; const ARow, ACol: Cardinal; + ACell: PCell); +begin + Unused(AStream); + Unused(ARow, ACol, ACell); + // nothing to do +end; + +procedure TsCSVWriter.WriteDateTime(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: TDateTime; ACell: PCell); +var + s: String; +begin + Unused(ARow, ACol); + if CSVParams.DateTimeFormat <> '' then + s := FormatDateTime(CSVParams.DateTimeFormat, AValue, FFormatSettings) + else + s := FWorksheet.ReadAsUTF8Text(ACell); + AppendToStream(AStream, s); +end; + +procedure TsCSVWriter.WriteFormula(AStream: TStream; const ARow, ACol: Cardinal; + ACell: PCell); +begin + // no formulas in CSV + Unused(AStream); + Unused(ARow, ACol, AStream); +end; + +procedure TsCSVWriter.WriteLabel(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: string; ACell: PCell); +var + s: String; +begin + Unused(ARow, ACol); + if ACell = nil then + exit; + s := ACell^.UTF8StringValue; + if CSVParams.QuoteChar <> #0 then + s := CSVParams.QuoteChar + s + CSVParams.QuoteChar; + AppendToStream(AStream, s); +end; + +procedure TsCSVWriter.WriteNumber(AStream: TStream; const ARow, ACol: Cardinal; + const AValue: double; ACell: PCell); +var + s: String; + mask: String; +begin + Unused(ARow, ACol); + if ACell = nil then + exit; + if CSVParams.NumberFormat <> '' then + s := Format(CSVParams.NumberFormat, [AValue], FFormatSettings) + else + s := FWorksheet.ReadAsUTF8Text(ACell); + AppendToStream(AStream, s); +end; + +procedure TsCSVWriter.WriteSheet(AStream: TStream; AWorksheet: TsWorksheet); +var + r, c: Cardinal; + lastRow, lastCol: Cardinal; + cell: PCell; +begin + FWorksheet := AWorksheet; + 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 + AppendToStream(AStream, CSVParams.LineDelimiter) + else + AppendToStream(AStream, CSVParams.ColDelimiter); + end; +end; + +procedure TsCSVWriter.WriteToStream(AStream: TStream); +var + n: Integer; +begin + if (CSVParams.SheetIndex >= 0) and (CSVParams.SheetIndex < FWorkbook.GetWorksheetCount) + then n := CSVParams.SheetIndex + else n := 0; + WriteSheet(AStream, FWorkbook.GetWorksheetByIndex(n)); +end; + +procedure TsCSVWriter.WriteToStrings(AStrings: TStrings); +var + stream: TStream; +begin + stream := TStringStream.Create(''); + try + WriteToStream(stream); + stream.Position := 0; + AStrings.LoadFromStream(stream); + finally + stream.Free; + end; +end; + + +initialization + RegisterSpreadFormat(TsCSVReader, TsCSVWriter, sfCSV); + +end. +