diff --git a/.gitignore b/.gitignore index 2f0773c2..d9eedbce 100644 --- a/.gitignore +++ b/.gitignore @@ -357,7 +357,7 @@ output/ /tests/FsSpreadsheet.JsNativeTests/fable/**/*.js /tests/FsSpreadsheet.Net.Tests/TestFiles/WRITE_*.xlsx /tests/JS/TestFiles/WRITE_*.xlsx -/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet_WRITE.*.xlsx +/tests/TestUtils/TestFiles/TestWorkbook_FsSpreadsheet_WRITE.** /js **/py/** /.venv diff --git a/docs/index.md b/docs/index.md index 30e2a1f1..b8905a55 100644 --- a/docs/index.md +++ b/docs/index.md @@ -31,7 +31,7 @@ npm install @fslab/fsspreadsheet pip install fsspreadsheet ``` -## Usage_IO +## Usage_Xlsx_IO ### F# @@ -59,7 +59,7 @@ const wb = Xlsx.fromXlsxFile(path) const newPath = "path/to/new/spreadsheet.xlsx" -Xlsx.toFile(newPath,wb) +Xlsx.toXlsxFile(newPath,wb) ``` ### Python @@ -69,9 +69,55 @@ from fsspreadsheet.xlsx import Xlsx path = "path/to/spreadsheet.xlsx" -wb = Xlsx.fromXlsxFile(path) +wb = Xlsx.from_xlsx_file(path) newPath = "path/to/new/spreadsheet.xlsx" -Xlsx.to_file(newPath,wb) +Xlsx.to_xlsx_file(newPath,wb) +``` + + +## Usage_Json_IO + +### F# + +```fsharp +open FsSpreadsheet +open FsSpreadsheet.Net + +let path = "path/to/spreadsheet.json" + +let wb = FsWorkbook.fromJsonFile(path) + +let newPath = "path/to/new/spreadsheet.json" + +wb.ToJsonFile(newPath) +``` + +### Javascript + +```javascript +import { Json } from '@fslab/fsspreadsheet/Json.js'; + +const path = "path/to/spreadsheet.json" + +const wb = Json.fromJsonFile(path) + +const newPath = "path/to/new/spreadsheet.json" + +Json.toJsonFile(newPath,wb) +``` + +### Python + +```python +from fsspreadsheet.json import Json + +path = "path/to/spreadsheet.json" + +wb = Json.from_json_file(path) + +newPath = "path/to/new/spreadsheet.json" + +Json.to_json_file(newPath,wb) ``` diff --git a/src/FsSpreadsheet.CsvIO/FsExtension.fs b/src/FsSpreadsheet.CsvIO/FsExtension.fs index 752df39a..d1b84bb6 100644 --- a/src/FsSpreadsheet.CsvIO/FsExtension.fs +++ b/src/FsSpreadsheet.CsvIO/FsExtension.fs @@ -58,55 +58,55 @@ module FsExtensions = type FsWorkbook with - member self.ToStream(stream : System.IO.MemoryStream,?Separator : char) = + member self.ToCsvStream(stream : System.IO.MemoryStream,?Separator : char) = let streamWriter = new System.IO.StreamWriter(stream) self.GetWorksheets().[0].ToTableString(Separator) |> streamWriter.Write streamWriter.Flush() - member self.ToBytes(?Separator : char) = + member self.ToCsvBytes(?Separator : char) = use memoryStream = new System.IO.MemoryStream() match Separator with - | Some s -> self.ToStream(memoryStream,s) - | None -> self.ToStream(memoryStream) + | Some s -> self.ToCsvStream(memoryStream,s) + | None -> self.ToCsvStream(memoryStream) memoryStream.ToArray() - member self.ToFile(path,?Separator : char) = + member self.ToCsvFile(path,?Separator : char) = match Separator with - | Some s -> self.ToBytes(s) - | None -> self.ToBytes() + | Some s -> self.ToCsvBytes(s) + | None -> self.ToCsvBytes() |> fun bytes -> System.IO.File.WriteAllBytes (path, bytes) - static member toStream(stream : System.IO.MemoryStream,workbook : FsWorkbook,?Separator : char) = + static member toCsvStream(stream : System.IO.MemoryStream,workbook : FsWorkbook,?Separator : char) = match Separator with - | Some s -> workbook.ToStream(stream,s) - | None -> workbook.ToStream(stream) - workbook.ToStream(stream) + | Some s -> workbook.ToCsvStream(stream,s) + | None -> workbook.ToCsvStream(stream) + workbook.ToCsvStream(stream) - static member toBytes(workbook: FsWorkbook,?Separator : char) = + static member toCsvBytes(workbook: FsWorkbook,?Separator : char) = match Separator with - | Some s -> workbook.ToBytes(s) - | None -> workbook.ToBytes() + | Some s -> workbook.ToCsvBytes(s) + | None -> workbook.ToCsvBytes() - static member toFile(path,workbook: FsWorkbook,?Separator : char) = + static member toCsvFile(path,workbook: FsWorkbook,?Separator : char) = match Separator with - | Some s -> workbook.ToFile(path,s) - | None -> workbook.ToFile(path) + | Some s -> workbook.ToCsvFile(path,s) + | None -> workbook.ToCsvFile(path) type Writer = - static member toStream(stream : System.IO.MemoryStream,workbook : FsWorkbook,?Separator : char) = + static member toCsvStream(stream : System.IO.MemoryStream,workbook : FsWorkbook,?Separator : char) = match Separator with - | Some s -> workbook.ToStream(stream,s) - | None -> workbook.ToStream(stream) - workbook.ToStream(stream) + | Some s -> workbook.ToCsvStream(stream,s) + | None -> workbook.ToCsvStream(stream) + workbook.ToCsvStream(stream) - static member toBytes(workbook: FsWorkbook,?Separator : char) = + static member toCsvBytes(workbook: FsWorkbook,?Separator : char) = match Separator with - | Some s -> workbook.ToBytes(s) - | None -> workbook.ToBytes() + | Some s -> workbook.ToCsvBytes(s) + | None -> workbook.ToCsvBytes() - static member toFile(path,workbook: FsWorkbook,?Separator : char) = + static member toCsvFile(path,workbook: FsWorkbook,?Separator : char) = match Separator with - | Some s -> workbook.ToFile(path,s) - | None -> workbook.ToFile(path) \ No newline at end of file + | Some s -> workbook.ToCsvFile(path,s) + | None -> workbook.ToCsvFile(path) \ No newline at end of file diff --git a/src/FsSpreadsheet.Js/FsExtensions.fs b/src/FsSpreadsheet.Js/FsExtensions.fs index fe57837d..41dadc70 100644 --- a/src/FsSpreadsheet.Js/FsExtensions.fs +++ b/src/FsSpreadsheet.Js/FsExtensions.fs @@ -17,23 +17,43 @@ type FsWorkbook with static member fromXlsxStream(stream:System.IO.Stream) : Promise = Xlsx.fromXlsxStream stream - static member fromBytes(bytes: byte []) : Promise = - Xlsx.fromBytes bytes + static member fromXlsxBytes(bytes: byte []) : Promise = + Xlsx.fromXlsxBytes bytes - static member toFile(path: string) (wb:FsWorkbook) : Promise = - Xlsx.toFile path wb + static member toXlsxFile(path: string) (wb:FsWorkbook) : Promise = + Xlsx.toXlsxFile path wb - static member toStream(stream: System.IO.Stream) (wb:FsWorkbook) : Promise = - Xlsx.toStream stream wb + static member toXlsxStream(stream: System.IO.Stream) (wb:FsWorkbook) : Promise = + Xlsx.toXlsxStream stream wb - static member toBytes(wb:FsWorkbook) : Promise = - Xlsx.toBytes wb + static member toXlsxBytes(wb:FsWorkbook) : Promise = + Xlsx.toXlsxBytes wb - member this.ToFile(path: string) : Promise = - FsWorkbook.toFile path this + member this.ToXlsxFile(path: string) : Promise = + FsWorkbook.toXlsxFile path this - member this.ToStream(stream: System.IO.Stream) : Promise = - FsWorkbook.toStream stream this + member this.ToXlsxStream(stream: System.IO.Stream) : Promise = + FsWorkbook.toXlsxStream stream this - member this.ToBytes() : Promise = - FsWorkbook.toBytes this \ No newline at end of file + member this.ToXlsxBytes() : Promise = + FsWorkbook.toXlsxBytes this + + + + static member fromJsonString (json:string) : FsWorkbook = + Json.fromJsonString json + + static member toJsonString (wb:FsWorkbook) : string = + Json.toJsonString wb + + //static member fromJsonFile (path:string) : Promise = + // Json.fromJsonFile path + + //static member toJsonFile (path:string) (wb:FsWorkbook) : Promise = + // Json.toJsonFile path wb + + //member this.ToJsonFile(path: string) : Promise = + // FsWorkbook.toJsonFile path this + + member this.ToJsonString() : string = + FsWorkbook.toJsonString this \ No newline at end of file diff --git a/src/FsSpreadsheet.Js/FsSpreadsheet.Js.fsproj b/src/FsSpreadsheet.Js/FsSpreadsheet.Js.fsproj index f380206c..adbfd0d2 100644 --- a/src/FsSpreadsheet.Js/FsSpreadsheet.Js.fsproj +++ b/src/FsSpreadsheet.Js/FsSpreadsheet.Js.fsproj @@ -26,20 +26,20 @@ + + - - - + diff --git a/src/FsSpreadsheet.Js/Json.fs b/src/FsSpreadsheet.Js/Json.fs new file mode 100644 index 00000000..3869db09 --- /dev/null +++ b/src/FsSpreadsheet.Js/Json.fs @@ -0,0 +1,42 @@ +namespace FsSpreadsheet.Js + +open FsSpreadsheet +open Fable.ExcelJs +open Fable.Core +open Fable.Core.JsInterop +open Fable.Core.JS + +open Thoth.Json.JavaScript + + + + +/// This does currently not correctly work if you want to use this from js +/// https://github.com/fable-compiler/Fable/issues/3498 +[] +type Json = + + static member tryFromJsonString (json:string) : Result = + match Thoth.Json.JavaScript.Decode.fromString FsSpreadsheet.Json.Workbook.decode json with + | Ok wb -> Ok wb + | Error e -> Error e + + static member fromJsonString (json:string) : FsWorkbook = + match Json.tryFromJsonString json with + | Ok wb -> wb + | Error e -> failwithf "Could not deserialize json Workbook: \n%s" e + + static member toJsonString (wb:FsWorkbook, ?spaces) : string = + let spaces = defaultArg spaces 2 + FsSpreadsheet.Json.Workbook.encode wb + |> Thoth.Json.JavaScript.Encode.toString spaces + + //static member fromJsonFile (path:string) : Promise = + // promise { + // let! json = Fable.Core.JS. path + // return Json.fromJsonString json + // } + + //static member toJsonFile (path:string) (wb:FsWorkbook) : Promise = + // let json = Json.toJsonString wb + // Fable.Core.JS.writeFile path json \ No newline at end of file diff --git a/src/FsSpreadsheet.Js/Xlsx.fs b/src/FsSpreadsheet.Js/Xlsx.fs index a3d6206b..8790fa4c 100644 --- a/src/FsSpreadsheet.Js/Xlsx.fs +++ b/src/FsSpreadsheet.Js/Xlsx.fs @@ -18,6 +18,10 @@ type Xlsx = return fswb } + [] + static member fromFile (path:string) : Promise = + Xlsx.fromXlsxFile path + static member fromXlsxStream (stream:System.IO.Stream) : Promise = promise { let wb = ExcelJs.Excel.Workbook() @@ -25,7 +29,11 @@ type Xlsx = return JsWorkbook.readToFsWorkbook wb } - static member fromBytes (bytes: byte []) : Promise = + [] + static member fromStream (stream:System.IO.Stream) : Promise = + Xlsx.fromXlsxStream stream + + static member fromXlsxBytes (bytes: byte []) : Promise = promise { let wb = ExcelJs.Excel.Workbook() let uint8 = Fable.Core.JS.Constructors.Uint8Array.Create bytes @@ -33,19 +41,34 @@ type Xlsx = return JsWorkbook.readToFsWorkbook wb } - static member toFile (path: string) (wb:FsWorkbook) : Promise = + [] + static member fromBytes (bytes: byte []) : Promise = + Xlsx.fromXlsxBytes bytes + + static member toXlsxFile (path: string) (wb:FsWorkbook) : Promise = let jswb = JsWorkbook.writeFromFsWorkbook wb jswb.xlsx.writeFile(path) - static member toStream (stream: System.IO.Stream) (wb:FsWorkbook) : Promise = + [] + static member toFile (path: string) (wb:FsWorkbook) : Promise = + Xlsx.toXlsxFile path wb + + static member toXlsxStream (stream: System.IO.Stream) (wb:FsWorkbook) : Promise = let jswb = JsWorkbook.writeFromFsWorkbook wb jswb.xlsx.write(stream) - static member toBytes (wb:FsWorkbook) : Promise = + [] + static member toStream (stream: System.IO.Stream) (wb:FsWorkbook) : Promise = + Xlsx.toXlsxStream stream wb + + static member toXlsxBytes (wb:FsWorkbook) : Promise = promise { let jswb = JsWorkbook.writeFromFsWorkbook wb let buffer = jswb.xlsx.writeBuffer() return !!buffer } + [] + static member toBytes (wb:FsWorkbook) : Promise = + Xlsx.toXlsxBytes wb \ No newline at end of file diff --git a/src/FsSpreadsheet.Net/FsExtensions.fs b/src/FsSpreadsheet.Net/FsExtensions.fs index d827cd2f..7558ebf0 100644 --- a/src/FsSpreadsheet.Net/FsExtensions.fs +++ b/src/FsSpreadsheet.Net/FsExtensions.fs @@ -308,7 +308,7 @@ module FsExtensions = /// /// Creates an FsWorkbook from a given Stream to an XlsxFile. /// - static member fromBytes (bytes : byte []) = + static member fromXlsxBytes (bytes : byte []) = let stream = new MemoryStream(bytes,writable = true) FsWorkbook.fromXlsxStream stream @@ -317,8 +317,43 @@ module FsExtensions = /// static member fromXlsxFile (filePath : string) = let bytes = File.ReadAllBytes filePath - FsWorkbook.fromBytes bytes + FsWorkbook.fromXlsxBytes bytes + /// + /// Takes the path to an Xlsx file and returns the FsWorkbook based on its content. + /// + [] + static member fromFile (filePath : string) = + let bytes = File.ReadAllBytes filePath + FsWorkbook.fromXlsxBytes bytes + + /// + /// Takes a json string and returns the FsWorkbook based on its content. + /// + static member tryFromJsonString (json : string) = + Thoth.Json.Newtonsoft.Decode.fromString FsSpreadsheet.Json.Workbook.decode json + + /// + /// Takes a json string and returns the FsWorkbook based on its content. + /// + static member fromJsonString (json : string) = + match FsWorkbook.tryFromJsonString json with + | Ok wb -> wb + | Error e -> failwithf "Could not deserialize json Workbook: \n%s" e + + /// + /// Takes the path to an json file and returns the FsWorkbook based on its content. + /// + static member tryFromJsonFile (filePath : string) = + let json = File.ReadAllText filePath + FsWorkbook.tryFromJsonString json + + /// + /// Takes the path to an json file and returns the FsWorkbook based on its content. + /// + static member fromJsonFile (filePath : string) = + let json = File.ReadAllText filePath + FsWorkbook.fromJsonString json member self.ToEmptySpreadsheet(doc : Packaging.SpreadsheetDocument) = @@ -334,7 +369,7 @@ module FsExtensions = /// /// Writes the FsWorkbook into a given MemoryStream. /// - member self.ToStream(stream : MemoryStream) = + member self.ToXlsxStream(stream : MemoryStream) = if self.GetWorksheets() |> Seq.isEmpty then failwith "Cannot write an empty workbook to a stream. Workbook did not contain any Worksheets." let doc = Spreadsheet.initEmptyOnStream stream @@ -348,28 +383,36 @@ module FsExtensions = /// /// Writes an FsWorkbook into a given MemoryStream. /// - static member toStream stream (workbook : FsWorkbook) = - workbook.ToStream stream + static member toXlsxStream stream (workbook : FsWorkbook) = + workbook.ToXlsxStream stream /// /// Returns the FsWorkbook in the form of a byte array. /// - member self.ToBytes() = + member self.ToXlsxBytes() = use memoryStream = new MemoryStream() - self.ToStream(memoryStream) + self.ToXlsxStream(memoryStream) memoryStream.ToArray() /// /// Returns an FsWorkbook in the form of a byte array. /// - static member toBytes (workbook: FsWorkbook) = - workbook.ToBytes() + static member toXlsxBytes (workbook: FsWorkbook) = + workbook.ToXlsxBytes() /// /// Writes the FsWorkbook into a binary file at the given path. /// member self.ToXlsxFile(path) = - self.ToBytes() + self.ToXlsxBytes() + |> fun bytes -> File.WriteAllBytes (path, bytes) + + /// + /// Writes the FsWorkbook into a binary file at the given path. + /// + [] + member self.ToFile(path) = + self.ToXlsxBytes() |> fun bytes -> File.WriteAllBytes (path, bytes) /// @@ -378,25 +421,61 @@ module FsExtensions = static member toXlsxFile path (workbook : FsWorkbook) = workbook.ToXlsxFile(path) + /// + /// Takes the path to an Xlsx file and returns the FsWorkbook based on its content. + /// + [] + static member toFile (filePath : string) path (workbook : FsWorkbook) = + workbook.ToXlsxFile(path) + + static member toJsonString (workbook : FsWorkbook, ?spaces) = + let spaces = defaultArg spaces 2 + FsSpreadsheet.Json.Workbook.encode workbook + |> Thoth.Json.Newtonsoft.Encode.toString spaces + + static member toJsonFile (path, ?spaces) = + fun workbook -> + let json = FsWorkbook.toJsonString (workbook,?spaces = spaces) + File.WriteAllText(path,json) + + member this.ToJsonString(?spaces) = + FsWorkbook.toJsonString(this, ?spaces = spaces) + + member this.ToJsonFile(path: string, ?spaces) = + FsWorkbook.toJsonFile(path, ?spaces = spaces) this type Writer = + /// /// Writes an FsWorkbook into a given MemoryStream. /// - static member toStream(stream : MemoryStream, workbook : FsWorkbook) = - workbook.ToStream(stream) + static member toXlsxStream(stream : MemoryStream, workbook : FsWorkbook) = + workbook.ToXlsxStream(stream) /// /// Returns an FsWorkbook in the form of a byte array. /// - static member toBytes(workbook: FsWorkbook) = - workbook.ToBytes() + static member toXlsxBytes(workbook: FsWorkbook) = + workbook.ToXlsxBytes() /// /// Writes an FsWorkbook into a binary file at the given path. /// + static member toXlsxFile(path,workbook: FsWorkbook) = + workbook.ToXlsxFile(path) + + /// + /// Writes an FsWorkbook into a binary file at the given path. + /// + [] static member toFile(path,workbook: FsWorkbook) = - workbook.ToXlsxFile(path) \ No newline at end of file + workbook.ToXlsxFile(path) + + static member toJsonString (workbook : FsWorkbook, ?spaces) = + FsWorkbook.toJsonString(workbook, ?spaces = spaces) + + static member toJsonFile (path, ?spaces) = + fun workbook -> FsWorkbook.toJsonFile (path, ?spaces = spaces) workbook \ No newline at end of file diff --git a/src/FsSpreadsheet.Net/FsSpreadsheet.Net.fsproj b/src/FsSpreadsheet.Net/FsSpreadsheet.Net.fsproj index 5ebaf83c..ef666692 100644 --- a/src/FsSpreadsheet.Net/FsSpreadsheet.Net.fsproj +++ b/src/FsSpreadsheet.Net/FsSpreadsheet.Net.fsproj @@ -35,6 +35,7 @@ + diff --git a/src/FsSpreadsheet.Net/ZipArchiveReader.fs b/src/FsSpreadsheet.Net/ZipArchiveReader.fs index 3a1d24dc..e0f31fc9 100644 --- a/src/FsSpreadsheet.Net/ZipArchiveReader.fs +++ b/src/FsSpreadsheet.Net/ZipArchiveReader.fs @@ -325,14 +325,14 @@ module FsWorkbook = let fromZipArchive (wb : ZipArchive) = parseWorkbook wb - let fromStream (stream : Stream) = + let fromXlsxStream (stream : Stream) = use zip = new ZipArchive(stream) fromZipArchive zip - let fromBytes (bytes : byte []) = + let fromXlsxBytes (bytes : byte []) = use ms = new MemoryStream(bytes) - fromStream ms + fromXlsxStream ms - let fromFile (path : string) = + let fromXlsxFile (path : string) = use fs = File.OpenRead(path) - fromStream fs \ No newline at end of file + fromXlsxStream fs \ No newline at end of file diff --git a/src/FsSpreadsheet.Py/FsExtension.fs b/src/FsSpreadsheet.Py/FsExtension.fs index f3b9b8c4..eadbf417 100644 --- a/src/FsSpreadsheet.Py/FsExtension.fs +++ b/src/FsSpreadsheet.Py/FsExtension.fs @@ -3,7 +3,6 @@ module FsSpreadsheet.Py.FsSpreadsheet open FsSpreadsheet open FsSpreadsheet.Py -open Fable.Core // This is mainly used for fsharp based access in a fable environment. // If you want to use these bindings from js, you should use the ones in `Xlsx.fs` @@ -15,24 +14,42 @@ type FsWorkbook with static member fromXlsxStream(stream:System.IO.Stream) : FsWorkbook = Xlsx.fromXlsxStream stream - static member fromBytes(bytes: byte []) : FsWorkbook = - Xlsx.fromBytes bytes + static member fromXlsxBytes(bytes: byte []) : FsWorkbook = + Xlsx.fromXlsxBytes bytes - static member toFile(path: string) (wb:FsWorkbook) : unit = - Xlsx.toFile path wb + static member toXlsxFile(path: string) (wb:FsWorkbook) : unit = + Xlsx.toXlsxFile path wb - //static member toStream(stream: System.IO.Stream) (wb:FsWorkbook) : Promise = + //static member toXlsxStream(stream: System.IO.Stream) (wb:FsWorkbook) : Promise = // PyWorkbook.fromFsWorkbook wb // |> fun wb -> Xlsx.writeBuffer(wb,stream) - static member toBytes(wb:FsWorkbook) : byte [] = - Xlsx.toBytes wb + static member toXlsxBytes(wb:FsWorkbook) : byte [] = + Xlsx.toXlsxBytes wb - member this.ToFile(path: string) : unit = - FsWorkbook.toFile path this + member this.ToXlsxFile(path: string) : unit = + FsWorkbook.toXlsxFile path this - //member this.ToStream(stream: System.IO.Stream) : unit = - // FsWorkbook.toStream stream this + //member this.ToXlsxStream(stream: System.IO.Stream) : unit = + // FsWorkbook.toXlsxStream stream this - member this.ToBytes() : byte [] = - FsWorkbook.toBytes this \ No newline at end of file + member this.ToXlsxBytes() : byte [] = + FsWorkbook.toXlsxBytes this + + static member fromJsonString (json:string) : FsWorkbook = + Json.fromJsonString json + + static member toJsonString (wb:FsWorkbook) : string = + Json.toJsonString wb + + //static member fromJsonFile (path:string) : Promise = + // Json.fromJsonFile path + + //static member toJsonFile (path:string) (wb:FsWorkbook) : Promise = + // Json.toJsonFile path wb + + //member this.ToJsonFile(path: string) : Promise = + // FsWorkbook.toJsonFile path this + + member this.ToJsonString() : string = + FsWorkbook.toJsonString this \ No newline at end of file diff --git a/src/FsSpreadsheet.Py/FsSpreadsheet.Py.fsproj b/src/FsSpreadsheet.Py/FsSpreadsheet.Py.fsproj index 3b300a7a..243da25a 100644 --- a/src/FsSpreadsheet.Py/FsSpreadsheet.Py.fsproj +++ b/src/FsSpreadsheet.Py/FsSpreadsheet.Py.fsproj @@ -12,17 +12,17 @@ + + - - - + diff --git a/src/FsSpreadsheet.Py/Json.fs b/src/FsSpreadsheet.Py/Json.fs new file mode 100644 index 00000000..17f22cda --- /dev/null +++ b/src/FsSpreadsheet.Py/Json.fs @@ -0,0 +1,29 @@ +namespace FsSpreadsheet.Py + +open FsSpreadsheet +open Fable.Core +open Fable.Core.JsInterop +open Fable.Core.JS + +open Thoth.Json.Python + + + + +/// This does currently not correctly work if you want to use this from js +/// https://github.com/fable-compiler/Fable/issues/3498 +[] +type Json = + + static member tryFromJsonString (json:string) : Result = + Decode.fromString FsSpreadsheet.Json.Workbook.decode json + + static member fromJsonString (json:string) : FsWorkbook = + match Json.tryFromJsonString json with + | Ok wb -> wb + | Error e -> failwithf "Could not deserialize json Workbook: \n%s" e + + static member toJsonString (wb:FsWorkbook, ?spaces) : string = + let spaces = defaultArg spaces 2 + FsSpreadsheet.Json.Workbook.encode wb + |> Encode.toString spaces diff --git a/src/FsSpreadsheet.Py/Xlsx.fs b/src/FsSpreadsheet.Py/Xlsx.fs index b0682358..9014b433 100644 --- a/src/FsSpreadsheet.Py/Xlsx.fs +++ b/src/FsSpreadsheet.Py/Xlsx.fs @@ -19,18 +19,18 @@ type Xlsx = Xlsx.load stream |> PyWorkbook.toFsWorkbook - static member fromBytes(bytes: byte []) : FsWorkbook = + static member fromXlsxBytes(bytes: byte []) : FsWorkbook = Xlsx.read bytes |> PyWorkbook.toFsWorkbook - static member toFile(path: string) (wb:FsWorkbook) : unit = + static member toXlsxFile(path: string) (wb:FsWorkbook) : unit = PyWorkbook.fromFsWorkbook wb |> fun wb -> Xlsx.writeFile(wb,path) - //static member toStream(stream: System.IO.Stream) (wb:FsWorkbook) : Promise = + //static member toXlsxStream(stream: System.IO.Stream) (wb:FsWorkbook) : Promise = // PyWorkbook.fromFsWorkbook wb // |> fun wb -> Xlsx.writeBuffer(wb,stream) - static member toBytes(wb:FsWorkbook) : byte [] = + static member toXlsxBytes(wb:FsWorkbook) : byte [] = PyWorkbook.fromFsWorkbook wb |> fun wb -> Xlsx.write(wb) diff --git a/src/FsSpreadsheet/FsSpreadsheet.fsproj b/src/FsSpreadsheet/FsSpreadsheet.fsproj index 0376e21d..aead6edd 100644 --- a/src/FsSpreadsheet/FsSpreadsheet.fsproj +++ b/src/FsSpreadsheet/FsSpreadsheet.fsproj @@ -33,6 +33,12 @@ + + + + + + @@ -48,11 +54,11 @@ - + - + - + diff --git a/src/FsSpreadsheet/Json/Cell.fs b/src/FsSpreadsheet/Json/Cell.fs new file mode 100644 index 00000000..118aad94 --- /dev/null +++ b/src/FsSpreadsheet/Json/Cell.fs @@ -0,0 +1,23 @@ +module FsSpreadsheet.Json.Cell + +open FsSpreadsheet +open Thoth.Json.Core + +[] +let column = "column" + +[] +let value = "value" + +let encode (cell:FsCell) = + Encode.object [ + column, Encode.int cell.ColumnNumber + value, Value.encode cell.Value + ] + +let decode rowNumber : Decoder = + Decode.object (fun builder -> + let v,dt = builder.Required.Field value (Value.decode) + let c = builder.Required.Field column Decode.int + new FsCell(v,dt,FsAddress(rowNumber,c)) + ) diff --git a/src/FsSpreadsheet/Json/Row.fs b/src/FsSpreadsheet/Json/Row.fs new file mode 100644 index 00000000..d633a42d --- /dev/null +++ b/src/FsSpreadsheet/Json/Row.fs @@ -0,0 +1,23 @@ +module FsSpreadsheet.Json.Row + +open FsSpreadsheet +open Thoth.Json.Core + +[] +let cells = "cells" + +[] +let number = "number" + +let encode (row:FsRow) = + Encode.object [ + number, Encode.int row.Index + cells, Encode.seq (row.Cells |> Seq.map Cell.encode) + ] + +let decode : Decoder = + Decode.object (fun builder -> + let n = builder.Required.Field number Decode.int + let cs = builder.Required.Field cells (Decode.seq (Cell.decode n)) + n,cs + ) \ No newline at end of file diff --git a/src/FsSpreadsheet/Json/Table.fs b/src/FsSpreadsheet/Json/Table.fs new file mode 100644 index 00000000..3514660b --- /dev/null +++ b/src/FsSpreadsheet/Json/Table.fs @@ -0,0 +1,24 @@ +module FsSpreadsheet.Json.Table + +open FsSpreadsheet +open Thoth.Json.Core + + +[] +let name = "name" + +[] +let range = "range" + +let encode (sheet:FsTable) = + Encode.object [ + name, Encode.string sheet.Name + range, Encode.string sheet.RangeAddress.Range + ] + +let decode : Decoder = + Decode.object (fun builder -> + let n = builder.Required.Field name Decode.string + let r = builder.Required.Field range Decode.string + FsTable(n, FsRangeAddress(r)) + ) \ No newline at end of file diff --git a/src/FsSpreadsheet/Json/Value.fs b/src/FsSpreadsheet/Json/Value.fs new file mode 100644 index 00000000..6d48fda0 --- /dev/null +++ b/src/FsSpreadsheet/Json/Value.fs @@ -0,0 +1,70 @@ +module FsSpreadsheet.Json.Value + +open Thoth.Json.Core +open FsSpreadsheet + +#if FABLE_COMPILER_PYTHON +module PyTime = + + open Fable.Core + open Fable.Core.PyInterop + + // Currently in Fable, a created datetime object will contain a timezone. This is not allowed in python xlsx, so we need to remove it. + // Unfortunately, the timezone object in python is read-only, so we need to create a new datetime object without timezone. + // For this, we use the fromtimestamp method of the datetime module and convert the timestamp to a new datetime object without timezone. + + type DateTimeStatic = + [] + abstract member fromTimeStamp: timestamp:float -> System.DateTime + + [] + let DateTime : DateTimeStatic = nativeOnly + + let toUniversalTimePy (dt:System.DateTime) = + + dt.ToUniversalTime()?timestamp() + |> DateTime.fromTimeStamp +#endif + + + + + +module Decode = + + let datetime: Decoder = + #if FABLE_COMPILER_PYTHON + Decode.datetimeLocal |> Decode.map PyTime.toUniversalTimePy + #else + { new Decoder with + member _.Decode(helpers, value) = + if helpers.isString value then + match System.DateTime.TryParse(helpers.asString value) with + | true, datetime -> datetime |> Ok + | _ -> ("", BadPrimitive("a datetime", value)) |> Error + else + ("", BadPrimitive("a datetime", value)) |> Error + } + #endif + +let encode (value : obj) = + match value with + | :? string as s -> Encode.string s + | :? float as f -> Encode.float f + | :? int as i -> Encode.int i + | :? bool as b -> Encode.bool b + | :? System.DateTime as d -> + d.ToString("O", System.Globalization.CultureInfo.InvariantCulture).Split('+').[0] + |> Encode.string + | _ -> Encode.nil + + + +let decode = + Decode.oneOf [ + Decode.bool |> Decode.map (fun b -> b :> obj, DataType.Boolean) + Decode.int |> Decode.map (fun i -> i :> obj, DataType.Number) + Decode.float |> Decode.map (fun f -> f :> obj, DataType.Number) + Decode.datetime |> Decode.map (fun d -> d :> obj, DataType.Date) + Decode.string |> Decode.map (fun s -> s :> obj, DataType.String) + ] \ No newline at end of file diff --git a/src/FsSpreadsheet/Json/Workbook.fs b/src/FsSpreadsheet/Json/Workbook.fs new file mode 100644 index 00000000..cd00d6a0 --- /dev/null +++ b/src/FsSpreadsheet/Json/Workbook.fs @@ -0,0 +1,20 @@ +module FsSpreadsheet.Json.Workbook + +open FsSpreadsheet +open Thoth.Json.Core + +[] +let sheets = "sheets" + +let encode (wb:FsWorkbook) = + Encode.object [ + sheets, Encode.seq (wb.GetWorksheets() |> Seq.map Worksheet.encode) + ] + +let decode : Decoder = + Decode.object (fun builder -> + let wb = new FsWorkbook() + let ws = builder.Required.Field sheets (Decode.seq Worksheet.decode) + wb.AddWorksheets(ws) + wb + ) \ No newline at end of file diff --git a/src/FsSpreadsheet/Json/Worksheet.fs b/src/FsSpreadsheet/Json/Worksheet.fs new file mode 100644 index 00000000..f126b2fb --- /dev/null +++ b/src/FsSpreadsheet/Json/Worksheet.fs @@ -0,0 +1,49 @@ +module FsSpreadsheet.Json.Worksheet + +open FsSpreadsheet +open Thoth.Json.Core + +[] +let name = "name" + +[] +let rows = "rows" + +[] +let tables = "tables" + +let encode (sheet:FsWorksheet) = + sheet.RescanRows() + Encode.object [ + name, Encode.string sheet.Name + if Seq.isEmpty sheet.Tables |> not then + tables, Encode.seq (sheet.Tables |> Seq.map Table.encode) + rows, Encode.seq (sheet.Rows |> Seq.map Row.encode) + + ] + +let decode : Decoder = + Decode.object (fun builder -> + let n = builder.Required.Field name Decode.string + let ts = builder.Optional.Field tables (Decode.seq Table.decode) + let rs = builder.Required.Field rows (Decode.seq Row.decode) + let sheet = new FsWorksheet(n) + rs + |> Seq.iter (fun (rowI,cells) -> + let r = sheet.Row(rowI) + cells + |> Seq.iter (fun cell -> + let c = r[cell.ColumnNumber] + c.Value <- cell.Value + c.DataType <- cell.DataType + ) + ) + match ts with + | Some ts -> + ts + |> Seq.iter (fun t -> + sheet.AddTable(t) |> ignore + ) + | None -> () + sheet + ) \ No newline at end of file diff --git a/tests/FsSpreadsheet.Js.Tests/DefaultIO.Tests.fs b/tests/FsSpreadsheet.Js.Tests/DefaultIO.Tests.fs index 0626a179..ff2d412f 100644 --- a/tests/FsSpreadsheet.Js.Tests/DefaultIO.Tests.fs +++ b/tests/FsSpreadsheet.Js.Tests/DefaultIO.Tests.fs @@ -41,7 +41,7 @@ let private tests_Write = testList "Write" [ testCaseAsync "default" (Async.AwaitPromise <| promise { let wb = DefaultTestObject.defaultTestObject() let p = DefaultTestObject.WriteTestFiles.FsSpreadsheetJS.asRelativePathNode - do! FsWorkbook.toFile p wb + do! FsWorkbook.toXlsxFile p wb let! wb_read = FsWorkbook.fromXlsxFile p Expect.isDefaultTestObject wb_read }) diff --git a/tests/FsSpreadsheet.Js.Tests/FsSpreadsheet.Js.Tests.fsproj b/tests/FsSpreadsheet.Js.Tests/FsSpreadsheet.Js.Tests.fsproj index 95538507..1030228b 100644 --- a/tests/FsSpreadsheet.Js.Tests/FsSpreadsheet.Js.Tests.fsproj +++ b/tests/FsSpreadsheet.Js.Tests/FsSpreadsheet.Js.Tests.fsproj @@ -9,6 +9,7 @@ + diff --git a/tests/FsSpreadsheet.Js.Tests/Json.Tests.fs b/tests/FsSpreadsheet.Js.Tests/Json.Tests.fs new file mode 100644 index 00000000..1316477e --- /dev/null +++ b/tests/FsSpreadsheet.Js.Tests/Json.Tests.fs @@ -0,0 +1,19 @@ +module Json.Tests + +open FsSpreadsheet +open FsSpreadsheet.Js +open Fable.Pyxpecto + +let defaultTestObject = + testList "defaultTestObject" [ + + testCase "Read-Write DefaultTestObject" <| fun _ -> + let dto = DefaultTestObject.defaultTestObject() + let s = dto.ToJsonString() + let dto2 = FsWorkbook.fromJsonString(s) + TestingUtils.Expect.isDefaultTestObject dto2 + ] + +let main = testList "Json" [ + defaultTestObject +] \ No newline at end of file diff --git a/tests/FsSpreadsheet.Js.Tests/Main.fs b/tests/FsSpreadsheet.Js.Tests/Main.fs index f2554c42..7120117e 100644 --- a/tests/FsSpreadsheet.Js.Tests/Main.fs +++ b/tests/FsSpreadsheet.Js.Tests/Main.fs @@ -9,6 +9,7 @@ let all = [ Workbook.Tests.main DefaultIO.Tests.main + Json.Tests.main ] // This is possibly the most magic used to make this work. diff --git a/tests/FsSpreadsheet.Net.Tests/DefaultIO.Tests.fs b/tests/FsSpreadsheet.Net.Tests/DefaultIO.Tests.fs index de46301e..69127753 100644 --- a/tests/FsSpreadsheet.Net.Tests/DefaultIO.Tests.fs +++ b/tests/FsSpreadsheet.Net.Tests/DefaultIO.Tests.fs @@ -1,6 +1,5 @@ module DefaultIO -open Expecto open TestingUtils open FsSpreadsheet open FsSpreadsheet.Net @@ -45,7 +44,6 @@ let private tests_Write = testList "Write" [ ] -[] let main = testList "DefaultIO" [ tests_Read tests_Write diff --git a/tests/FsSpreadsheet.Net.Tests/FsSpreadsheet.Net.Tests.fsproj b/tests/FsSpreadsheet.Net.Tests/FsSpreadsheet.Net.Tests.fsproj index ddb13f7d..9f3361ed 100644 --- a/tests/FsSpreadsheet.Net.Tests/FsSpreadsheet.Net.Tests.fsproj +++ b/tests/FsSpreadsheet.Net.Tests/FsSpreadsheet.Net.Tests.fsproj @@ -18,6 +18,7 @@ + diff --git a/tests/FsSpreadsheet.Net.Tests/FsWorkbook.fs b/tests/FsSpreadsheet.Net.Tests/FsWorkbook.fs index f8abf1ae..75183445 100644 --- a/tests/FsSpreadsheet.Net.Tests/FsWorkbook.fs +++ b/tests/FsSpreadsheet.Net.Tests/FsWorkbook.fs @@ -1,6 +1,4 @@ -module FsWorkbook - -open Expecto +module FsWorkbook.Tests open FsSpreadsheet open FsSpreadsheet.Net @@ -10,7 +8,7 @@ let writeAndReadBytes = testList "WriteAndReadBytes" [ testCase "Empty" (fun () -> let wb = new FsWorkbook() - let f() = wb.ToBytes() + let f() = wb.ToXlsxBytes() try f() |> ignore failwith "Should throw an exception" @@ -35,8 +33,8 @@ let writeAndReadBytes = let expected = new FsWorkbook() let ws = TestObjects.sheet1() expected.AddWorksheet(ws) - let bytes = expected.ToBytes() - let actual = FsWorkbook.fromBytes(bytes) + let bytes = expected.ToXlsxBytes() + let actual = FsWorkbook.fromXlsxBytes(bytes) Expect.equal (expected.GetWorksheets().Count) (actual.GetWorksheets().Count) "Worksheet count should be equal" Expect.equal (expected.GetWorksheetByName(TestObjects.sheet1Name).Name) TestObjects.sheet1Name "excpected sheetname" Expect.equal (actual.GetWorksheetByName(TestObjects.sheet1Name).Name) TestObjects.sheet1Name "actual sheetname" @@ -46,8 +44,8 @@ let writeAndReadBytes = let wb = new FsWorkbook() wb.AddWorksheet(TestObjects.sheet1()) wb.AddWorksheet(TestObjects.sheet2()) - let bytes = wb.ToBytes() - let wb2 = FsWorkbook.fromBytes(bytes) + let bytes = wb.ToXlsxBytes() + let wb2 = FsWorkbook.fromXlsxBytes(bytes) Expect.equal (wb.GetWorksheets().Count) (wb2.GetWorksheets().Count) "Worksheet count should be equal" Expect.workSheetEqual (wb.GetWorksheetByName(TestObjects.sheet1Name)) (wb2.GetWorksheetByName(TestObjects.sheet1Name)) "First Worksheet did not match" Expect.workSheetEqual (wb.GetWorksheetByName(TestObjects.sheet2Name)) (wb2.GetWorksheetByName(TestObjects.sheet2Name)) "Second Worksheet did not match" @@ -72,19 +70,17 @@ let performance = testList "Performace" [ testCase "ReadBigFile" (fun () -> let sw = Stopwatch() - let p = "./TestFiles/BigFile.xlsx" - sw.Start() - let wb = FsWorkbook.fromXlsxFile(p) + sw.Start() + let wb = FsWorkbook.fromXlsxFile(DefaultTestObject.BigFile.asRelativePath) sw.Stop() let elapsed = sw.Elapsed.Milliseconds - Expect.isLessThan elapsed 2000 $"Elapsed time should be less than 2000ms, but was {elapsed}ms" + Expect.isTrue (elapsed < 2000) $"Elapsed time should be less than 2000ms, but was {elapsed}ms" Expect.equal (wb.GetWorksheetAt(1).Rows.Count) 153991 "Row count should be 153991" ) ] -[] -let tests = +let main = testList "FsWorkbook" [ writeAndReadBytes performance diff --git a/tests/FsSpreadsheet.Net.Tests/Json.Tests.fs b/tests/FsSpreadsheet.Net.Tests/Json.Tests.fs new file mode 100644 index 00000000..28803b04 --- /dev/null +++ b/tests/FsSpreadsheet.Net.Tests/Json.Tests.fs @@ -0,0 +1,21 @@ +module Json.Tests + +open TestingUtils +open FsSpreadsheet +open FsSpreadsheet.Net +open Fable.Pyxpecto + +let defaultTestObject = + testList "defaultTestObject" [ + + testCase "Read-Write DefaultTestObject" <| fun _ -> + let dto = DefaultTestObject.defaultTestObject() + let s = dto.ToJsonString() + System.IO.File.WriteAllText(DefaultTestObject.FsSpreadsheetJSON.asRelativePath,s) + let dto2 = FsWorkbook.fromJsonString(s) + TestingUtils.Expect.isDefaultTestObject dto2 + ] + +let main = testList "Json" [ + defaultTestObject +] \ No newline at end of file diff --git a/tests/FsSpreadsheet.Net.Tests/Main.fs b/tests/FsSpreadsheet.Net.Tests/Main.fs index d6a0bbfc..e4314e2a 100644 --- a/tests/FsSpreadsheet.Net.Tests/Main.fs +++ b/tests/FsSpreadsheet.Net.Tests/Main.fs @@ -1,6 +1,24 @@ module FsSpreadsheet.Net.Tests -open Expecto + +open Fable.Pyxpecto +open TestingUtils + +let all = + testList "All" + [ + ZipArchiveReader.main + Stylesheet.main + DefaultIO.main + FsExtension.Tests.main + Cell.Tests.main + Sheet.Tests.main + Workbook.Tests.main + Spreadsheet.Tests.main + Table.Tests.main + FsWorkbook.Tests.main + Json.Tests.main + ] [] let main argv = - Tests.runTestsInAssemblyWithCLIArgs [] argv \ No newline at end of file + Pyxpecto.runTests [||] all \ No newline at end of file diff --git a/tests/FsSpreadsheet.Net.Tests/OpenXml/Cell.fs b/tests/FsSpreadsheet.Net.Tests/OpenXml/Cell.fs index 3695bf13..d90c7fea 100644 --- a/tests/FsSpreadsheet.Net.Tests/OpenXml/Cell.fs +++ b/tests/FsSpreadsheet.Net.Tests/OpenXml/Cell.fs @@ -1,6 +1,6 @@ -module Cell +module Cell.Tests -open Expecto +open TestingUtils open FsSpreadsheet.Net open DocumentFormat.OpenXml @@ -17,7 +17,6 @@ let cbsi1Fox = wsp1Fox.Worksheet.Descendants() |> Array.ofSeq let nullCell = Cell.create (Some Spreadsheet.CellValues.Error) "A1" (Cell.CellValue.create "") nullCell.CellValue.Text <- null -[] let cellTests = testList "Cell" [ testList "includeSharedStringValue" [ @@ -28,4 +27,6 @@ let cellTests = testCase "nullCell with included SharedStringValue has no CellValueText" <| fun _ -> Expect.notEqual cissv1_0.CellValue.Text cissvNull.CellValue.Text "Does not differ" ] - ] \ No newline at end of file + ] + +let main = cellTests \ No newline at end of file diff --git a/tests/FsSpreadsheet.Net.Tests/OpenXml/FsExtensions.fs b/tests/FsSpreadsheet.Net.Tests/OpenXml/FsExtensions.fs index 3b7ea2ef..94f7bfa3 100644 --- a/tests/FsSpreadsheet.Net.Tests/OpenXml/FsExtensions.fs +++ b/tests/FsSpreadsheet.Net.Tests/OpenXml/FsExtensions.fs @@ -1,6 +1,6 @@ -module FsExtension +module FsExtension.Tests -open Expecto +open TestingUtils open FsSpreadsheet open FsSpreadsheet.Net open DocumentFormat.OpenXml @@ -50,7 +50,6 @@ dummyFsWorkbook.AddWorksheet(dummyFsWorksheet4) |> ignore let testFile2Path = Path.Combine(__SOURCE_DIRECTORY__, "../data", "2EXT02_Protein.xlsx") -[] let fsExtensionTests = testList "FsExtensions" [ //testList "DataType" [ @@ -163,7 +162,9 @@ let fsExtensionTests = Expect.equal v "Id" "value is not equal" testCase "Worksheet SwateTemplateMetadata from 2EXT02_Protein has FsRows" <| fun _ -> let rows = tf2Worksheet.Value.Rows - Expect.isGreaterThan rows.Count 0 "Worksheet SwateTemplateMetadata from 2EXT02_Protein has no FsRows" + Expect.notEqual rows.Count 0 "Worksheet SwateTemplateMetadata from 2EXT02_Protein has no FsRows" ] ] - ] \ No newline at end of file + ] + +let main = fsExtensionTests diff --git a/tests/FsSpreadsheet.Net.Tests/OpenXml/Sheet.fs b/tests/FsSpreadsheet.Net.Tests/OpenXml/Sheet.fs index 7993e60e..c3a9a6b7 100644 --- a/tests/FsSpreadsheet.Net.Tests/OpenXml/Sheet.fs +++ b/tests/FsSpreadsheet.Net.Tests/OpenXml/Sheet.fs @@ -1,6 +1,6 @@ -module Sheet +module Sheet.Tests -open Expecto +open TestingUtils open FsSpreadsheet.Net open DocumentFormat.OpenXml @@ -13,7 +13,6 @@ let shtsFox = wbFox.Sheets let shtssFox = shtsFox.Descendants() |> Array.ofSeq // array is needed since seqs cannot be compared -[] let sheetsTests = testList "Sheets" [ testList "get" [ @@ -26,4 +25,6 @@ let sheetsTests = let shtss = Sheet.Sheets.getSheets shtsFox |> Array.ofSeq // array is needed since seqs cannot be compared Expect.equal shtss shtssFox "Differs" ] - ] \ No newline at end of file + ] + +let main = sheetsTests \ No newline at end of file diff --git a/tests/FsSpreadsheet.Net.Tests/OpenXml/Spreadsheet.fs b/tests/FsSpreadsheet.Net.Tests/OpenXml/Spreadsheet.fs index ee38b81d..3f72e918 100644 --- a/tests/FsSpreadsheet.Net.Tests/OpenXml/Spreadsheet.fs +++ b/tests/FsSpreadsheet.Net.Tests/OpenXml/Spreadsheet.fs @@ -1,6 +1,6 @@ -module Spreadsheet +module Spreadsheet.Tests -open Expecto +open TestingUtils open FsSpreadsheet.Net open DocumentFormat.OpenXml @@ -36,9 +36,6 @@ let cbsi1Fox = // get the Cells, but with their real values (inferred from //testSsdFox = testDoc //testSsdFox = testSsdFox2 - - -[] let spreadsheetTests = testList "Spreadsheet" [ let ssd = Spreadsheet.fromFile testFilePath false @@ -90,5 +87,4 @@ let spreadsheetTests = - -//testSsdFox.Close() \ No newline at end of file +let main = spreadsheetTests diff --git a/tests/FsSpreadsheet.Net.Tests/OpenXml/Workbook.fs b/tests/FsSpreadsheet.Net.Tests/OpenXml/Workbook.fs index 45a1fc9e..fe2284b8 100644 --- a/tests/FsSpreadsheet.Net.Tests/OpenXml/Workbook.fs +++ b/tests/FsSpreadsheet.Net.Tests/OpenXml/Workbook.fs @@ -1,6 +1,6 @@ -module Workbook +module Workbook.Tests -open Expecto +open TestingUtils open FsSpreadsheet.Net open DocumentFormat.OpenXml @@ -11,7 +11,6 @@ let wbpFox = ssdFox.WorkbookPart let wbFox = wbpFox.Workbook -[] let workbookTests = testList "Workbook" [ testList "get" [ @@ -19,4 +18,6 @@ let workbookTests = let wb = Workbook.get wbpFox Expect.equal wb wbFox "Differs" ] - ] \ No newline at end of file + ] + +let main = workbookTests \ No newline at end of file diff --git a/tests/FsSpreadsheet.Net.Tests/Stylesheet.Tests.fs b/tests/FsSpreadsheet.Net.Tests/Stylesheet.Tests.fs index 760f8353..b59db0d3 100644 --- a/tests/FsSpreadsheet.Net.Tests/Stylesheet.Tests.fs +++ b/tests/FsSpreadsheet.Net.Tests/Stylesheet.Tests.fs @@ -1,11 +1,8 @@ module Stylesheet -open Expecto -open FsSpreadsheet +open TestingUtils open FsSpreadsheet.Net open DocumentFormat.OpenXml.Spreadsheet -open DocumentFormat.OpenXml.Packaging -open DocumentFormat.OpenXml let private tests_NumberingFormat = testList "NumberingFormat" [ testList "isDateTime" [ @@ -29,7 +26,6 @@ let private tests_NumberingFormat = testList "NumberingFormat" [ ] ] -[] let main = testList "Stylesheet" [ tests_NumberingFormat ] \ No newline at end of file diff --git a/tests/FsSpreadsheet.Net.Tests/Table.fs b/tests/FsSpreadsheet.Net.Tests/Table.fs index 783d3da5..f6b084f7 100644 --- a/tests/FsSpreadsheet.Net.Tests/Table.fs +++ b/tests/FsSpreadsheet.Net.Tests/Table.fs @@ -1,6 +1,5 @@ -module FsTable +module Table.Tests -open Expecto open FsSpreadsheet open FsSpreadsheet.Net open DocumentFormat.OpenXml @@ -31,7 +30,7 @@ let transformTable = // --- Function of interest --- - let bytes = wb.ToBytes() + let bytes = wb.ToXlsxBytes() // --- Get Tables --- @@ -69,7 +68,6 @@ let transformTable = ] -[] let main = testList "FsTable" [ transformTable diff --git a/tests/FsSpreadsheet.Net.Tests/ZipArchiveReader.fs b/tests/FsSpreadsheet.Net.Tests/ZipArchiveReader.fs index 23eb78ef..03a10240 100644 --- a/tests/FsSpreadsheet.Net.Tests/ZipArchiveReader.fs +++ b/tests/FsSpreadsheet.Net.Tests/ZipArchiveReader.fs @@ -7,9 +7,13 @@ open FsSpreadsheet.Net.ZipArchiveReader let tests_Read = testList "Read" [ let readFromTestFile (testFile: DefaultTestObject.TestFiles) = try - FsWorkbook.fromFile(testFile.asRelativePath) + let p = testFile.asRelativePath + FsWorkbook.fromXlsxFile(p) with - | _ -> FsWorkbook.fromFile($"{DefaultTestObject.testFolder}/{testFile.asFileName}") + | err -> + printfn "Could not read file from default path: %s" err.Message + let p = $"{DefaultTestObject.testFolder}/{testFile.asFileName}" + FsWorkbook.fromXlsxFile(p) testCase "FsCell equality" <| fun _ -> let c1 = FsCell(1, DataType.Number, FsAddress("A2")) @@ -37,15 +41,14 @@ let tests_Read = testList "Read" [ open FsSpreadsheet.Net let performanceTest = testList "Performance" [ - testCase "BigFile" <| fun _ -> - let readF() = FsWorkbook.fromFile("./TestFiles/BigFile.xlsx") |> ignore - let refReadF() = FsWorkbook.fromXlsxFile("./TestFiles/BigFile.xlsx") |> ignore + ptestCase "BigFile" <| fun _ -> + let readF() = FsWorkbook.fromXlsxFile(DefaultTestObject.BigFile.asRelativePath) |> ignore + let refReadF() = FsWorkbook.fromXlsxFile(DefaultTestObject.BigFile.asRelativePath) |> ignore Expect.isFasterThan readF refReadF "ZipArchiveReader should be faster than standard reader" //Expect.equal (wb.GetWorksheetAt(1).Rows.Count) 153991 "Row count should be equal" ] -[] let main = testList "ZipArchiveReader" [ performanceTest tests_Read diff --git a/tests/FsSpreadsheet.Py.Tests/DefaultIO.Tests.fs b/tests/FsSpreadsheet.Py.Tests/DefaultIO.Tests.fs index fd1b3f4a..ebe5a6c9 100644 --- a/tests/FsSpreadsheet.Py.Tests/DefaultIO.Tests.fs +++ b/tests/FsSpreadsheet.Py.Tests/DefaultIO.Tests.fs @@ -41,7 +41,7 @@ let private tests_Write = testList "Write" [ testCase "default" <| fun _ -> let wb = DefaultTestObject.defaultTestObject() let p = DefaultTestObject.WriteTestFiles.FsSpreadsheetPY.asRelativePathNode - do FsWorkbook.toFile p wb + do FsWorkbook.toXlsxFile p wb let wb_read = FsWorkbook.fromXlsxFile p Expect.isDefaultTestObject wb_read diff --git a/tests/FsSpreadsheet.Py.Tests/FsSpreadsheet.Py.Tests.fsproj b/tests/FsSpreadsheet.Py.Tests/FsSpreadsheet.Py.Tests.fsproj index a96bc3e3..5cb5e563 100644 --- a/tests/FsSpreadsheet.Py.Tests/FsSpreadsheet.Py.Tests.fsproj +++ b/tests/FsSpreadsheet.Py.Tests/FsSpreadsheet.Py.Tests.fsproj @@ -12,6 +12,7 @@ + diff --git a/tests/FsSpreadsheet.Py.Tests/Json.Tests.fs b/tests/FsSpreadsheet.Py.Tests/Json.Tests.fs new file mode 100644 index 00000000..9880c451 --- /dev/null +++ b/tests/FsSpreadsheet.Py.Tests/Json.Tests.fs @@ -0,0 +1,22 @@ +module Json.Tests + +open FsSpreadsheet +open FsSpreadsheet.Py +open Fable.Pyxpecto + +let defaultTestObject = + testList "defaultTestObject" [ + + testCase "Read-Write DefaultTestObject" <| fun _ -> + let dto = DefaultTestObject.defaultTestObject() + let s = dto.ToJsonString() + let dto2 = FsWorkbook.fromJsonString(s) + TestingUtils.Expect.isDefaultTestObject dto2 + + //testCase "Should Fail" <| fun _ -> + // Expect.isTrue false "is not the expected DataType.Boolean" + ] + +let main = testList "Json" [ + defaultTestObject +] \ No newline at end of file diff --git a/tests/FsSpreadsheet.Py.Tests/Main.fs b/tests/FsSpreadsheet.Py.Tests/Main.fs index 8e2f2893..e3466f53 100644 --- a/tests/FsSpreadsheet.Py.Tests/Main.fs +++ b/tests/FsSpreadsheet.Py.Tests/Main.fs @@ -11,6 +11,7 @@ let all = Worksheet.Tests.main Workbook.Tests.main DefaultIO.Tests.main + Json.Tests.main ] //// This is possibly the most magic used to make this work. diff --git a/tests/JS/Exceljs.js b/tests/JS/Exceljs.js index 5f0e0330..2af82b54 100644 --- a/tests/JS/Exceljs.js +++ b/tests/JS/Exceljs.js @@ -97,7 +97,7 @@ describe('FsSpreadsheet.Js', function () { const table = new FsTable("MyNewTable", FsRangeAddress_$ctor_Z721C83C5("B1:D3")); fsws.AddTable(table); fsws.RescanRows() - await Xlsx.toFile(path, fswb) + await Xlsx.toXlsxFile(path, fswb) const readfswb = await Xlsx.fromXlsxFile(path) equal(readfswb.GetWorksheets().length, fswb.GetWorksheets().length) equal(readfswb.GetWorksheets()[0].Name, "My Awesome Worksheet") @@ -121,7 +121,7 @@ describe('FsSpreadsheet.Js', function () { equal(table.Name, "annotationTableStupidQuail41", "table.Name") equal(table.ShowHeaderRow, true, "table.ShowHeaderRow") // issue #69 const outoutPath = "tests/JS/TestFiles/WRITE_TestAssayExcel.xlsx" - await Xlsx.toFile(outoutPath, fswb) + await Xlsx.toXlsxFile(outoutPath, fswb) const fswb2 = await Xlsx.fromXlsxFile(outoutPath) equal(fswb2.GetWorksheets().length, 5) // test correct read }) diff --git a/tests/Speedtest/Program.fs b/tests/Speedtest/Program.fs index 5c3d005d..0ef75a95 100644 --- a/tests/Speedtest/Program.fs +++ b/tests/Speedtest/Program.fs @@ -24,10 +24,10 @@ let main argv = let zipArchiveReader() = - let readAssay() = ZipArchiveReader.FsWorkbook.fromFile assayPath - let readStudy() = ZipArchiveReader.FsWorkbook.fromFile studyPath - let readInvestigation() = ZipArchiveReader.FsWorkbook.fromFile investigationPath - let bigFile() = ZipArchiveReader.FsWorkbook.fromFile @"C:\Users\HLWei\source\repos\IO\FsSpreadsheet\tests\TestUtils\TestFiles\BigFile.xlsx" + let readAssay() = ZipArchiveReader.FsWorkbook.fromXlsxFile assayPath + let readStudy() = ZipArchiveReader.FsWorkbook.fromXlsxFile studyPath + let readInvestigation() = ZipArchiveReader.FsWorkbook.fromXlsxFile investigationPath + let bigFile() = ZipArchiveReader.FsWorkbook.fromXlsxFile @"C:\Users\HLWei\source\repos\IO\FsSpreadsheet\tests\TestUtils\TestFiles\BigFile.xlsx" readInvestigation() |> ignore diff --git a/tests/TestUtils/DefaultTestObjects.fs b/tests/TestUtils/DefaultTestObjects.fs index d76fbf23..9fd27e9b 100644 --- a/tests/TestUtils/DefaultTestObjects.fs +++ b/tests/TestUtils/DefaultTestObjects.fs @@ -35,14 +35,16 @@ type WriteTestFiles = | FsSpreadsheetNET | FsSpreadsheetJS | FsSpreadsheetPY +| FsSpreadsheetJSON member this.asFileName = match this with + | FsSpreadsheetJSON -> "TestWorkbook_FsSpreadsheet_WRITE.json" | FsSpreadsheetNET -> "TestWorkbook_FsSpreadsheet_WRITE.net.xlsx" | FsSpreadsheetJS -> "TestWorkbook_FsSpreadsheet_WRITE.js.xlsx" | FsSpreadsheetPY -> "TestWorkbook_FsSpreadsheet_WRITE.py.xlsx" - member this.asRelativePath = $"{testFolder}/{this.asFileName}" + member this.asRelativePath = $"../TestUtils/{testFolder}/{this.asFileName}" member this.asRelativePathNode = $"./tests/TestUtils/{testFolder}/{this.asFileName}" module ExpectedRows =