diff --git a/src/FsSpreadsheet.ExcelIO/Cell.fs b/src/FsSpreadsheet.ExcelIO/Cell.fs index 6840e9ff..06870a6c 100644 --- a/src/FsSpreadsheet.ExcelIO/Cell.fs +++ b/src/FsSpreadsheet.ExcelIO/Cell.fs @@ -161,9 +161,12 @@ module Cell = |> SharedStringTable.count |> string |> fun v -> {|DataType = Some CellValues.SharedString; Value = v; Format = None|} - | DataType.String -> {|DataType = Some CellValues.String; Value = value; Format = None|} - | DataType.Boolean -> {|DataType = Some CellValues.Boolean; Value = value; Format = None|} - | DataType.Number -> {|DataType = Some CellValues.Number; Value = value; Format = None|} + | DataType.String -> + {|DataType = Some CellValues.String; Value = value; Format = None|} + | DataType.Boolean -> + {|DataType = Some CellValues.Boolean; Value = System.Boolean.Parse value |> FsCellAux.boolConverter; Format = None|} + | DataType.Number -> + {|DataType = Some CellValues.Number; Value = value; Format = None|} | DataType.Date -> //let cellFormat = CellFormat(NumberFormatId = UInt32Value 19u, ApplyNumberFormat = BooleanValue true) let value = System.DateTime.Parse(value).ToOADate() |> string diff --git a/src/FsSpreadsheet.ExcelIO/FsExtensions.fs b/src/FsSpreadsheet.ExcelIO/FsExtensions.fs index 1725d6d1..70e717b6 100644 --- a/src/FsSpreadsheet.ExcelIO/FsExtensions.fs +++ b/src/FsSpreadsheet.ExcelIO/FsExtensions.fs @@ -82,13 +82,10 @@ module FsExtensions = | _ -> () | Number -> try - cellValue <- int cellValueString + cellValue <- float cellValueString with | _ -> - try - cellValue <- float cellValueString - with - | _ -> () + () | Empty | String -> () //let dt, v = DataType.InferCellValue v FsCell.createWithDataType dt (int row) (int col) (cellValue) @@ -168,7 +165,7 @@ module FsExtensions = let cells = cells |> List.map (fun cell -> - Cell.fromValueWithDataType doc (uint32 cell.ColumnNumber) (uint32 cell.RowNumber) (cell.ValueAsString()) (cell.DataType) + FsCell.toXlsxCell doc cell ) let row = Row.create (uint32 row.Index) (Row.Spans.fromBoundaries min max) cells SheetData.appendRow row sd |> ignore diff --git a/src/FsSpreadsheet.Exceljs/Cell.fs b/src/FsSpreadsheet.Exceljs/Cell.fs new file mode 100644 index 00000000..6fec03d2 --- /dev/null +++ b/src/FsSpreadsheet.Exceljs/Cell.fs @@ -0,0 +1,88 @@ +namespace FsSpreadsheet.Exceljs + + +module JsCell = + + open Fable.Core + open Fable.Core.JsInterop + open FsSpreadsheet + open Fable.ExcelJs + + [] + let private log (obj:obj) = jsNative + + let writeFromFsCell (fsCell: FsCell) = + match fsCell.DataType with + | Boolean -> + fsCell.ValueAsBool() |> box |> Some + | Number -> + fsCell.ValueAsFloat() |> box |> Some + | Date -> + /// Here it will actually show the correct DateTime. But when writing, exceljs will apply local offset. + let dt = fsCell.ValueAsDateTime() |> System.DateTimeOffset + /// Therefore we add offset and it should work. + let dt = dt + dt.Offset |> box |> Some + dt + | String -> + fsCell.Value |> Some + | anyElse -> + let msg = sprintf "ValueType '%A' is not fully implemented in FsSpreadsheet and is handled as string input." anyElse + #if FABLE_COMPILER_JAVASCRIPT + log msg + #else + printfn "%s" msg + #endif + fsCell.Value |> box |> Some + + /// + /// `worksheetName`, `rowIndex` and `columnIndex` are only used for debugging. + /// + /// + /// + /// + /// + let readToFsCell worksheetName rowIndex columnIndex (jsCell: Cell) = + let t = enum(jsCell.``type``) + let fsadress = FsAddress(jsCell.address) + let createFscell = fun dt v -> FsCell(v,dt,address = fsadress) + let vTemp = string jsCell.value.Value + let fscell = + match t with + | ValueType.Boolean -> + let b = System.Boolean.Parse vTemp + createFscell DataType.Boolean b + | ValueType.Number -> float vTemp |> createFscell DataType.Number + | ValueType.Date -> + let dt = System.DateTime.Parse(vTemp).ToUniversalTime() + /// Without this step universal time get changed to local time? Exceljs tests will hit this. + /// + /// Expected item (from test object): C2 : Sat Oct 14 2023 00:00:00 GMT+0200 (Mitteleuropäische Sommerzeit) | Date + /// + /// Actual item (created here): C2 : Sat Oct 14 2023 02:00:00 GMT+0200 (Mitteleuropäische Sommerzeit) | Date + /// + /// But logging hour minute showed that the values were given correctly and needed to be reinitialized. + let dt = System.DateTime(dt.Year,dt.Month,dt.Day,dt.Hour,dt.Minute, dt.Second) + dt |> createFscell DataType.Date + | ValueType.String -> vTemp |> createFscell DataType.String + | ValueType.Formula -> + match jsCell.formula with + | "TRUE()" -> + let b = true + createFscell DataType.Boolean b + | "FALSE()" -> + let b = false + createFscell DataType.Boolean b + | anyElse -> + let msg = sprintf "ValueType 'Format' (%s) is not fully implemented in FsSpreadsheet and is handled as string input. In %s: (%i,%i)" anyElse worksheetName rowIndex columnIndex + log msg + anyElse |> createFscell DataType.String + | ValueType.Hyperlink -> + //log (c.value.Value?text) + jsCell.value.Value?hyperlink |> createFscell DataType.String + | anyElse -> + let msg = sprintf "ValueType `%A` (%s) is not fully implemented in FsSpreadsheet and is handled as string input. In %s: (%i,%i)" anyElse vTemp worksheetName rowIndex columnIndex + log msg + vTemp |> createFscell DataType.String + fscell + + diff --git a/src/FsSpreadsheet.Exceljs/FsSpreadsheet.Exceljs.fsproj b/src/FsSpreadsheet.Exceljs/FsSpreadsheet.Exceljs.fsproj index 6fd50397..a568732c 100644 --- a/src/FsSpreadsheet.Exceljs/FsSpreadsheet.Exceljs.fsproj +++ b/src/FsSpreadsheet.Exceljs/FsSpreadsheet.Exceljs.fsproj @@ -1,52 +1,51 @@ - - - - Kevin Frey, Heinrich Lukas Weil, Oliver Maus, Kevin Schneider, Timo Mühlhaus - Excel IO Extensions for the FsSpreadsheet Datamodel in js environments using exceljs. - Spreadsheet creation and manipulation in FSharp - MIT - logo.png - F# FSharp spreadsheet Excel xlsx datascience fable fable-library fable-javascript - https://github.com/CSBiology/FsSpreadsheet - git - - - - net6.0 - true - - - + + + + Kevin Frey, Heinrich Lukas Weil, Oliver Maus, Kevin Schneider, Timo Mühlhaus + Excel IO Extensions for the FsSpreadsheet Datamodel in js environments using exceljs. + Spreadsheet creation and manipulation in FSharp + MIT + logo.png + F# FSharp spreadsheet Excel xlsx datascience fable fable-library fable-javascript + https://github.com/CSBiology/FsSpreadsheet + git + + + + net6.0 + true + + + \ true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/FsSpreadsheet.Exceljs/Table.fs b/src/FsSpreadsheet.Exceljs/Table.fs index 3554fa6e..58359f08 100644 --- a/src/FsSpreadsheet.Exceljs/Table.fs +++ b/src/FsSpreadsheet.Exceljs/Table.fs @@ -10,7 +10,7 @@ module JsTable = [] let private log (obj:obj) = jsNative - let fromFsTable (fscellcollection: FsCellsCollection) (fsTable: FsTable) : Table = + let writeFromFsTable (fscellcollection: FsCellsCollection) (fsTable: FsTable) : Table = let fsColumns = fsTable.GetColumns fscellcollection let columns = if fsTable.ShowHeaderRow then @@ -24,36 +24,25 @@ module JsTable = [| for col in fsColumns do let cells = if fsTable.ShowHeaderRow then col.Cells |> Seq.tail else col.Cells - yield! cells |> Seq.mapi (fun i c -> - let rowValue = - match c.DataType with - | Boolean -> c.ValueAsBool() |> box - | Number -> c.ValueAsFloat() |> box - | Date -> c.ValueAsDateTime() |> box - | String -> c.Value |> box - | anyElse -> - let msg = sprintf "ValueType '%A' is not fully implemented in FsSpreadsheet and is handled as string input." anyElse - #if FABLE_COMPILER_JAVASCRIPT - log msg - #else - printfn "%s" msg - #endif - c.Value |> box - i+1, rowValue + yield! cells |> Seq.map (fun c -> + let rowValue = JsCell.writeFromFsCell c |> Option.get + c.Address.RowNumber, (c.Address.ColumnNumber, rowValue) ) |] |> Array.groupBy fst |> Array.sortBy fst |> Array.map (fun (_,arr) -> - arr |> Array.map snd + let m = arr |> Array.map snd |> Map + let row = [|fsTable.RangeAddress.FirstAddress.ColumnNumber .. fsTable.RangeAddress.FirstAddress.ColumnNumber + (columns.Length-1)|] + let row = row |> Array.map (fun i -> m.TryFind i |> box) + row ) let defaultStyle = {| - theme = "TableStyleMedium7" showRowStripes = true |} Table(fsTable.Name,fsTable.RangeAddress.Range,columns,rows,fsTable.Name,headerRow = fsTable.ShowHeaderRow, style = defaultStyle) - let fromJsTable(table:ITableRef) = + let readToFsTable(table:ITableRef) = let table = table.table.Value let tableRef = table.tableRef |> FsRangeAddress let tableName = if isNull table.displayName then table.name else table.displayName diff --git a/src/FsSpreadsheet.Exceljs/Workbook.fs b/src/FsSpreadsheet.Exceljs/Workbook.fs index 6c569e03..a53c3d2e 100644 --- a/src/FsSpreadsheet.Exceljs/Workbook.fs +++ b/src/FsSpreadsheet.Exceljs/Workbook.fs @@ -13,15 +13,15 @@ module JsWorkbook = [] let private log (obj:obj) = jsNative - let toFsWorkbook (jswb: Workbook) = - let fswb = new FsWorkbook() - for jsws in jswb.worksheets do - JsWorksheet.addJsWorksheet fswb jsws - fswb - - let fromFsWorkbook (fswb: FsWorkbook) = + let writeFromFsWorkbook (fswb: FsWorkbook) = let jswb = ExcelJs.Excel.Workbook() jswb?_themes <- Aux.theme1 for fsws in fswb.GetWorksheets() do - JsWorksheet.addFsWorksheet jswb fsws + JsWorksheet.writeFromFsWorksheet jswb fsws jswb + + let readToFsWorkbook (jswb: Workbook) = + let fswb = new FsWorkbook() + for jsws in jswb.worksheets do + JsWorksheet.readToFsWorksheet fswb jsws + fswb diff --git a/src/FsSpreadsheet.Exceljs/Worksheet.fs b/src/FsSpreadsheet.Exceljs/Worksheet.fs index ed84e4c2..ecbcfb09 100644 --- a/src/FsSpreadsheet.Exceljs/Worksheet.fs +++ b/src/FsSpreadsheet.Exceljs/Worksheet.fs @@ -10,92 +10,32 @@ module JsWorksheet = open FsSpreadsheet open Fable.ExcelJs - open Fable.Core.JsInterop - let boolConverter (bool:bool) = - match bool with | true -> "1" | false -> "0" - - let addFsWorksheet (wb: Workbook) (fsws:FsWorksheet) : unit = + let writeFromFsWorksheet (wb: Workbook) (fsws:FsWorksheet) : unit = fsws.RescanRows() let rows = fsws.Rows |> Seq.map (fun x -> x.Cells) let ws = wb.addWorksheet(fsws.Name) // due to the design of fsspreadsheet this might overwrite some of the stuff from tables, // but as it should be the same, this is only a performance sink. for row in rows do - for cell in row do - let c = ws.getCell(cell.Address.Address) - match cell.DataType with - | Boolean -> - c.value <- cell.ValueAsBool() |> boolConverter |> box |> Some - | Number -> - c.value <- cell.ValueAsFloat() |> box |> Some - | Date -> - c.value <- cell.ValueAsDateTime() |> box |> Some - | String -> - c.value <- cell.Value |> box |> Some - | anyElse -> - let msg = sprintf "ValueType '%A' is not fully implemented in FsSpreadsheet and is handled as string input." anyElse - #if FABLE_COMPILER_JAVASCRIPT - log msg - #else - printfn "%s" msg - #endif - c.value <- cell.Value |> box |> Some - let tables = fsws.Tables |> Seq.map (fun table -> JsTable.fromFsTable fsws.CellCollection table) + for fsCell in row do + let jsCell = ws.getCell(fsCell.Address.Address) + jsCell.value <- JsCell.writeFromFsCell fsCell + let tables = fsws.Tables |> Seq.map (fun table -> JsTable.writeFromFsTable fsws.CellCollection table) for table in tables do ws.addTable(table) |> ignore - let addJsWorksheet (wb: FsWorkbook) (jsws: Worksheet) : unit = + let readToFsWorksheet (wb: FsWorkbook) (jsws: Worksheet) : unit = let fsws = FsWorksheet(jsws.name) jsws.eachRow(fun (row, rowIndex) -> row.eachCell(fun (c, columnIndex) -> if c.value.IsSome then - let t = enum(c.``type``) - let fsadress = FsAddress(c.address) - let createFscell = fun dt v -> FsCell(v,dt,address = fsadress) - let vTemp = string c.value.Value - let fscell = - match t with - | ValueType.Boolean -> - let b = System.Boolean.Parse vTemp |> boolConverter - createFscell DataType.Boolean b - | ValueType.Number -> float vTemp |> createFscell DataType.Number - | ValueType.Date -> - let dt = System.DateTime.Parse(vTemp).ToUniversalTime() - /// Without this step universal time get changed to local time? Exceljs tests will hit this. - /// - /// Expected item (from test object): C2 : Sat Oct 14 2023 00:00:00 GMT+0200 (Mitteleuropäische Sommerzeit) | Date - /// - /// Actual item (created here): C2 : Sat Oct 14 2023 02:00:00 GMT+0200 (Mitteleuropäische Sommerzeit) | Date - /// - /// But logging hour minute showed that the values were given correctly and needed to be reinitialized. - let dt = System.DateTime(dt.Year,dt.Month,dt.Day,dt.Hour,dt.Minute, dt.Second) - dt |> createFscell DataType.Date - | ValueType.String -> vTemp |> createFscell DataType.String - | ValueType.Formula -> - match c.formula with - | "TRUE()" -> - let b = true |> boolConverter - createFscell DataType.Boolean b - | "FALSE()" -> - let b = false |> boolConverter - createFscell DataType.Boolean b - | anyElse -> - let msg = sprintf "ValueType 'Format' (%s) is not fully implemented in FsSpreadsheet and is handled as string input. In %s: (%i,%i)" anyElse jsws.name rowIndex columnIndex - log msg - anyElse |> createFscell DataType.String - | ValueType.Hyperlink -> - //log (c.value.Value?text) - c.value.Value?hyperlink |> createFscell DataType.String - | anyElse -> - let msg = sprintf "ValueType `%A` (%s) is not fully implemented in FsSpreadsheet and is handled as string input. In %s: (%i,%i)" anyElse vTemp jsws.name rowIndex columnIndex - log msg - vTemp |> createFscell DataType.String - fsws.AddCell(fscell) |> ignore + let fsCell = JsCell.readToFsCell jsws.name rowIndex columnIndex c + fsws.AddCell(fsCell) |> ignore ) ) for jstableref in jsws.getTables() do - let table = JsTable.fromJsTable jstableref + let table = JsTable.readToFsTable jstableref fsws.AddTable table |> ignore fsws.RescanRows() wb.AddWorksheet(fsws) \ No newline at end of file diff --git a/src/FsSpreadsheet.Exceljs/Xlsx.fs b/src/FsSpreadsheet.Exceljs/Xlsx.fs index 850733de..aa5af836 100644 --- a/src/FsSpreadsheet.Exceljs/Xlsx.fs +++ b/src/FsSpreadsheet.Exceljs/Xlsx.fs @@ -14,7 +14,7 @@ type Xlsx = promise { let wb = ExcelJs.Excel.Workbook() do! wb.xlsx.readFile(path) - let fswb = JsWorkbook.toFsWorkbook wb + let fswb = JsWorkbook.readToFsWorkbook wb return fswb } @@ -22,7 +22,7 @@ type Xlsx = promise { let wb = ExcelJs.Excel.Workbook() do! wb.xlsx.read stream - return JsWorkbook.toFsWorkbook wb + return JsWorkbook.readToFsWorkbook wb } static member fromBytes (bytes: byte []) : Promise = @@ -30,20 +30,20 @@ type Xlsx = let wb = ExcelJs.Excel.Workbook() let uint8 = Fable.Core.JS.Constructors.Uint8Array.Create bytes do! wb.xlsx.load(uint8.buffer) - return JsWorkbook.toFsWorkbook wb + return JsWorkbook.readToFsWorkbook wb } static member toFile (path: string) (wb:FsWorkbook) : Promise = - let jswb = JsWorkbook.fromFsWorkbook wb + let jswb = JsWorkbook.writeFromFsWorkbook wb jswb.xlsx.writeFile(path) static member toStream (stream: System.IO.Stream) (wb:FsWorkbook) : Promise = - let jswb = JsWorkbook.fromFsWorkbook wb + let jswb = JsWorkbook.writeFromFsWorkbook wb jswb.xlsx.write(stream) static member toBytes (wb:FsWorkbook) : Promise = promise { - let jswb = JsWorkbook.fromFsWorkbook wb + let jswb = JsWorkbook.writeFromFsWorkbook wb let buffer = jswb.xlsx.writeBuffer() return !!buffer } diff --git a/src/FsSpreadsheet/Cells/FsCell.fs b/src/FsSpreadsheet/Cells/FsCell.fs index df8f0f05..d0a5714b 100644 --- a/src/FsSpreadsheet/Cells/FsCell.fs +++ b/src/FsSpreadsheet/Cells/FsCell.fs @@ -54,6 +54,11 @@ type DataType = /// Creates an FsCell of `DataType` dataType, with value of type `string`, and `FsAddress` address. /// +module FsCellAux = + + let boolConverter (bool:bool) = + match bool with | true -> "1" | false -> "0" + [] type FsCell (value : obj, ?dataType : DataType, ?address : FsAddress) = @@ -233,8 +238,16 @@ type FsCell (value : obj, ?dataType : DataType, ?address : FsAddress) = /// /// Gets the value as string /// - member self.ValueAsString() = - self.Value.ToString() + member self.ValueAsString() : string = + let v = self.Value + match self.DataType with + | DataType.String | DataType.Date | DataType.Boolean | DataType.Empty -> + v.ToString() + | Number -> + // Example: 4.123: + // - (4.123)ToString() will parse floats in germany to "4,123" which is not allowed by Excel. + // - string(4.123) will parse floats in germany to "4.123" which is allowed by Excel. + string v /// /// Gets the value as string @@ -417,9 +430,6 @@ type FsCell (value : obj, ?dataType : DataType, ?address : FsAddress) = this.RowNumber = other.RowNumber |] |> Seq.forall (fun x -> x=true) - if not r then - printfn "[VALUE] %A, %A" this.Value other.Value - printfn "[DATATYPE] %O, %O" this.DataType other.DataType r diff --git a/tests/FsSpreadsheet.ExcelIO.Tests/DefaultIO.Tests.fs b/tests/FsSpreadsheet.ExcelIO.Tests/DefaultIO.Tests.fs index 989d1f21..65a7bbec 100644 --- a/tests/FsSpreadsheet.ExcelIO.Tests/DefaultIO.Tests.fs +++ b/tests/FsSpreadsheet.ExcelIO.Tests/DefaultIO.Tests.fs @@ -20,7 +20,7 @@ let tests_Read = testList "Read" [ testCase "Excel" <| fun _ -> let wb = readFromTestFile DefaultTestObject.TestFiles.Excel Expect.isDefaultTestObject wb - testCase "Libre" <| fun _ -> + ptestCase "Libre" <| fun _ -> let wb = readFromTestFile DefaultTestObject.TestFiles.Libre Expect.isDefaultTestObject wb testCase "FableExceljs" <| fun _ -> @@ -31,6 +31,7 @@ let tests_Read = testList "Read" [ Expect.isDefaultTestObject wb testCase "FsSpreadsheet" <| fun _ -> let wb = readFromTestFile DefaultTestObject.TestFiles.FsSpreadsheetNET + wb.GetWorksheets().[0].GetCellAt(5,1) |> fun x -> (x.Value, x.DataType) |> printfn "%A" Expect.isDefaultTestObject wb ] diff --git a/tests/FsSpreadsheet.ExcelIO.Tests/OpenXml/FsExtensions.fs b/tests/FsSpreadsheet.ExcelIO.Tests/OpenXml/FsExtensions.fs index 82881b6a..5ffc6d5c 100644 --- a/tests/FsSpreadsheet.ExcelIO.Tests/OpenXml/FsExtensions.fs +++ b/tests/FsSpreadsheet.ExcelIO.Tests/OpenXml/FsExtensions.fs @@ -120,7 +120,7 @@ let fsExtensionTests = Expect.equal d DataType.String "DataType is not DataType.String" testCase "is equal to dummyFsWorkbook in sheet2, cellC7 value" <| fun _ -> let v = (FsWorksheet.getCellAt 7 3 fsWorksheet2FromStream).Value - Expect.equal v 7 "value is not equal" + Expect.equal v 7. "value is not equal" testCase "is equal to dummyFsWorkbook in sheet2, cellC7 address" <| fun _ -> let a = (FsWorksheet.getCellAt 7 3 fsWorksheet2FromStream).Address.Address Expect.equal a "C7" "address is not equal" diff --git a/tests/FsSpreadsheet.ExcelIO.Tests/TestObjects.fs b/tests/FsSpreadsheet.ExcelIO.Tests/TestObjects.fs index 0be08089..41c08507 100644 --- a/tests/FsSpreadsheet.ExcelIO.Tests/TestObjects.fs +++ b/tests/FsSpreadsheet.ExcelIO.Tests/TestObjects.fs @@ -26,15 +26,15 @@ let sheet1() = let sheet2() = let ws = new FsWorksheet(sheet2Name) [ - FsCell.createWithDataType DataType.Number 1 1 1 - FsCell.createWithDataType DataType.Number 1 2 2 - FsCell.createWithDataType DataType.Number 1 3 3 - FsCell.createWithDataType DataType.Number 1 4 4 + FsCell.createWithDataType DataType.Number 1 1 1. + FsCell.createWithDataType DataType.Number 1 2 2. + FsCell.createWithDataType DataType.Number 1 3 3. + FsCell.createWithDataType DataType.Number 1 4 4. - FsCell.createWithDataType DataType.Number 2 1 5 - FsCell.createWithDataType DataType.Number 2 2 6 - FsCell.createWithDataType DataType.Number 2 3 7 - FsCell.createWithDataType DataType.Number 2 4 8 + FsCell.createWithDataType DataType.Number 2 1 5. + FsCell.createWithDataType DataType.Number 2 2 6. + FsCell.createWithDataType DataType.Number 2 3 7. + FsCell.createWithDataType DataType.Number 2 4 8. ] |> List.iter (fun c -> ws.Row(c.RowNumber).[c.ColumnNumber].SetValueAs c.Value) ws \ No newline at end of file diff --git a/tests/FsSpreadsheet.Exceljs.Tests/DefaultIO.Tests.fs b/tests/FsSpreadsheet.Exceljs.Tests/DefaultIO.Tests.fs index 3b1604c7..660669c2 100644 --- a/tests/FsSpreadsheet.Exceljs.Tests/DefaultIO.Tests.fs +++ b/tests/FsSpreadsheet.Exceljs.Tests/DefaultIO.Tests.fs @@ -13,7 +13,7 @@ let tests_Read = testList "Read" [ let! wb = readFromTestFile DefaultTestObject.TestFiles.Excel |> Async.AwaitPromise Expect.isDefaultTestObject wb } - testCaseAsync "Libre" <| async { + ptestCaseAsync "Libre" <| async { let! wb = readFromTestFile DefaultTestObject.TestFiles.Libre |> Async.AwaitPromise Expect.isDefaultTestObject wb } @@ -25,8 +25,12 @@ let tests_Read = testList "Read" [ let! wb = readFromTestFile DefaultTestObject.TestFiles.ClosedXML |> Async.AwaitPromise Expect.isDefaultTestObject wb } - testCaseAsync "FsSpreadsheet" <| async { + testCaseAsync "FsSpreadsheetNET" <| async { let! wb = readFromTestFile DefaultTestObject.TestFiles.FsSpreadsheetNET |> Async.AwaitPromise Expect.isDefaultTestObject wb } + testCaseAsync "FsSpreadsheetJS" <| async { + let! wb = readFromTestFile DefaultTestObject.TestFiles.FsSpreadsheetJS |> Async.AwaitPromise + Expect.isDefaultTestObject wb + } ] \ No newline at end of file diff --git a/tests/FsSpreadsheet.Exceljs.Tests/FsSpreadsheet.Exceljs.Tests.csproj b/tests/FsSpreadsheet.Exceljs.Tests/FsSpreadsheet.Exceljs.Tests.csproj new file mode 100644 index 00000000..7851ed66 --- /dev/null +++ b/tests/FsSpreadsheet.Exceljs.Tests/FsSpreadsheet.Exceljs.Tests.csproj @@ -0,0 +1,22 @@ + + + + Exe + net6.0 + false + + + + + + + + + + + + + + + + diff --git a/tests/FsSpreadsheet.Exceljs.Tests/Workbook.Tests.fs b/tests/FsSpreadsheet.Exceljs.Tests/Workbook.Tests.fs index 46ea3795..7ab1e3c6 100644 --- a/tests/FsSpreadsheet.Exceljs.Tests/Workbook.Tests.fs +++ b/tests/FsSpreadsheet.Exceljs.Tests/Workbook.Tests.fs @@ -5,6 +5,8 @@ open Fable.ExcelJs open FsSpreadsheet.Exceljs open FsSpreadsheet +open Fable.Core + module Helper = open Fable.Core @@ -18,7 +20,7 @@ let private tests_toFsWorkbook = testList "toFsWorkbook" [ testCase "empty" <| fun _ -> let jswb = ExcelJs.Excel.Workbook() Expect.passWithMsg "Create jswb" - let fswb = JsWorkbook.toFsWorkbook jswb + let fswb = JsWorkbook.readToFsWorkbook jswb Expect.passWithMsg "Convert to fswb" let fswsList = fswb.GetWorksheets() let jswsList = jswb.worksheets @@ -27,7 +29,7 @@ let private tests_toFsWorkbook = testList "toFsWorkbook" [ let jswb = ExcelJs.Excel.Workbook() let _ = jswb.addWorksheet("My Awesome Worksheet") Expect.passWithMsg "Create jswb" - let fswb = JsWorkbook.toFsWorkbook jswb + let fswb = JsWorkbook.readToFsWorkbook jswb Expect.passWithMsg "Convert to fswb" let jswsList = jswb.worksheets let fswsList = fswb.GetWorksheets() @@ -39,7 +41,7 @@ let private tests_toFsWorkbook = testList "toFsWorkbook" [ let _ = jswb.addWorksheet("My Best Worksheet") let _ = jswb.addWorksheet("My Nice Worksheet") Expect.passWithMsg "Create jswb" - let fswb = JsWorkbook.toFsWorkbook jswb + let fswb = JsWorkbook.readToFsWorkbook jswb Expect.passWithMsg "Convert to fswb" let jswsList = jswb.worksheets let fswsList = fswb.GetWorksheets() @@ -57,7 +59,7 @@ let private tests_toFsWorkbook = testList "toFsWorkbook" [ let table = Table("My_Awesome_Table", "B1", tableColumns, [||]) let _ = jsws.addTable(table) Expect.passWithMsg "Create jswb" - let fswb = JsWorkbook.toFsWorkbook jswb + let fswb = JsWorkbook.readToFsWorkbook jswb Expect.passWithMsg "Convert to fswb" let fsTables_a = fswb.GetWorksheets().[0].Tables let fsTables_b = fswb.GetTables() @@ -87,7 +89,7 @@ let private tests_toFsWorkbook = testList "toFsWorkbook" [ let table = Table("My_Awesome_Table", "B1", tableColumns, rows) let _ = jsws.addTable(table) Expect.passWithMsg "Create jswb" - let fswb = JsWorkbook.toFsWorkbook jswb + let fswb = JsWorkbook.readToFsWorkbook jswb Expect.passWithMsg "Convert to fswb" let fsTables = fswb.GetTables() Expect.hasLength (jsws.getTables()) 1 "js table count" @@ -107,7 +109,7 @@ let private tests_toFsWorkbook = testList "toFsWorkbook" [ let table = Table("My_Awesome_Table", "B1", tableColumns, rows) let _ = jsws.addTable(table) Expect.passWithMsg "Create jswb" - let fswb = JsWorkbook.toFsWorkbook jswb + let fswb = JsWorkbook.readToFsWorkbook jswb let getCellValue (address: string) = let ws = fswb.GetWorksheetAt 1 let range = FsAddress(address) @@ -132,7 +134,7 @@ let tests_toJsWorkbook = testList "toJsWorkbook" [ testCase "empty" <| fun _ -> let fswb = new FsWorkbook() Expect.passWithMsg "Create fswb" - let jswb = JsWorkbook.fromFsWorkbook fswb + let jswb = JsWorkbook.writeFromFsWorkbook fswb Expect.passWithMsg "Convert to jswb" let fswsList = fswb.GetWorksheets() let jswsList = jswb.worksheets @@ -141,7 +143,7 @@ let tests_toJsWorkbook = testList "toJsWorkbook" [ let fswb = new FsWorkbook() let _ = fswb.InitWorksheet("My Awesome Worksheet") Expect.passWithMsg "Create fswb" - let jswb = JsWorkbook.fromFsWorkbook fswb + let jswb = JsWorkbook.writeFromFsWorkbook fswb Expect.passWithMsg "Convert to jswb" let fswsList = fswb.GetWorksheets() let jswsList = jswb.worksheets @@ -154,7 +156,7 @@ let tests_toJsWorkbook = testList "toJsWorkbook" [ let _ = fswb.InitWorksheet("My cool Worksheet") let _ = fswb.InitWorksheet("My wow Worksheet") Expect.passWithMsg "Create fswb" - let jswb = JsWorkbook.fromFsWorkbook fswb + let jswb = JsWorkbook.writeFromFsWorkbook fswb Expect.passWithMsg "Convert to jswb" let fswsList = fswb.GetWorksheets() let jswsList = jswb.worksheets @@ -171,7 +173,7 @@ let tests_toJsWorkbook = testList "toJsWorkbook" [ let t = FsTable("My_New_Table", FsRangeAddress("B1:C1")) let _ = fsws.AddTable(t) Expect.passWithMsg "Create jswb" - let jswb = JsWorkbook.fromFsWorkbook fswb + let jswb = JsWorkbook.writeFromFsWorkbook fswb Expect.passWithMsg "Convert to fswb" let jsws = jswb.worksheets.[0] Expect.equal jsws.name "My Awesome Worksheet" "ws name" @@ -198,7 +200,7 @@ let tests_toJsWorkbook = testList "toJsWorkbook" [ let t = FsTable("My_New_Table", FsRangeAddress("B1:D3")) let _ = fsws.AddTable(t) Expect.passWithMsg "Create jswb" - let jswb = JsWorkbook.fromFsWorkbook fswb + let jswb = JsWorkbook.writeFromFsWorkbook fswb Expect.passWithMsg "Convert to fswb" let jsws = jswb.worksheets.[0] Expect.equal jsws.name "My Awesome Worksheet" "ws name" @@ -227,7 +229,7 @@ let tests_toJsWorkbook = testList "toJsWorkbook" [ let _ = fsws.AddTable(t) fsws.RescanRows() Expect.passWithMsg "Create jswb" - let jswb = JsWorkbook.fromFsWorkbook fswb + let jswb = JsWorkbook.writeFromFsWorkbook fswb let jstable = jswb.worksheets.[0].getTables().[0].table.Value let row0 = jstable.rows.[0] let row1 = jstable.rows.[1] @@ -279,7 +281,7 @@ open Fable.Core let tests_xlsx = testList "xlsx" [ testList "read" [ - ftestCaseAsync "isa.assay.xlsx" <| async { + testCaseAsync "isa.assay.xlsx" <| async { let! fswb = Xlsx.fromXlsxFile("./tests/JS/TestFiles/isa.assay.xlsx") |> Async.AwaitPromise Expect.equal (fswb.GetWorksheets().Count) 5 "Count" } diff --git a/tests/JS/Exceljs.js b/tests/JS/Exceljs.js index 49ec9388..3463ef35 100644 --- a/tests/JS/Exceljs.js +++ b/tests/JS/Exceljs.js @@ -3,7 +3,7 @@ import { Xlsx } from './FsSpreadsheet.Exceljs/Xlsx.js'; import { FsWorkbook } from "./FsSpreadsheet.Exceljs/FsSpreadsheet/FsWorkbook.js"; import { FsRangeAddress_$ctor_Z721C83C5, FsRangeAddress__get_Range } from "./FsSpreadsheet.Exceljs/FsSpreadsheet/Ranges/FsRangeAddress.js"; import { FsTable } from "./FsSpreadsheet.Exceljs/FsSpreadsheet/Tables/FsTable.js"; -import { fromFsWorkbook, toFsWorkbook } from "./FsSpreadsheet.Exceljs/Workbook.js"; +import { writeFromFsWorkbook, readToFsWorkbook } from "./FsSpreadsheet.Exceljs/Workbook.js"; describe('FsSpreadsheet.Exceljs', function () { describe('read', function () { diff --git a/tests/TestUtils/DefaultTestObjects.fs b/tests/TestUtils/DefaultTestObjects.fs index cbc4eea8..c8f1df31 100644 --- a/tests/TestUtils/DefaultTestObjects.fs +++ b/tests/TestUtils/DefaultTestObjects.fs @@ -43,7 +43,7 @@ module ExpectedRows = row let firstRow(range: string) cc = let row = FsRow(FsRangeAddress(range),cc) - row[1].SetValueAs 1 + row[1].SetValueAs 1. row[2].SetValueAs "Hello" row[3].SetValueAs (System.DateTime(2023,10,14,0,0,0)) row[4].SetValueAs true @@ -52,7 +52,7 @@ module ExpectedRows = row let secondRow(range:string) cc = let row = FsRow(FsRangeAddress(range),cc) - row[1].SetValueAs 2 + row[1].SetValueAs 2. row[2].SetValueAs "World" row[3].SetValueAs (System.DateTime(2023,10,15, 18,0,0)) row[4].SetValueAs false @@ -60,14 +60,14 @@ module ExpectedRows = row let thirdRow(range:string) cc = let row = FsRow(FsRangeAddress(range),cc) - row[1].SetValueAs 3 + row[1].SetValueAs 3. row[2].SetValueAs "Bye" row[3].SetValueAs (System.DateTime(2023,10,16, 20,0,0)) row[4].SetValueAs true row let fourthRow(range:string) cc = let row = FsRow(FsRangeAddress(range),cc) - row[1].SetValueAs 4 + row[1].SetValueAs 4.269 row[2].SetValueAs "Outer Space" row[3].SetValueAs (System.DateTime(2023,10,17,0,0,0)) row[4].SetValueAs false diff --git a/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.fsx b/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.fsx index 0e7349d7..81513451 100644 --- a/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.fsx +++ b/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.fsx @@ -1,16 +1,25 @@ -#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Release\net6.0\DocumentFormat.OpenXml.dll" -#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Release\net6.0\FsSpreadsheet.dll" -#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Release\net6.0\FsSpreadsheet.ExcelIO.dll" -#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Release\net6.0\System.IO.Packaging.dll" +#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Debug\net6.0\DocumentFormat.OpenXml.dll" +#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Debug\net6.0\FsSpreadsheet.dll" +#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Debug\net6.0\FsSpreadsheet.ExcelIO.dll" +#r @"..\..\..\FsSpreadsheet.ExcelIO.Tests\bin\Debug\net6.0\System.IO.Packaging.dll" open FsSpreadsheet open FsSpreadsheet.ExcelIO +open DocumentFormat.OpenXml.Spreadsheet +open DocumentFormat.OpenXml let inputPath = @"../TestWorkbook_Excel.xlsx" let outputPath = @"../TestWorkbook_FsSpreadsheet.net.xlsx" let wb = FsWorkbook.fromXlsxFile (inputPath) +// wb.GetWorksheets().[0].GetCellAt(5,1) |> fun x -> (x.Value, x.DataType) |> printfn "%A" + +// let r = wb.GetWorksheets().[0].GetCellAt(5,1).Value |> string + +// Cell(DataType = EnumValue(CellValues.Number), CellValue = CellValue(r)).InnerText + +// for i in r do printfn "%A" i wb.ToFile(outputPath) diff --git a/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.js b/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.js index 11ed0b0f..12b9264a 100644 --- a/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.js +++ b/tests/TestUtils/TestFiles/Scripts/fsSpreadsheet.js @@ -6,8 +6,8 @@ export const outputPath = "../TestWorkbook_FsSpreadsheet.js.xlsx"; async function run() { let wb = await Xlsx.fromXlsxFile(inputPath) - console.log(wb) - // await Xlsx.toFile(wb) + // console.log(wb) + Xlsx.toFile(outputPath, wb) } run(); diff --git a/tests/TestUtils/TestFiles/TestWorkbook_ClosedXML.xlsx b/tests/TestUtils/TestFiles/TestWorkbook_ClosedXML.xlsx index 9df17ab7..09270a7e 100644 Binary files a/tests/TestUtils/TestFiles/TestWorkbook_ClosedXML.xlsx and b/tests/TestUtils/TestFiles/TestWorkbook_ClosedXML.xlsx differ diff --git a/tests/TestUtils/TestFiles/TestWorkbook_Excel.xlsx b/tests/TestUtils/TestFiles/TestWorkbook_Excel.xlsx index 16e21c11..013a1e5e 100644 Binary files a/tests/TestUtils/TestFiles/TestWorkbook_Excel.xlsx and b/tests/TestUtils/TestFiles/TestWorkbook_Excel.xlsx differ diff --git a/tests/TestUtils/TestFiles/TestWorkbook_FableExceljs.xlsx b/tests/TestUtils/TestFiles/TestWorkbook_FableExceljs.xlsx index 28fc364e..85dbdad5 100644 Binary files a/tests/TestUtils/TestFiles/TestWorkbook_FableExceljs.xlsx and b/tests/TestUtils/TestFiles/TestWorkbook_FableExceljs.xlsx differ diff --git a/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet.js.xlsx b/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet.js.xlsx new file mode 100644 index 00000000..77e4df3b Binary files /dev/null and b/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet.js.xlsx differ diff --git a/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet.net.xlsx b/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet.net.xlsx index 40c1cd02..85fdd4c9 100644 Binary files a/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet.net.xlsx and b/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet.net.xlsx differ diff --git a/tests/TestUtils/TestUtils.fsproj b/tests/TestUtils/TestUtils.fsproj index cc653788..476f1794 100644 --- a/tests/TestUtils/TestUtils.fsproj +++ b/tests/TestUtils/TestUtils.fsproj @@ -18,9 +18,12 @@ Always - - Always - + + Always + + + Always +