Skip to content

Commit

Permalink
Merge pull request #40 from CSBiology/xlsxlIOfix
Browse files Browse the repository at this point in the history
test and fix writeAndReadSpreadsheet
  • Loading branch information
HLWeil authored Jul 19, 2023
2 parents fc07f3a + d6f86d2 commit 0d7e699
Show file tree
Hide file tree
Showing 13 changed files with 145 additions and 20 deletions.
18 changes: 14 additions & 4 deletions src/FsSpreadsheet.ExcelIO/FsExtensions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,14 @@ module FsExtensions =
member self.FromXlsxStream (stream : Stream) =
let doc = Spreadsheet.fromStream stream false
let sst = Spreadsheet.tryGetSharedStringTable doc
let xlsxWorkbookPart = Spreadsheet.getWorkbookPart doc
let xlsxWorkbook = Workbook.get xlsxWorkbookPart
let xlsxWorkbookPart = Spreadsheet.getWorkbookPart doc
let xlsxSheets =
Sheet.Sheets.get xlsxWorkbook
|> Sheet.Sheets.getSheets
try
let xlsxWorkbook = Workbook.get xlsxWorkbookPart
Sheet.Sheets.get xlsxWorkbook
|> Sheet.Sheets.getSheets
with
| _ -> []
let xlsxWorksheetParts =
xlsxSheets
|> Seq.map (
Expand Down Expand Up @@ -211,6 +214,13 @@ module FsExtensions =
static member fromXlsxStream (stream : Stream) =
(new FsWorkbook()).FromXlsxStream stream

/// <summary>
/// Creates an FsWorkbook from a given Stream to an XlsxFile.
/// </summary>
static member fromBytes (bytes : byte []) =
let stream = new MemoryStream(bytes)
(new FsWorkbook()).FromXlsxStream stream

/// <summary>
/// Takes the path to an Xlsx file and returns the FsWorkbook based on its content.
/// </summary>
Expand Down
7 changes: 5 additions & 2 deletions src/FsSpreadsheet.ExcelIO/Spreadsheet.fs
Original file line number Diff line number Diff line change
Expand Up @@ -195,15 +195,18 @@ module Spreadsheet =
let getCellsBySheet (sheet : Sheet) (spreadsheetDocument : SpreadsheetDocument) =
let workbookPart = spreadsheetDocument.WorkbookPart
let worksheetPart = Worksheet.WorksheetPart.getByID sheet.Id.Value workbookPart
let stringTablePart = getOrInitSharedStringTablePart spreadsheetDocument
let includeSSV =
match tryGetSharedStringTable spreadsheetDocument with
| Some sst -> Cell.includeSharedStringValue sst
| None -> id
seq {
use reader = OpenXmlReader.Create(worksheetPart)

while reader.Read() do
if (reader.ElementType = typeof<Cell>) then
let cell = reader.LoadCurrentElement() :?> Cell
let cellRef = if cell.CellReference.HasValue then cell.CellReference.Value else ""
yield Cell.includeSharedStringValue stringTablePart.SharedStringTable cell
yield includeSSV cell
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions src/FsSpreadsheet/FsWorkbook.fs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ type FsWorkbook() =
member self.InitWorksheet(name : string) =
let sheet = FsWorksheet name
_worksheets <- List.append _worksheets [sheet]
sheet

/// <summary>
/// Creates an empty FsWorksheet with given name and adds it to the FsWorkbook.
/// </summary>
static member initWorksheet (name : string) (workbook : FsWorkbook) =
workbook.InitWorksheet name
workbook



/// <summary>
/// Adds a given FsWorksheet to the FsWorkbook.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="FsExtensions.fs" />
<Compile Include="Cell.fs" />
<Compile Include="Sheet.fs" />
<Compile Include="Workbook.fs" />
<Compile Include="Spreadsheet.fs" />
<Compile Include="Utils.fs" />
<Compile Include="TestObjects.fs" />
<Compile Include="OpenXml\FsExtensions.fs" />
<Compile Include="OpenXml\Cell.fs" />
<Compile Include="OpenXml\Sheet.fs" />
<Compile Include="OpenXml\Workbook.fs" />
<Compile Include="OpenXml\Spreadsheet.fs" />
<Compile Include="FsWorkbook.fs" />
<Compile Include="Main.fs" />
</ItemGroup>

Expand All @@ -25,5 +28,4 @@
<ItemGroup>
<PackageReference Update="FSharp.Core" Version="7.0.300" />
</ItemGroup>

</Project>
44 changes: 44 additions & 0 deletions tests/FsSpreadsheet.ExcelIO.Tests/FsWorkbook.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
module FsWorkbook

open Expecto
open FsSpreadsheet
open FsSpreadsheet.ExcelIO

open TestingUtils

let writeAndReadBytes =
testList "WriteAndReadBytes" [
testCase "Empty" (fun () ->
let wb = new FsWorkbook()
let bytes = wb.ToBytes()
let wb2 = FsWorkbook.fromBytes(bytes)
Expect.equal (wb.GetWorksheets() |> List.length) (wb2.GetWorksheets() |> List.length) "Worksheet count should be equal"
)
testCase "SingleWorksheet" (fun () ->
let wb = new FsWorkbook()
let ws = TestObjects.sheet1()
wb.AddWorksheet(ws)
let bytes = wb.ToBytes()
let wb2 = FsWorkbook.fromBytes(bytes)
Expect.equal (wb.GetWorksheets() |> List.length) (wb2.GetWorksheets() |> List.length) "Worksheet count should be equal"
Expect.workSheetEqual (wb.GetWorksheetByName(TestObjects.sheet1Name)) (wb2.GetWorksheetByName(TestObjects.sheet1Name)) "Worksheet did not match"
)
testCase "MultipleWorksheets" (fun () ->
let wb = new FsWorkbook()
wb.AddWorksheet(TestObjects.sheet1())
wb.AddWorksheet(TestObjects.sheet2())
let bytes = wb.ToBytes()
let wb2 = FsWorkbook.fromBytes(bytes)
Expect.equal (wb.GetWorksheets() |> List.length) (wb2.GetWorksheets() |> List.length) "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"
)
]



[<Tests>]
let tests =
testList "FsWorkbook" [
writeAndReadBytes
]
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ open FsSpreadsheet.ExcelIO
open DocumentFormat.OpenXml


let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "data", "testUnit.xlsx")
let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "../data", "testUnit.xlsx")
// *fox = from OpenXml, to distinguish between objects from FsSpreadsheet.ExcelIO
let ssdFox = Packaging.SpreadsheetDocument.Open(testFilePath, false)
let wbpFox = ssdFox.WorkbookPart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ let dummyDtEmpty = DataType.Empty
let dummyXlsxCell = Cell.create CellValues.Number "A1" (CellValue(1.337))

//let testFilePath = @"C:\Repos\CSBiology\FsSpreadsheet\tests\FsSpreadsheet.ExcelIO.Tests\data\testUnit.xlsx"
let testFilePath = Path.Combine(__SOURCE_DIRECTORY__, "data", "testUnit.xlsx")
let testFilePath = Path.Combine(__SOURCE_DIRECTORY__, "../data", "testUnit.xlsx")
let sr = new StreamReader(testFilePath)
let dummyFsWorkbook = new FsWorkbook()
let dummyFsCells = [
Expand Down Expand Up @@ -47,7 +47,7 @@ dummyFsWorkbook.AddWorksheet(dummyFsWorksheet3) |> ignore
dummyFsWorkbook.AddWorksheet(dummyFsWorksheet4) |> ignore

//let testFile2Path = @"C:\Repos\CSBiology\FsSpreadsheet\tests\FsSpreadsheet.ExcelIO.Tests\data\2EXT02_Protein.xlsx"
let testFile2Path = Path.Combine(__SOURCE_DIRECTORY__, "data", "2EXT02_Protein.xlsx")
let testFile2Path = Path.Combine(__SOURCE_DIRECTORY__, "../data", "2EXT02_Protein.xlsx")


[<Tests>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ open Expecto
open FsSpreadsheet.ExcelIO
open DocumentFormat.OpenXml

let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "data", "testUnit.xlsx")
let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "../data", "testUnit.xlsx")
// *fox = from OpenXml, to distinguish between objects from FsSpreadsheet.ExcelIO
let ssdFox = Packaging.SpreadsheetDocument.Open(testFilePath, false)
let wbpFox = ssdFox.WorkbookPart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ open FsSpreadsheet.ExcelIO
open DocumentFormat.OpenXml


let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "data", "testUnit.xlsx")
let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "../data", "testUnit.xlsx")
// *fox = from OpenXml, to distinguish between objects from FsSpreadsheet.ExcelIO
let ssdFox = Packaging.SpreadsheetDocument.Open(testFilePath, false)
let wbpFox = ssdFox.WorkbookPart
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ open Expecto
open FsSpreadsheet.ExcelIO
open DocumentFormat.OpenXml

let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "data", "testUnit.xlsx")
let testFilePath = System.IO.Path.Combine(__SOURCE_DIRECTORY__, "../data", "testUnit.xlsx")
// *fox = from OpenXml, to distinguish between objects from FsSpreadsheet.ExcelIO
let ssdFox = Packaging.SpreadsheetDocument.Open(testFilePath, false)
let wbpFox = ssdFox.WorkbookPart
Expand Down
40 changes: 40 additions & 0 deletions tests/FsSpreadsheet.ExcelIO.Tests/TestObjects.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module TestObjects

open FsSpreadsheet

let sheet1Name = "Sheet1"
let sheet2Name = "Sheet2"

let sheet1() =
let ws = new FsWorksheet(sheet1Name)
[
FsCell.createWithDataType DataType.String 1 1 "A1"
FsCell.createWithDataType DataType.String 1 2 "B1"
FsCell.createWithDataType DataType.String 1 3 "C1"

FsCell.createWithDataType DataType.String 2 1 "A2"
FsCell.createWithDataType DataType.String 2 2 "B2"
FsCell.createWithDataType DataType.String 2 3 "C2"

FsCell.createWithDataType DataType.String 3 1 "A3"
FsCell.createWithDataType DataType.String 3 2 "B3"
FsCell.createWithDataType DataType.String 3 3 "C3"
]
|> List.iter (fun c -> ws.Row(c.RowNumber).[c.ColumnNumber].SetValueAs c.Value)
ws

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 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
21 changes: 21 additions & 0 deletions tests/FsSpreadsheet.ExcelIO.Tests/Utils.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module TestingUtils

open FsSpreadsheet
open Expecto

module Expect =

let workSheetEqual (actual : FsWorksheet) (expected : FsWorksheet) message =
let f (ws : FsWorksheet) =
ws.RescanRows()
ws.Rows
|> Seq.map (fun r -> r.Cells |> Seq.map (fun c -> c.Value) |> Seq.reduce (fun a b -> a + b))
if actual.Name <> expected.Name then
failwithf $"{message}. Worksheet names do not match. Expected {expected.Name} but got {actual.Name}"
Expect.sequenceEqual (f actual) (f expected) $"{message}. Worksheet does not match"

let columnsEqual (actual : FsCell seq seq) (expected : FsCell seq seq) message =
let f (cols : FsCell seq seq) =
cols
|> Seq.map (fun r -> r |> Seq.map (fun c -> c.Value) |> Seq.reduce (fun a b -> a + b))
Expect.sequenceEqual (f actual) (f expected) $"{message}. Columns do not match"
5 changes: 5 additions & 0 deletions tests/FsSpreadsheet.Tests/FsWorkbook.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ dummyWorksheet2.AddTable dummyTables[1] |> ignore

let main =
testList "FsWorkbook" [
testList "GetWorksheets" [
testCase "empty" <| fun _ ->
let wb = new FsWorkbook()
Expect.equal 0 (wb.GetWorksheets().Length) "Should be empty"
]
testList "TryGetWorksheetByName" [
let testWorksheet = dummyWorkbook.TryGetWorksheetByName "dummyWorksheet1"
testCase "is Some" <| fun _ ->
Expand Down

0 comments on commit 0d7e699

Please sign in to comment.