diff --git a/components/fpspreadsheet/source/common/xlsxml.pas b/components/fpspreadsheet/source/common/xlsxml.pas index 16db956ba..39ecc9579 100644 --- a/components/fpspreadsheet/source/common/xlsxml.pas +++ b/components/fpspreadsheet/source/common/xlsxml.pas @@ -29,6 +29,7 @@ type { TsSpreadExcelXMLReader } TsSpreadExcelXMLReader = class(TsSpreadXMLReader) private + FDateMode: TDateMode; FPointSeparatorSettings: TFormatSettings; function ExtractDateTime(AText: String): TDateTime; @@ -449,10 +450,11 @@ var err: TsErrorValue; cell: PCell; fmt: TsCellFormat; + nfp: TsNumFormatParams; idx: Integer; mergedCols, mergedRows: Integer; font: TsFont; - rtp: TsRichTextParams; + dt: TDateTime; begin if ANode = nil then exit; @@ -470,7 +472,7 @@ begin if idx <> -1 then begin fmt := FCellFormatList.Items[idx]^; cell^.FormatIndex := book.AddCellFormat(fmt); - font := book.GetFont(fmt.FontIndex);; + font := book.GetFont(fmt.FontIndex); end; end; @@ -524,7 +526,15 @@ begin 'Number': sheet.WriteNumber(cell, StrToFloat(sv, FPointSeparatorSettings)); 'DateTime': - sheet.WriteDateTime(cell, ExtractDateTime(sv)); + begin + dt := ExtractDateTime(sv); + if (cell^.FormatIndex > 0) then begin + nfp := TsWorkbook(FWorkbook).GetNumberFormat(fmt.NumberFormatIndex); + if not IsTimeIntervalFormat(nfp) then + dt := ConvertExcelDateTimeToDateTime(dt, FDateMode); + end; + sheet.WriteDateTime(cell, dt); + end; 'Boolean': if sv = '1' then sheet.WriteBoolValue(cell, true) @@ -616,7 +626,10 @@ begin s := ANode.TextContent; if s = 'True' then FWorkbook.Protection := FWorkbook.Protection + [bpLockWindows]; - end; + end else + if nodeName = 'Date1904' then + FDateMode := dm1904; + ANode := ANode.NextSibling; end; end; @@ -761,12 +774,12 @@ procedure TsSpreadExcelXMLReader.ReadNames(ANode: TDOMNode; end; var - s, s1: String; + s: String; nodeName: String; sheet1, sheet2: String; r1, c1, r2, c2: Cardinal; flags: TsRelFlags; - p, q: Integer; + p: Integer; begin while ANode <> nil do begin nodeName := ANode.NodeName; @@ -811,8 +824,27 @@ begin s := GetAttrValue(ANode, 'ss:Format'); case s of - 'General': - exit; + 'General': Exit; + 'Standard': + begin + nf := nfFixedTh; + nfs := BuildNumberFormatString(nf, FWorkbook.FormatSettings, 2); + end; + 'Fixed': + begin + nf := nfFixed; + nfs := BuildNumberFormatString(nf, FWorkbook.FormatSettings, 2); + end; + 'Percent': + begin + nf := nfPercentage; + nfs := BuildNumberFormatString(nf, FWorkbook.FormatSettings, 2); + end; + 'Scientific': + begin + nf := nfExp; + nfs := BuildNumberFormatString(nf, FWorkbook.FormatSettings); + end; 'Short Date': begin nf := nfShortDate; @@ -866,7 +898,6 @@ var nodeName: String; fmt: TsCellFormat; s: String; - id: Integer; idx: Integer; childNode: TDOMNode; begin @@ -1064,8 +1095,6 @@ var n: Integer; hasFitToPage: Boolean = false; c, r: Cardinal; - r1, c1, r2, c2: Cardinal; - flags: TsRelFlags; begin if ANode = nil then exit; @@ -1391,7 +1420,11 @@ begin Result := ''; comment := (FWorksheet as TsWorksheet).FindComment(ACell); if Assigned(comment) then - Result := INDENT1 + '' + comment^.Text + '' + LF + CELL_INDENT; + Result := INDENT1 + + '' + + UTF8TextToXMLText(comment^.Text) + + '' + + LF + CELL_INDENT; // If there will be some rich-text-like formatting in the future, use // Result := ''+comment^.Text+'': end; @@ -1597,16 +1630,19 @@ var c, c1, c2: Cardinal; colwidthStr: String; styleStr: String; + hiddenStr: String; col: PCol; begin c1 := 0; c2 := TsWorksheet(AWorksheet).GetLastColIndex; - FPrevCol := -1; + FPrevCol := UNASSIGNED_ROW_COL_INDEX; for c := c1 to c2 do begin col := TsWorksheet(AWorksheet).FindCol(c); styleStr := ''; colWidthStr := ''; + hiddenStr := ''; + if Assigned(col) then begin // column width is needed in pts. @@ -1618,9 +1654,13 @@ begin if col^.FormatIndex > 0 then styleStr := GetStyleStr(col^.FormatIndex); end; - if (colWidthStr <> '') or (stylestr <> '') then begin + + if TsWorksheet(AWorksheet).ColHidden(c) then + hiddenStr := ' ss:Hidden="1"'; + + if (colWidthStr <> '') or (stylestr <> '') or (hiddenstr <> '') then begin AppendToStream(AStream, COL_INDENT + Format( - '' + LF, [GetIndexStr(c, FPrevCol), colWidthStr, styleStr])); + '' + LF, [GetIndexStr(c, FPrevCol), colWidthStr, styleStr, hiddenStr])); FPrevCol := c; end; end; @@ -1708,6 +1748,8 @@ end; procedure TsSpreadExcelXMLWriter.WriteLabel(AStream: TStream; const ARow, ACol: Cardinal; const AValue: string; ACell: PCell); +const + MAXBYTES = 32767; // limit for this format var valueStr: String; cctStr: String; @@ -1715,14 +1757,31 @@ var dataTagStr: String; p: Integer; tmp: String; - ch:char; + ResultingValue: String; begin + // Office 2007-2010 (at least) supports no more characters in a cell; + if Length(AValue) > MAXBYTES then + begin + ResultingValue := Copy(AValue, 1, MAXBYTES); //may chop off multicodepoint UTF8 characters but well... + Workbook.AddErrorMsg(rsTruncateTooLongCellText, [ + MAXBYTES, GetCellString(ARow, ACol) + ]); + end else + resultingValue := AValue; + + { Check for invalid characters } + if not ValidXMLText(ResultingValue) then + Workbook.AddErrorMsg( + rsInvalidCharacterInCell, [ + GetCellString(ARow, ACol) + ]); + if Length(ACell^.RichTextParams) > 0 then begin RichTextToHTML( FWorkbook as TsWorkbook, (FWorksheet as TsWorksheet).ReadCellFont(ACell), - AValue, + ResultingValue, ACell^.RichTextParams, valueStr, // html-formatted rich text 'html:', tcProperCase @@ -1749,7 +1808,7 @@ begin end; end else begin - valueStr := AValue; + valueStr := ResultingValue; if not ValidXMLText(valueStr, true, true) then Workbook.AddErrorMsg( rsInvalidCharacterInCell, [ @@ -1806,6 +1865,7 @@ var r, r1, r2: Cardinal; cell: PCell; rowheightStr: String; + hiddenStr: String; styleStr: String; row: PRow; hasCells: Boolean; @@ -1816,11 +1876,12 @@ begin r2 := sheet.GetLastRowIndex; c2 := sheet.GetLastColIndex; - FPrevRow := -1; + FPrevRow := UNASSIGNED_ROW_COL_INDEX; for r := r1 to r2 do begin row := sheet.FindRow(r); styleStr := ''; + hiddenStr := ''; // Row height is needed in pts. if Assigned(row) then begin @@ -1837,6 +1898,9 @@ begin end else rowheightStr := ' ss:AutoFitHeight="1"'; + if sheet.RowHidden(r) then + hiddenStr := ' ss:Hidden="1"'; + hasCells := false; for c := c1 to c2 do begin cell := sheet.FindCell(r, c); @@ -1847,7 +1911,7 @@ begin end; AppendToStream(AStream, ROW_INDENT + Format( - '' + LF) @@ -1856,7 +1920,7 @@ begin Continue; end; - FPrevCol := -1; + FPrevCol := UNASSIGNED_ROW_COL_INDEX; for c := c1 to c2 do begin cell := sheet.FindCell(r, c); @@ -2050,20 +2114,8 @@ end; procedure TsSpreadExcelXMLWriter.WriteTable(AStream: TStream; AWorksheet: TsBasicWorksheet); var - c, c1, c2: Cardinal; - r, r1, r2: Cardinal; - cell: PCell; - rowheightStr: String; - colwidthStr: String; - styleStr: String; - col: PCol; - row: PRow; sheet: TsWorksheet absolute AWorksheet; begin - r1 := 0; - c1 := 0; - r2 := sheet.GetLastRowIndex; - c2 := sheet.GetLastColIndex; AppendToStream(AStream, TABLE_INDENT + Format( '' + LF else + hideGridStr := INDENT3 + '' + LF + else hideGridStr := ''; // Show/hide column/row headers if not (soShowHeaders in AWorksheet.Options) then - hideHeadersStr := INDENT3 + '' + LF else + hideHeadersStr := INDENT3 + '' + LF + else hideHeadersStr := ''; if (FWorkbook as TsWorkbook).ActiveWorksheet = AWorksheet then - selectedStr := INDENT3 + '' + LF else + selectedStr := INDENT3 + '' + LF + else selectedStr := ''; + // Visible + if (soHidden in AWorksheet.Options) then + visibleStr := INDENT3 + 'SheetHidden' + LF + else + visibleStr := ''; + // Frozen panes frozenStr := GetFrozenPanesStr(AWorksheet, INDENT3); @@ -2198,6 +2260,7 @@ begin footerStr + marginStr + INDENT3 + '' + LF + + visibleStr + selectedStr + protectStr + frozenStr + diff --git a/components/fpspreadsheet/tests/celltypetests.pas b/components/fpspreadsheet/tests/celltypetests.pas index 19e844cd7..4b3605fa4 100644 --- a/components/fpspreadsheet/tests/celltypetests.pas +++ b/components/fpspreadsheet/tests/celltypetests.pas @@ -43,6 +43,9 @@ type // OOXML test cases procedure TestWriteRead_Bool_OOXML; + // Excel2003/XML test cases + procedure TestWriteRead_Bool_XML; + // CSV test cases procedure TestWriteRead_Bool_CSV; end; @@ -191,6 +194,12 @@ begin TestWriteRead_Bool(sfOOXML); end; +{ XML } +procedure TSpreadWriteReadCellTypeTests.TestWriteRead_Bool_XML; +begin + TestWriteRead_Bool(sfExcelXML); +end; + { CSV } procedure TSpreadWriteReadCellTypeTests.TestWriteRead_Bool_CSV; begin diff --git a/components/fpspreadsheet/tests/colortests.pas b/components/fpspreadsheet/tests/colortests.pas index 289de89c8..3b23d0189 100644 --- a/components/fpspreadsheet/tests/colortests.pas +++ b/components/fpspreadsheet/tests/colortests.pas @@ -1,11 +1,13 @@ +{ Color tests +-------------------------------------------------------------------------------- + This unit tests writing out to and reading back from files. +} + unit colortests; {$mode objfpc}{$H+} interface -{ Color tests -This unit tests writing out to and reading back from files. -} uses // Not using Lazarus package as the user may be working with multiple versions @@ -78,6 +80,18 @@ type procedure TestWriteRead_OOXML_Font_Biff5Pal; // official biff5 palette in BIFF8 file format procedure TestWriteRead_OOXML_Font_Biff8Pal; // official biff8 palette in BIFF8 file format procedure TestWriteRead_OOXML_Font_RandomPal; // palette 64, top 56 entries random + + { Excel 2003/XML file format tests } + // Background colors... + procedure TestWriteRead_XML_Background_InternalPal; // internal palette + procedure TestWriteRead_XML_Background_Biff5Pal; // official biff5 palette + procedure TestWriteRead_XML_Background_Biff8Pal; // official biff8 palette + procedure TestWriteRead_XML_Background_RandomPal; // palette 64, top 56 entries random + // Font colors... + procedure TestWriteRead_XML_Font_InternalPal; // internal palette for BIFF8 file format + procedure TestWriteRead_XML_Font_Biff5Pal; // official biff5 palette in BIFF8 file format + procedure TestWriteRead_XML_Font_Biff8Pal; // official biff8 palette in BIFF8 file format + procedure TestWriteRead_XML_Font_RandomPal; // palette 64, top 56 entries random end; @@ -458,6 +472,48 @@ begin end; +{ Tests for Excel 2003/XML file format } +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Background_InternalPal; +begin + TestWriteReadBackgroundColors(sfExcelXML, 0); +end; + +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Background_Biff5Pal; +begin + TestWriteReadBackgroundColors(sfExcelXML, 5); +end; + +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Background_Biff8Pal; +begin + TestWriteReadBackgroundColors(sfExcelXML, 8); +end; + +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Background_RandomPal; +begin + TestWriteReadBackgroundColors(sfExcelXML, 999); +end; + +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Font_InternalPal; +begin + TestWriteReadFontColors(sfExcelXML, 0); +end; + +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Font_Biff5Pal; +begin + TestWriteReadFontColors(sfExcelXML, 5); +end; + +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Font_Biff8Pal; +begin + TestWriteReadFontColors(sfExcelXML, 8); +end; + +procedure TSpreadWriteReadColorTests.TestWriteRead_XML_Font_RandomPal; +begin + TestWriteReadFontColors(sfExcelXML, 999); +end; + + initialization RegisterTest(TSpreadWriteReadColorTests); diff --git a/components/fpspreadsheet/tests/colrowtests.pas b/components/fpspreadsheet/tests/colrowtests.pas index 6998102a5..e630a24ef 100644 --- a/components/fpspreadsheet/tests/colrowtests.pas +++ b/components/fpspreadsheet/tests/colrowtests.pas @@ -222,52 +222,58 @@ type procedure TestWriteRead_HideColDef_BIFF5; procedure TestWriteRead_HideColDef_BIFF8; procedure TestWriteRead_HideColDef_OOXML; + procedure TestWriteRead_HideColDef_XML; procedure TestWriteRead_HideColDef_ODS; // Hide a row having default row height procedure TestWriteRead_HideRowDef_BIFF5; procedure TestWriteRead_HideRowDef_BIFF8; procedure TestWriteRead_HideRowDef_OOXML; + procedure TestWriteRead_HideRowDef_XML; procedure TestWriteRead_HideRowDef_ODS; // Show a hidden column having default col width procedure TestWriteRead_ShowColDef_BIFF5; procedure TestWriteRead_ShowColDef_BIFF8; procedure TestWriteRead_ShowColDef_OOXML; + procedure TestWriteRead_ShowColDef_XML; procedure TestWriteRead_ShowColDef_ODS; // Show a hidden row having default row height procedure TestWriteRead_ShowRowDef_BIFF5; procedure TestWriteRead_ShowRowDef_BIFF8; procedure TestWriteRead_ShowRowDef_OOXML; + procedure TestWriteRead_ShowRowDef_XML; procedure TestWriteRead_ShowRowDef_ODS; - // Hide a column procedure TestWriteRead_HideCol_BIFF5; procedure TestWriteRead_HideCol_BIFF8; procedure TestWriteRead_HideCol_OOXML; + procedure TestWriteRead_HideCol_XML; procedure TestWriteRead_HideCol_ODS; // Hide a row procedure TestWriteRead_HideRow_BIFF5; procedure TestWriteRead_HideRow_BIFF8; procedure TestWriteRead_HideRow_OOXML; + procedure TestWriteRead_HideRow_XML; procedure TestWriteRead_HideRow_ODS; // Show a hidden column procedure TestWriteRead_ShowCol_BIFF5; procedure TestWriteRead_ShowCol_BIFF8; procedure TestWriteRead_ShowCol_OOXML; + procedure TestWriteRead_ShowCol_XML; procedure TestWriteRead_ShowCol_ODS; // Show a hidden row procedure TestWriteRead_ShowRow_BIFF5; procedure TestWriteRead_ShowRow_BIFF8; procedure TestWriteRead_ShowRow_OOXML; + procedure TestWriteRead_ShowRow_XML; procedure TestWriteRead_ShowRow_ODS; - end; implementation @@ -1920,6 +1926,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideColDef_OOXML; begin TestWriteRead_HideShowColRow(true, true, true, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideColDef_XML; +begin + TestWriteRead_HideShowColRow(true, true, true, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideColDef_ODS; begin TestWriteRead_HideShowColRow(true, true, true, sfOpenDocument); @@ -1938,6 +1948,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideRowDef_OOXML; begin TestWriteRead_HideShowColRow(false, true, true, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideRowDef_XML; +begin + TestWriteRead_HideShowColRow(false, true, true, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideRowDef_ODS; begin TestWriteRead_HideShowColRow(false, true, true, sfOpenDocument); @@ -1956,6 +1970,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowColDef_OOXML; begin TestWriteRead_HideShowColRow(true, false, true, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowColDef_XML; +begin + TestWriteRead_HideShowColRow(true, false, true, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowColDef_ODS; begin TestWriteRead_HideShowColRow(true, false, true, sfOpenDocument); @@ -1974,6 +1992,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowRowDef_OOXML; begin TestWriteRead_HideShowColRow(false, false, true, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowRowDef_XML; +begin + TestWriteRead_HideShowColRow(false, false, true, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowRowDef_ODS; begin TestWriteRead_HideShowColRow(false, false, true, sfOpenDocument); @@ -1995,6 +2017,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideCol_OOXML; begin TestWriteRead_HideShowColRow(true, true, false, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideCol_XML; +begin + TestWriteRead_HideShowColRow(true, true, false, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideCol_ODS; begin TestWriteRead_HideShowColRow(true, true, false, sfOpenDocument); @@ -2013,6 +2039,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideRow_OOXML; begin TestWriteRead_HideShowColRow(false, true, false, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideRow_XML; +begin + TestWriteRead_HideShowColRow(false, true, false, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_HideRow_ODS; begin TestWriteRead_HideShowColRow(false, true, false, sfOpenDocument); @@ -2031,6 +2061,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowCol_OOXML; begin TestWriteRead_HideShowColRow(true, false, false, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowCol_XML; +begin + TestWriteRead_HideShowColRow(true, false, false, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowCol_ODS; begin TestWriteRead_HideShowColRow(true, false, false, sfOpenDocument); @@ -2049,6 +2083,10 @@ procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowRow_OOXML; begin TestWriteRead_HideShowColRow(false, false, false, sfOOXML); end; +procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowRow_XML; +begin + TestWriteRead_HideShowColRow(false, false, false, sfExcelXML); +end; procedure TSpreadWriteRead_ColRow_Tests.TestWriteRead_ShowRow_ODS; begin TestWriteRead_HideShowColRow(false, false, false, sfOpenDocument); diff --git a/components/fpspreadsheet/tests/commenttests.pas b/components/fpspreadsheet/tests/commenttests.pas index 88f4661a9..cae51ed74 100644 --- a/components/fpspreadsheet/tests/commenttests.pas +++ b/components/fpspreadsheet/tests/commenttests.pas @@ -60,6 +60,12 @@ type procedure TestWriteRead_OOXML_NonAscii_Comment; procedure TestWriteRead_OOXML_NonXMLChar_Comment; procedure TestWriteRead_OOXML_VeryLong_Comment; + + { XML comment tests } + procedure TestWriteRead_XML_Standard_Comment; + procedure TestWriteRead_XML_NonAscii_Comment; + procedure TestWriteRead_XML_NonXMLChar_Comment; + procedure TestWriteRead_XML_VeryLong_Comment; end; implementation @@ -284,6 +290,29 @@ begin TestWriteRead_Comment(sfOOXML, VERY_LONG_COMMENT); end; + +{ Tests for Excel 2003/XML file format } +procedure TSpreadWriteReadCommentTests.TestWriteRead_XML_Standard_Comment; +begin + TestWriteRead_Comment(sfExcelXML, STANDARD_COMMENT); +end; + +procedure TSpreadWriteReadCommentTests.TestWriteRead_XML_NonAscii_Comment; +begin + TestWriteRead_Comment(sfExcelXML, COMMENT_UTF8); +end; + +procedure TSpreadWriteReadCommentTests.TestWriteRead_XML_NonXMLChar_Comment; +begin + TestWriteRead_Comment(sfExcelXML, COMMENT_XML); +end; + +procedure TSpreadWriteReadCommentTests.TestWriteRead_XML_VeryLong_Comment; +begin + TestWriteRead_Comment(sfExcelXML, VERY_LONG_COMMENT); +end; + + initialization RegisterTest(TSpreadWriteReadCommentTests); diff --git a/components/fpspreadsheet/tests/datetests.pas b/components/fpspreadsheet/tests/datetests.pas index 246e0fcb3..1ac6732fa 100644 --- a/components/fpspreadsheet/tests/datetests.pas +++ b/components/fpspreadsheet/tests/datetests.pas @@ -297,12 +297,14 @@ type procedure TestWriteReadDates_BIFF8; procedure TestWriteReadDates_ODS; procedure TestWriteReadDates_OOXML; + procedure TestWriteReadDates_XML; procedure TestWriteReadMilliseconds_BIFF2; procedure TestWriteReadMilliseconds_BIFF5; procedure TestWriteReadMilliseconds_BIFF8; procedure TestWriteReadMilliseconds_ODS; procedure TestWriteReadMilliseconds_OOXML; + procedure TestWriteReadMilliseconds_XML; end; @@ -565,6 +567,11 @@ begin TestWriteReadDates(sfOOXML); end; +procedure TSpreadWriteReadDateTests.TestWriteReadDates_XML; +begin + TestWriteReadDates(sfExcelXML); +end; + { TSpreadReadDateTests } @@ -1815,6 +1822,11 @@ begin TestWriteReadMilliseconds(sfOOXML); end; +procedure TSpreadWriteReadDateTests.TestWriteReadMilliseconds_XML; +begin + TestWriteReadMilliseconds(sfExcelXML); +end; + initialization // Register so these tests are included in a full run diff --git a/components/fpspreadsheet/tests/errortests.pas b/components/fpspreadsheet/tests/errortests.pas index e2520f13b..ea046a6c5 100644 --- a/components/fpspreadsheet/tests/errortests.pas +++ b/components/fpspreadsheet/tests/errortests.pas @@ -30,6 +30,7 @@ type procedure TestWriteErrorMessages_BIFF8; procedure TestWriteErrorMessages_ODS; procedure TestWriteErrorMessages_OOXML; + procedure TestWriteErrorMessages_XML; end; implementation @@ -253,6 +254,11 @@ begin TestWriteErrorMessages(sfOOXML); end; +procedure TSpreadErrorTests.TestWriteErrorMessages_XML; +begin + TestWriteErrorMessages(sfExcelXML); +end; + initialization // Register so these tests are included in a full run diff --git a/components/fpspreadsheet/tests/formattests.pas b/components/fpspreadsheet/tests/formattests.pas index 5262e392a..c7a3d0188 100644 --- a/components/fpspreadsheet/tests/formattests.pas +++ b/components/fpspreadsheet/tests/formattests.pas @@ -154,6 +154,20 @@ type procedure TestWriteRead_OOXML_WordWrap; procedure TestWriteRead_OOXML_FormatStrings; + { Excel 2003/XML Tests } + procedure TestWriteRead_XML_Alignment; + procedure TestWriteRead_XML_Background; + procedure TestWriteRead_XML_Border; + procedure TestWriteRead_XML_BorderStyles; + procedure TestWriteRead_XML_ColWidths; + procedure TestWriteRead_XML_RowHeights; + procedure TestWriteRead_XML_DateTimeFormats; + procedure TestWriteRead_XML_MergedCells; + procedure TestWriteRead_XML_NumberFormats; + procedure TestWriteRead_XML_TextRotation; + procedure TestWriteRead_XML_WordWrap; + procedure TestWriteRead_XML_FormatStrings; + { CSV Tests } procedure TestWriteRead_CSV_DateTimeFormats; procedure TestWriteRead_CSV_NumberFormats_0; @@ -458,6 +472,11 @@ begin TestWriteRead_NumberFormats(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_NumberFormats; +begin + TestWriteRead_NumberFormats(sfExcelXML); +end; + procedure TSpreadWriteReadFormatTests.TestWriteRead_CSV_NumberFormats_0; begin TestWriteRead_NumberFormats(sfCSV, 0); @@ -565,6 +584,11 @@ begin TestWriteRead_DateTimeFormats(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_DateTimeFormats; +begin + TestWriteRead_DateTimeFormats(sfExcelXML); +end; + procedure TSpreadWriteReadFormatTests.TestWriteRead_CSV_DateTimeFormats; begin TestWriteRead_DateTimeFormats(sfCSV); @@ -721,6 +745,11 @@ begin TestWriteRead_Alignment(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_Alignment; +begin + TestWriteRead_Alignment(sfExcelXML); +end; + { This test writes in column A the names of the Background.Styles, in column B the background fill with a specific pattern and background color, in column C @@ -846,6 +875,11 @@ begin TestWriteRead_Background(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_Background; +begin + TestWriteRead_Background(sfExcelXML); +end; + { --- Border on/off tests --- } @@ -953,6 +987,11 @@ begin TestWriteRead_Border(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_Border; +begin + TestWriteRead_Border(sfExcelXML); +end; + { --- BorderStyle tests --- } @@ -1101,6 +1140,11 @@ begin TestWriteRead_BorderStyles(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_BorderStyles; +begin + TestWriteRead_BorderStyles(sfExcelXML); +end; + { --- Column widths tests --- } @@ -1186,6 +1230,11 @@ begin TestWriteRead_ColWidths(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_ColWidths; +begin + TestWriteRead_ColWidths(sfExcelXML); +end; + { --- Row height tests --- } @@ -1275,6 +1324,11 @@ begin TestWriteRead_RowHeights(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_RowHeights; +begin + TestWriteRead_RowHeights(sfExcelXML); +end; + { --- Text rotation tests --- } @@ -1360,6 +1414,11 @@ begin TestWriteRead_TextRotation(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_TextRotation; +begin + TestWriteRead_TextRotation(sfExcelXML); +end; + { --- Wordwrap tests --- } @@ -1447,6 +1506,11 @@ begin TestWriteRead_Wordwrap(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_Wordwrap; +begin + TestWriteRead_Wordwrap(sfExcelXML); +end; + { --- Merged tests --- } @@ -1601,6 +1665,12 @@ begin TestWriteRead_MergedCells(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_MergedCells; +begin + TestWriteRead_MergedCells(sfExcelXML); +end; + + { If a biff2 file contains more than 62 XF records the XF record index is stored in a separats IXFE record. This is tested here. } procedure TSpreadWriteReadFormatTests.TestWriteRead_ManyXF(AFormat: TsSpreadsheetFormat); @@ -1757,6 +1827,11 @@ begin TestWriteRead_FormatStrings(sfOOXML); end; +procedure TSpreadWriteReadFormatTests.TestWriteRead_XML_FormatStrings; +begin + TestWriteRead_FormatStrings(sfExcelXML); +end; + procedure TSpreadWriteReadFormatTests.TestWriteRead_ODS_FormatStrings; begin TestWriteRead_FormatStrings(sfOpenDocument); diff --git a/components/fpspreadsheet/tests/optiontests.pas b/components/fpspreadsheet/tests/optiontests.pas index fdc97ebae..f8aa6110e 100644 --- a/components/fpspreadsheet/tests/optiontests.pas +++ b/components/fpspreadsheet/tests/optiontests.pas @@ -94,6 +94,20 @@ type procedure TestWriteRead_OOXML_Panes_None; procedure TestWriteRead_OOXML_HiddenSheet; + + { Excel 2003/XML tests } + procedure TestWriteRead_XML_ShowGridLines_ShowHeaders; + procedure TestWriteRead_XML_ShowGridLines_HideHeaders; + procedure TestWriteRead_XML_HideGridLines_ShowHeaders; + procedure TestWriteRead_XML_HideGridLines_HideHeaders; + + procedure TestWriteRead_XML_Panes_HorVert; + procedure TestWriteRead_XML_Panes_Hor; + procedure TestWriteRead_XML_Panes_Vert; + procedure TestWriteRead_XML_Panes_None; + + procedure TestWriteRead_XML_HiddenSheet; + end; implementation @@ -272,6 +286,28 @@ begin end; +{ Tests for Excel2003/XML grid lines and/or headers } +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_ShowGridLines_ShowHeaders; +begin + TestWriteReadGridHeaders(sfExcelXML, true, true); +end; + +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_ShowGridLines_HideHeaders; +begin + TestWriteReadGridHeaders(sfExcelXML, true, false); +end; + +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_HideGridLines_ShowHeaders; +begin + TestWriteReadGridHeaders(sfExcelXML, false, true); +end; + +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_HideGridLines_HideHeaders; +begin + TestWriteReadGridHeaders(sfExcelXML, false, false); +end; + + { Test for frozen panes } procedure TSpreadWriteReadOptionsTests.TestWriteReadPanes(AFormat: TsSpreadsheetFormat; @@ -431,6 +467,28 @@ begin end; +{ Tests for Excel 2003/XML frozen panes } +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_Panes_HorVert; +begin + TestWriteReadPanes(sfExcelXML, 1, 2); +end; + +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_Panes_Hor; +begin + TestWriteReadPanes(sfExcelXML, 1, 0); +end; + +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_Panes_Vert; +begin + TestWriteReadPanes(sfExcelXML, 0, 2); +end; + +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_Panes_None; +begin + TestWriteReadPanes(sfExcelXML, 0, 0); +end; + + procedure TSpreadWriteReadOptionsTests.TestWriteReadHiddenSheet( AFormat: TsSpreadsheetFormat); const @@ -491,6 +549,11 @@ begin TestWriteReadHiddenSheet(sfOpenDocument); end; +procedure TSpreadWriteReadOptionsTests.TestWriteRead_XML_HiddenSheet; +begin + TestWriteReadHiddenSheet(sfExcelXML); +end; + initialization RegisterTest(TSpreadWriteReadOptionsTests); diff --git a/components/fpspreadsheet/tests/singleformulatests.pas b/components/fpspreadsheet/tests/singleformulatests.pas index 594e01ca8..65a54348a 100644 --- a/components/fpspreadsheet/tests/singleformulatests.pas +++ b/components/fpspreadsheet/tests/singleformulatests.pas @@ -35,12 +35,14 @@ type procedure AddConst_BIFF5; procedure AddConst_BIFF8; procedure AddConst_OOXML; + procedure AddConst_XML; procedure AddConst_ODS; procedure AddCells_BIFF2; procedure AddCells_BIFF5; procedure AddCells_BIFF8; procedure AddCells_OOXML; + procedure AddCells_XML; procedure AddCells_ODS; procedure RoundConst1_ODS; @@ -66,16 +68,19 @@ type procedure SumRange_BIFF5; procedure SumRange_BIFF8; procedure SumRange_OOXML; + procedure SumRange_XML; procedure SumRange_ODS; procedure SumSheetRange_BIFF5; // no 3d ranges for BIFF2 procedure SumSheetRange_BIFF8; procedure SumSheetRange_OOXML; + procedure SumSheetRange_XML; procedure SumSheetRange_ODS; procedure SumMultiSheetRange_BIFF5; procedure SumMultiSheetRange_BIFF8; procedure SumMultiSheetRange_OOXML; + procedure SumMultiSheetRange_XML; procedure SumMultiSheetRange_ODS; procedure SumMultiSheetRange_FlippedCells_BIFF8; @@ -86,6 +91,7 @@ type procedure IfConst_BIFF8; procedure IfConst_OOXML; + procedure IfConst_XML; procedure IfConst_ODS; procedure IfConst_BIFF8_2; @@ -104,11 +110,13 @@ type procedure NonExistantSheet_BIFF5; procedure NonExistantSheet_BIFF8; procedure NonExistantSheet_OOXML; + procedure NonExistantSheet_XML; procedure NonExistantSheet_ODS; procedure NonExistantSheetRange_BIFF5; procedure NonExistantSheetRange_BIFF8; procedure NonExistantSheetRange_OOXML; + procedure NonExistantSheetRange_XML; procedure NonExistantSheetRange_ODS; procedure RenameWorksheet_Single; @@ -314,6 +322,11 @@ begin TestFormula('1+1', '2', ftkConstants, sfOOXML); end; +procedure TSpreadSingleFormulaTests.AddConst_XML; +begin + TestFormula('1+1', '2', ftkConstants, sfExcelXML); +end; + procedure TSpreadSingleFormulaTests.AddConst_ODS; begin TestFormula('1+1', '2', ftkConstants, sfOpenDocument); @@ -341,6 +354,11 @@ begin TestFormula('C3+C4', '-1', ftkCells, sfOOXML); end; +procedure TSpreadSingleFormulaTests.AddCells_XML; +begin + TestFormula('C3+C4', '-1', ftkCells, sfExcelXML); +end; + procedure TSpreadSingleFormulaTests.AddCells_ODS; begin TestFormula('C3+C4', '-1', ftkCells, sfOpenDocument); @@ -472,6 +490,11 @@ begin TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfOOXML); end; +procedure TSpreadSingleFormulaTests.SumRange_XML; +begin + TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfExcelXML); +end; + procedure TSpreadSingleFormulaTests.SumRange_ODS; begin TestFormula('SUM(C3:C5)', '0.5', ftkCellRange, sfOpenDocument); @@ -494,6 +517,11 @@ begin TestFormula('SUM(Sheet2!C3:C5)', '5', ftkCellRangeSheet, sfOOXML); end; +procedure TSpreadSingleFormulaTests.SumSheetRange_XML; +begin + TestFormula('SUM(Sheet2!C3:C5)', '5', ftkCellRangeSheet, sfExcelXML); +end; + procedure TSpreadSingleFormulaTests.SumSheetRange_ODS; begin TestFormula('SUM(Sheet2!C3:C5)', '5', ftkCellRangeSheet, sfOpenDocument); @@ -516,6 +544,11 @@ begin TestFormula('SUM(Sheet2:Sheet3!C3:C5)', '55', ftkCellRangeSheetRange, sfOOXML); end; +procedure TSpreadSingleFormulaTests.SumMultiSheetRange_XML; +begin + TestFormula('SUM(Sheet2:Sheet3!C3:C5)', '55', ftkCellRangeSheetRange, sfExcelXML); +end; + procedure TSpreadSingleFormulaTests.SumMultiSheetRange_ODS; begin TestFormula('SUM(Sheet2:Sheet3!C3:C5)', '55', ftkCellRangeSheetRange, sfOpenDocument); @@ -564,6 +597,11 @@ begin TestFormula('IF(C3="A","is A","not A")', 'not A', ftkCellConstant, sfOOXML); end; +procedure TSpreadSingleFormulaTests.IfConst_XML; +begin + TestFormula('IF(C3="A","is A","not A")', 'not A', ftkCellConstant, sfExcelXML); +end; + procedure TSpreadSingleFormulaTests.IfConst_ODS; begin TestFormula('IF(C3="A","is A","not A")', 'not A', ftkCellConstant, sfOpenDocument); @@ -637,6 +675,11 @@ begin TestFormula('Missing!C3', '#REF!', ftkCellRangeSheet, sfOOXML, '#REF!'); end; +procedure TSpreadSingleFormulaTests.NonExistantSheet_XML; +begin + TestFormula('Missing!C3', '#REF!', ftkCellRangeSheet, sfExcelXML, '#REF!'); +end; + procedure TSpreadSingleFormulaTests.NonExistantSheet_ODS; begin TestFormula('Missing!C3', '#REF!', ftkCellRangeSheet, sfOpenDocument, '#REF!'); @@ -659,6 +702,11 @@ begin TestFormula('SUM(Missing1:Missing2!C3)', '#REF!', ftkCellRangeSheet, sfOOXML, 'SUM(#REF!)'); end; +procedure TSpreadSingleFormulaTests.NonExistantSheetRange_XML; +begin + TestFormula('SUM(Missing1:Missing2!C3)', '#REF!', ftkCellRangeSheet, sfExcelXML, 'SUM(#REF!)'); +end; + procedure TSpreadSingleFormulaTests.NonExistantSheetRange_ODS; begin TestFormula('SUM(Missing1:Missing2!C3)', '#REF!', ftkCellRangeSheet, sfOpenDocument, 'SUM(#REF!)'); diff --git a/components/fpspreadsheet/tests/stringtests.pas b/components/fpspreadsheet/tests/stringtests.pas index 77c353ebe..d5b49ae46 100644 --- a/components/fpspreadsheet/tests/stringtests.pas +++ b/components/fpspreadsheet/tests/stringtests.pas @@ -94,6 +94,20 @@ type procedure TestReadOOXMLString12; procedure TestReadOOXMLString13; + procedure TestReadXMLString0; //Excel2003/XML format empty string + procedure TestReadXMLString1; + procedure TestReadXMLString2; + procedure TestReadXMLString3; + procedure TestReadXMLString4; + procedure TestReadXMLString5; + procedure TestReadXMLString6; + procedure TestReadXMLString7; + procedure TestReadXMLString8; + procedure TestReadXMLString9; + procedure TestReadXMLString10; + procedure TestReadXMLString11; + procedure TestReadXMLString12; + procedure TestReadXMLString13; end; { TSpreadWriteReadStringTests } @@ -340,6 +354,7 @@ begin case Uppercase(ExtractFileExt(FileName)) of '.XLSX': AFormat := sfOOXML; '.ODS' : AFormat := sfOpenDocument; + '.XML' : AFormat := sfExcelXML; else AFormat := sfExcel8; end; TestWorkbook.ReadFromFile(FileName, AFormat); @@ -511,7 +526,7 @@ begin TestReadString(ExtractFilePath(ParamStr(0)) + TestFileODF,13); end; -{ ODF Tests } +{ Excel XLSX Tests } procedure TSpreadReadStringTests.TestReadOOXMLString0; begin TestReadString(ExtractFilePath(ParamStr(0)) + TestFileOOXML,0); @@ -582,6 +597,77 @@ begin TestReadString(ExtractFilePath(ParamStr(0)) + TestFileOOXML,13); end; +{ Excel2003/XML Tests } +procedure TSpreadReadStringTests.TestReadXMLString0; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,0); +end; + +procedure TSpreadReadStringTests.TestReadXMLString1; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,1); +end; + +procedure TSpreadReadStringTests.TestReadXMLString2; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,2); +end; + +procedure TSpreadReadStringTests.TestReadXMLString3; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,3); +end; + +procedure TSpreadReadStringTests.TestReadXMLString4; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,4); +end; + +procedure TSpreadReadStringTests.TestReadXMLString5; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,5); +end; + +procedure TSpreadReadStringTests.TestReadXMLString6; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,6); +end; + +procedure TSpreadReadStringTests.TestReadXMLString7; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,7); +end; + +procedure TSpreadReadStringTests.TestReadXMLString8; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,8); +end; + +procedure TSpreadReadStringTests.TestReadXMLString9; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,9); +end; + +procedure TSpreadReadStringTests.TestReadXMLString10; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,10); +end; + +procedure TSpreadReadStringTests.TestReadXMLString11; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,11); +end; + +procedure TSpreadReadStringTests.TestReadXMLString12; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,12); +end; + +procedure TSpreadReadStringTests.TestReadXMLString13; +begin + TestReadString(ExtractFilePath(ParamStr(0)) + TestFileXML,13); +end; + initialization // Register so these tests are included in a full run diff --git a/components/fpspreadsheet/tests/testsutility.pas b/components/fpspreadsheet/tests/testsutility.pas index 200a5028b..e810f2e8e 100644 --- a/components/fpspreadsheet/tests/testsutility.pas +++ b/components/fpspreadsheet/tests/testsutility.pas @@ -13,14 +13,21 @@ uses const TestFileBIFF8_1904='testbiff8_1904.xls'; //with 1904 datemode date system TestFileBIFF8_1899='testbiff8_1899.xls'; //with 1899/1900 datemode date system - TestFileBIFF8=TestFileBIFF8_1899; + TestFileBIFF8 = TestFileBIFF8_1899; + TestFileODF_1904='testodf_1904.ods'; //OpenDocument/LibreOffice with 1904 datemode date system TestFileODF_1899='testodf_1899.ods'; //OpenDocument/LibreOffice with 1899/1900 datemode date system - TestFileODF=TestFileODF_1899; + TestFileODF = TestFileODF_1899; + TestFileOOXML_1904='testooxml_1904.xlsx'; //Excel xlsx with 1904 datemode date system TestFileOOXML_1899='testooxml_1899.xlsx'; //Excel xlsx with 1899/1900 datemode date system - TestFileOOXML=TestFileOOXML_1899; - TestFileManual='testmanual.xls'; //file name for manual checking using external spreadsheet program (Excel/LibreOffice..) + TestFileOOXML = TestFileOOXML_1899; + + TestFileXML_1904='testxml_1904.xml'; //Excel 2003/XML file with 1904 datemode date system + TestFileXML_1899='testxml_1899.xml'; //Excel 2003/XML file with 1899/1900 datemode date system + TestFileXML = TestFileXML_1899; + + TestFileManual = 'testmanual.xls'; //file name for manual checking using external spreadsheet program (Excel/LibreOffice..) DatesSheet = 'Dates'; //worksheet name FormulasSheet = 'Formulas'; //worksheet name ManualSheet = 'ManualTests'; //worksheet names diff --git a/components/fpspreadsheet/tests/testxml_1899.xml b/components/fpspreadsheet/tests/testxml_1899.xml new file mode 100644 index 000000000..135ba42b8 --- /dev/null +++ b/components/fpspreadsheet/tests/testxml_1899.xml @@ -0,0 +1,591 @@ + + + + + Pamler + Werner + 2014-08-05T08:05:53Z + 2015-04-30T11:25:25Z + 16.00 + + + + + + 8190 + 16380 + 32767 + 32767 + 500 + 2 + False + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + -59000000 + minus 59 million + Please use the A column for cells that will be read by fpspreadsheet + + + -988 + Do not modify or delete cells; it will mess up the tests + + + -124.23432 + You can use other cells for comments, intermediate calculations, etc + + + -81.902850873027404 + + + -15 + + + -2.934E-3 + minus small fraction + + + 0 + minus zero + + + 0 + zero + + + 5.0000000000000001E-9 + small fraction + + + 0.98239399999999999 + almost 1 + + + 3.14159265358979 + some parts of pi + + + 59000000 + 59 million + + + 59000000.100000001 + same + a tenth + + + 0.35360000000000003 + 0.3536 formatted as percent with no decimal + + + 0.35360000000000003 + 0.3536 formatted as percent with two decimals + + + 59000000.123400003 + 59 million + 0.1234, formatted with thousand separator, no decimals + + + 59000000.123400003 + 59 million + 0.1234, formatted with thousand separator, two decimals + + + -59000000.123400003 + minus 59 million + 0.1234, formatted as "exp" with 2 decimals + + + 59000000.123400003 + 59 million + 0.1234, formatted as EUROs, € at end, two decimals + + + 59000000.123400003 + 59 million + 0.1234, formatted as DOLLARs, $ at end, two decimals + + + -59000000.123400003 + minus 59 million + 0.1234, formatted as EUROs, € at end, two decimals + + + -59000000.123400003 + minus 59 million + 0.1234, formatted as DOLLARs, $ at end, two decimals + + + -59000000.123400003 + minus 59 million + 0.1234, formatted as DOLLARs, $ at end, negative red, two decimals + +
+ + +
+