Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#63 Add FsColumn functionality #64

Merged
merged 6 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,20 @@
### 3.4.0+39d270a (Released 2023-8-11)
### 4.0.0+5d5067f (Released 2023-8-11)
* Additions:
* [[#19bd2a8](https://github.com/CSBiology/FsSpreadsheet/commit/19bd2a8817940d4f8725a85ebfa595faa214a24d)] Add `MinRowIndex` and `MinColIndex` to FsColumn
* [[#5c2e616](https://github.com/CSBiology/FsSpreadsheet/commit/5c2e6167c3c0ea9bfd6ae4a59de60485325a31ab)] Add `HasCellAt` to FsColumn
* [[#3e7b7d2](https://github.com/CSBiology/FsSpreadsheet/commit/3e7b7d2c76a7ab1b72c13dd20983b975cb8b1308)] Add `TryItem` functionality to FsColumn
* [[#5d5067f](https://github.com/CSBiology/FsSpreadsheet/commit/5d5067f81459164c72e6abf7db1c94b7b494d1ee)] Add dense column functionality
* [[#ac14e0d](https://github.com/CSBiology/FsSpreadsheet/commit/ac14e0d2b8df599aa83e0c93326553f4bb2c2d79)] Add unit tests for column index getting and base cells in FsRow
* [[#36b2b16](https://github.com/CSBiology/FsSpreadsheet/commit/36b2b163e17a944da64f04074e539cc7cd687b0c)] Add tests for FsRow
* [[#05f19ae](https://github.com/CSBiology/FsSpreadsheet/commit/05f19ae60db21031fb0ee527ef94431d199bee6e)] Add `GetRowCount` functionality to FsRangeBase
* [[#aa4938c](https://github.com/CSBiology/FsSpreadsheet/commit/aa4938cb7dff34e84cf4d15d7325fd60ed1ebd85)] Add `GetRows` functionality to FsTable
* [[#2a29cfe](https://github.com/CSBiology/FsSpreadsheet/commit/2a29cfe16f4360ad0f0fbb213ccc0abcbb653087)] Add FsRow members: `TryItem`, `ToDenseRow`, `HasCellAt`, `MinColIndex`, `MaxColIndex`
* Bugfixes:
* [[#2b3b30b](https://github.com/CSBiology/FsSpreadsheet/commit/2b3b30b30a03ef821668ab6a011368662622b564)] Fix critical JS bug in column index getting

### 3.3.0+ec1b7c9 (Released 2023-8-3)
* Additions:
* [[#c228e7f](https://github.com/CSBiology/FsSpreadsheet/commit/c228e7f3799d87d34e44fb96500fe4f360d6454e)] Change npm dependency to exceljs fork
* [[#c228e7f](https://github.com/CSBiology/FsSpreadsheet/commit/c228e7f3799d87d34e44fb96500fe4f360d6454e)] Change npm dependency to exceljs fork
* [[#5625b33](https://github.com/CSBiology/FsSpreadsheet/commit/5625b3310a5918a5396d49a7bef1e6654d50d295)] Update more tests
* [[#4378808](https://github.com/CSBiology/FsSpreadsheet/commit/4378808c13d3250b90ac2311fd127b999498b2c4)] Update gitignore
* Deletions:
* [[#7779011](https://github.com/CSBiology/FsSpreadsheet/commit/77790114c7d652e818ab1c9492f730ce573c47b3)] delete dist
* Bugfixes:
* [[#d14448e](https://github.com/CSBiology/FsSpreadsheet/commit/d14448e093ffe8268a2445d31f2aeeccf6a79fc1)] Fix Async/Promises and fsspreadsheet readin :tada:
* [[#a96bcd0](https://github.com/CSBiology/FsSpreadsheet/commit/a96bcd0082dab203a7fdbed7ba12e96e21203f33)] fix timeout issue :bug:

### 3.2.1+caf21db (Released 2023-8-1)
* Additions:
* [[#cb35186](https://github.com/CSBiology/FsSpreadsheet/commit/cb3518609e9fe42e05789441906dc148a4b8d53e)] Update and clean up RELEASE_NOTES.md
* [[#489f6b7](https://github.com/CSBiology/FsSpreadsheet/commit/489f6b77789cca13840382d5c2dd03dc973b65df)] Add logo to Exceljs project file
* [[#caf21db](https://github.com/CSBiology/FsSpreadsheet/commit/caf21db25490908a61381fd229fdaf5cc9a66ab2)] INcrease package.json version together with fake task.

### 3.2.0+e47262b (Released 2023-7-31)
* Additions:
* [[#2b9c7fa](https://github.com/CSBiology/FsSpreadsheet/commit/2b9c7fa2c3fccfb6a5956b2e244a557fda4e0793)] Add some tests for exceljs
* [[#1fd0e34](https://github.com/CSBiology/FsSpreadsheet/commit/1fd0e34fafc9e82f0a509af9a4d1579a4ea458d5)] Add fable necessities to fsproj.
* [[#72bb41e](https://github.com/CSBiology/FsSpreadsheet/commit/72bb41ea6b8ad2c5490619af35a4d9038f0700da)] Write some tests #54
Expand All @@ -43,10 +31,14 @@
* [[#3116aae](https://github.com/CSBiology/FsSpreadsheet/commit/3116aae6831fddcccc552d9d68b1bf4a565578ec)] Add dotnet tool femto
* [[#eb7160d](https://github.com/CSBiology/FsSpreadsheet/commit/eb7160d105d3d3fbabaea36abdc085412e173d75)] Update .gitignore
* Deletions:
* [[#7779011](https://github.com/CSBiology/FsSpreadsheet/commit/77790114c7d652e818ab1c9492f730ce573c47b3)] delete dist
* [[#2253fb1](https://github.com/CSBiology/FsSpreadsheet/commit/2253fb1ef938754f8135d18949252d991ec1af32)] Remove some js tests until fsspreadsheet syntax better fits js.
* [[#146d920](https://github.com/CSBiology/FsSpreadsheet/commit/146d9205a549e6ccbf0b317a52fe56ea63e08bfc)] Delete .zip :fire:
* [[#6b3a27b](https://github.com/CSBiology/FsSpreadsheet/commit/6b3a27bf8db2ee6b23c2dacce8466ea22bcda9b4)] remove annoying warning
* Bugfixes:
* [[#2b3b30b](https://github.com/CSBiology/FsSpreadsheet/commit/2b3b30b30a03ef821668ab6a011368662622b564)] Fix critical JS bug in column index getting
* [[#d14448e](https://github.com/CSBiology/FsSpreadsheet/commit/d14448e093ffe8268a2445d31f2aeeccf6a79fc1)] Fix Async/Promises and fsspreadsheet readin :tada:
* [[#a96bcd0](https://github.com/CSBiology/FsSpreadsheet/commit/a96bcd0082dab203a7fdbed7ba12e96e21203f33)] fix timeout issue :bug:
* [[#a680d45](https://github.com/CSBiology/FsSpreadsheet/commit/a680d45f9a7b985d61fa9887fd984e32024faf9a)] fix xlsxparser picking the wrong name fix teststrings
* [[#5293ae9](https://github.com/CSBiology/FsSpreadsheet/commit/5293ae92184f4dc4038076761cd65beb3e243aba)] hotfix table not written correctly #49
* [[#53b109c](https://github.com/CSBiology/FsSpreadsheet/commit/53b109cf42b9fba59c55011d2eb45fa39132b9c2)] fix datatypes in fs->js conversion + finish tests
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fsspreadsheet",
"version": "3.4.0+39d270a",
"version": "4.0.0+5d5067f",
"description": "Minimal spreadsheet creation and manipulation using exceljs io.",
"type": "module",
"main": "dist/Xlsx.js",
Expand Down
100 changes: 86 additions & 14 deletions src/FsSpreadsheet/FsColumn.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
// ----------

/// Creates an empty FsColumn, ranging from row 0, column 0 to row 0, column (1-based).
static member empty() = FsColumn (FsRangeAddress(FsAddress(0,0),FsAddress(0,0)),FsCellsCollection())
static member empty() = FsColumn (FsRangeAddress(FsAddress(0,0), FsAddress(0,0)), FsCellsCollection())

/// <summary>
/// Create an FsColumn from a given FsCellsCollection and an columnColumn.
Expand All @@ -39,7 +39,7 @@
).Address.RowNumber
let minRowIndex = getIndexBy Seq.minBy
let maxRowIndex = getIndexBy Seq.maxBy
FsColumn (FsRangeAddress(FsAddress(minRowIndex, index),FsAddress(maxRowIndex, index)), cells)
FsColumn (FsRangeAddress(FsAddress(minRowIndex, index), FsAddress(maxRowIndex, index)), cells)

interface IEnumerable<FsCell> with
member this.GetEnumerator() : System.Collections.Generic.IEnumerator<FsCell> = this.Cells.GetEnumerator()
Expand All @@ -52,29 +52,41 @@
// ----------

/// The associated FsCells.
member self.Cells =
member this.Cells =
base.Cells(cells)

/// <summary>
/// The index of the FsColumn.
/// </summary>
member self.Index
with get() = self.RangeAddress.FirstAddress.ColumnNumber
member this.Index
with get() = this.RangeAddress.FirstAddress.ColumnNumber
and set(i) =
self.RangeAddress.FirstAddress.ColumnNumber <- i
self.RangeAddress.LastAddress.ColumnNumber <- i
this.RangeAddress.FirstAddress.ColumnNumber <- i
this.RangeAddress.LastAddress.ColumnNumber <- i

/// <summary>
/// The number of the lowest row index of the FsColumn where an FsCell exists.
/// </summary>
member this.MinRowIndex
with get() = this.RangeAddress.FirstAddress.RowNumber

/// <summary>
/// The number of the highest row index of the FsColumn where an FsCell exists.
/// </summary>
member this.MaxRowIndex
with get() = this.RangeAddress.LastAddress.RowNumber


// -------
// METHODS
// -------

/// <summary>
/// Creates a deep copy of this FsRow.
/// Creates a deep copy of this FsColumn.
/// </summary>
member self.Copy() =
let ra = self.RangeAddress.Copy()
let cells = self.Cells |> Seq.map (fun c -> c.Copy())
member this.Copy() =
let ra = this.RangeAddress.Copy()
let cells = this.Cells |> Seq.map (fun c -> c.Copy())
let fcc = FsCellsCollection()
fcc.Add cells
FsColumn(ra, fcc)
Expand All @@ -90,20 +102,50 @@
/// </summary>
static member getIndex (column : FsColumn) =
column.Index


/// <summary>
/// Checks if there is an FsCell at given row index.
/// </summary>
/// <param name="rowIndex">The number of the row where the presence of an FsCell shall be checked.</param>
member this.HasCellAt(rowIndex) =
this.Cells
|> Seq.exists (fun c -> c.RowNumber = rowIndex)

/// <summary>

Check warning on line 114 in src/FsSpreadsheet/FsColumn.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This XML comment is invalid: unknown parameter 'colIndex'

Check warning on line 114 in src/FsSpreadsheet/FsColumn.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This XML comment is incomplete: no documentation for parameter 'rowIndex'

Check warning on line 114 in src/FsSpreadsheet/FsColumn.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This XML comment is invalid: unknown parameter 'colIndex'

Check warning on line 114 in src/FsSpreadsheet/FsColumn.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This XML comment is incomplete: no documentation for parameter 'rowIndex'
/// Checks if there is an FsCell at given row index of a given FsColumn.
/// </summary>
/// <param name="colIndex">The number of the row where the presence of an FsCell shall be checked.</param>
static member hasCellAt rowIndex (column : FsColumn) =
column.HasCellAt rowIndex

/// <summary>
/// Returns the FsCell at rowIndex.
/// </summary>
member this.Item (rowIndex) =
// use FsRangeBase call with colindex 1
base.Cell(FsAddress(rowIndex,1),cells)
base.Cell(FsAddress(rowIndex, 1), cells)

/// <summary>
/// Returns the FsCell at the given rowIndex from an FsColumn.
/// </summary>
static member item rowIndex (column : FsColumn) =
column.Item(rowIndex)

/// <summary>
/// Returns the FsCell at the given rowIndex if it exists. Else returns None.
/// </summary>
/// <param name="rowIndex">The number of the column where the FsCell shall be retrieved.</param>
member this.TryItem(rowIndex) =
if this.HasCellAt rowIndex then Some this[rowIndex]
else None

/// <summary>
/// Returns the FsCell at the given rowIndex if it exists in the given FsColumn. Else returns None.
/// </summary>
/// <param name="rowIndex">The number of the column where the FsCell shall be retrieved.</param>
static member tryItem rowIndex (column : FsColumn) =
column.TryItem rowIndex

///// <summary>
///// Inserts the value at columnIndex as an FsCell. If there is an FsCell at the position, this FsCells and all the ones /right /to it are shifted to the right.
///// </summary>
Expand All @@ -120,9 +162,39 @@
// row.InsertValueAt(colIndex, value) |> ignore
// row

//member self.SortCells() = _cells <- _cells |> List.sortBy (fun c -> c.WorksheetColumn)
//member this.SortCells() = _cells <- _cells |> List.sortBy (fun c -> c.WorksheetColumn)

// TO DO (later)
///// Takes an FsCellsCollection and creates an FsRow from the given rowIndex and the cells in the FsCellsCollection that share the same rowIndex.
//static member fromCellsCollection rowIndex (cellsCollection : FsCellsCollection) =

/// <summary>
/// Transforms the FsColumn into a dense FsColumn.
///
/// FsColumns are sparse by default. This means there are no FsCells present between positions with that are filled with FsCells. In dense FsColumns, such "empty positions" are then filled with empty FsCells.
/// </summary>
member this.ToDenseColumn() =
for i = this.MinRowIndex to this.MaxRowIndex do
ignore this[i]

/// <summary>
/// Transforms the given FsColumn into a dense FsColumn.
///
/// FsColumns are sparse by default. This means there are no FsCells present between positions with that are filled with FsCells. In dense FsColumns, such "empty positions" are then filled with empty FsCells.
/// </summary>
/// <param name="column">The FsColumn that gets transformed into a dense FsColumn.</param>
/// <remarks>This is an in-place operation.</remarks>
static member toDenseColumn (column : FsColumn) =
column.ToDenseColumn()
column

/// <summary>
/// Takes a given FsColumn and returns a new dense FsColumn from it.
///
/// FsColumns are sparse by default. This means there are no FsCells present between positions with that are filled with FsCells. In dense FsColumns, such "empty positions" are then filled with empty FsCells.
/// </summary>
/// <param name="column">The FsColumn that whose copy gets transformed into a dense FsColumn.</param>
static member createDenseColumnOf (column : FsColumn) =
let newColumn = column.Copy()
newColumn.ToDenseColumn()
newColumn
8 changes: 4 additions & 4 deletions src/FsSpreadsheet/FsRow.fs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
// Creation
// ----------

static member empty() = FsRow (FsRangeAddress(FsAddress(0,0),FsAddress(0,0)),FsCellsCollection())
static member empty() = FsRow (FsRangeAddress(FsAddress(0,0), FsAddress(0,0)), FsCellsCollection())

/// <summary>
/// Creates an FsRow from a given FsCellsCollection and an rowIndex.
Expand All @@ -41,7 +41,7 @@
).Address.ColumnNumber
let minColIndex = getIndexBy Seq.minBy
let maxColIndex = getIndexBy Seq.maxBy
FsRow (FsRangeAddress(FsAddress(index, minColIndex),FsAddress(index, maxColIndex)), cells)
FsRow (FsRangeAddress(FsAddress(index, minColIndex), FsAddress(index, maxColIndex)), cells)

interface IEnumerable<FsCell> with
member this.GetEnumerator() : System.Collections.Generic.IEnumerator<FsCell> = this.Cells.GetEnumerator()
Expand Down Expand Up @@ -125,7 +125,7 @@
/// </summary>
member this.Item(columnIndex) =
// use FsRangeBase call with colindex 1
base.Cell(FsAddress(1,columnIndex),cells)
base.Cell(FsAddress(1, columnIndex), cells)

/// <summary>
/// Returns the FsCell at the given columnIndex from an FsRow if it exists. Else creates an ampty FsCell at that position.
Expand All @@ -141,11 +141,11 @@
if this.HasCellAt colIndex then Some this[colIndex]
else None

/// <summary>

Check warning on line 144 in src/FsSpreadsheet/FsRow.fs

View workflow job for this annotation

GitHub Actions / build-and-test-windows

This XML comment is incomplete: no documentation for parameter 'row'

Check warning on line 144 in src/FsSpreadsheet/FsRow.fs

View workflow job for this annotation

GitHub Actions / build-and-test-linux

This XML comment is incomplete: no documentation for parameter 'row'
/// Returns the FsCell at the given columnIndex if it exists in the given FsRow. Else returns None.
/// </summary>
/// <param name="colIndex">The number of the column where the FsCell shall be retrieved.</param>
static member tryItem colIndex (row: FsRow) =
static member tryItem colIndex (row : FsRow) =
row.TryItem colIndex

/// <summary>
Expand Down
38 changes: 38 additions & 0 deletions tests/FsSpreadsheet.Tests/FsColumnTests.fs
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,42 @@ let main =
let expectedValues = ["Name";"John Doe";"Jane Doe";"Jack Doe"]
Expect.mySequenceEqual (Seq.item 0 columns |> Seq.map FsCell.getValueAsString) expectedValues "Values are not correct"
]
testList "ToDenseColumn" [
testCase "is correct" (fun _ ->
let cellsCollWithEmpty = FsCellsCollection()
cellsCollWithEmpty.Add [
FsCell.create 1 1 "Kevin"
FsCell.createEmptyWithAdress(FsAddress("A2"))
FsCell.create 3 1 "Schneider"
]
let column = FsColumn(FsRangeAddress("A1:A3"), cellsCollWithEmpty)
let actual = FsColumn.toDenseColumn column |> Seq.map FsCell.getValueAsString |> Seq.toList
let expected = ["Kevin"; ""; "Schneider"]
Expect.mySequenceEqual actual expected "Column values differ"
)
]
testList "Base.Cells" [
testCase "can be retrieved" <| fun _ ->
let cellsColl = FsCellsCollection()
cellsColl.Add (FsCell.create 1 1 "Kevin")
let column = FsColumn(FsRangeAddress("A1:A1"), cellsColl)
let firstCell = column.Cells |> Seq.head
Expect.equal (FsCell.getValueAsString firstCell) "Kevin" "Did not retrieve"
]
testList "MinColIndex" [
testCase "can be retrieved" <| fun _ ->
let cellsColl = FsCellsCollection()
cellsColl.Add (FsCell.create 1 1 "Kevin")
let column = FsColumn(FsRangeAddress("A1:A1"), cellsColl)
let minRowIndex = column.MinRowIndex
Expect.equal minRowIndex 1 "Incorrect index"
]
testList "MaxColIndex" [
testCase "can be retrieved" <| fun _ ->
let cellsColl = FsCellsCollection()
cellsColl.Add (FsCell.create 1 1 "Kevin")
let column = FsColumn(FsRangeAddress("A1:A1"), cellsColl)
let maxRowIndex = column.MaxRowIndex
Expect.equal maxRowIndex 1 "Incorrect index"
]
]
Loading