diff --git a/FsSpreadsheet.sln b/FsSpreadsheet.sln index 7977c049..f1c802f7 100644 --- a/FsSpreadsheet.sln +++ b/FsSpreadsheet.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30907.101 +# Visual Studio Version 17 +VisualStudioVersion = 17.3.32929.385 MinimumVisualStudioVersion = 15.0.26124.0 Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "FsSpreadsheet", "src\FsSpreadsheet\FsSpreadsheet.fsproj", "{601DB071-B467-4237-9403-E63616038B61}" EndProject @@ -18,6 +18,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution", "Solution", "{27 RELEASE_NOTES.md = RELEASE_NOTES.md EndProjectSection EndProject +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsSpreadsheet.CsvIO", "src\FsSpreadsheet.CsvIO\FsSpreadsheet.CsvIO.fsproj", "{A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -64,6 +66,18 @@ Global {CBA2E524-B861-44FE-A0B0-668E57FF2A24}.Release|x64.Build.0 = Release|Any CPU {CBA2E524-B861-44FE-A0B0-668E57FF2A24}.Release|x86.ActiveCfg = Release|Any CPU {CBA2E524-B861-44FE-A0B0-668E57FF2A24}.Release|x86.Build.0 = Release|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Debug|x64.ActiveCfg = Debug|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Debug|x64.Build.0 = Debug|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Debug|x86.ActiveCfg = Debug|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Debug|x86.Build.0 = Debug|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Release|Any CPU.Build.0 = Release|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Release|x64.ActiveCfg = Release|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Release|x64.Build.0 = Release|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Release|x86.ActiveCfg = Release|Any CPU + {A89CB3BC-7C15-4A71-863C-2E1DDEDDD12A}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/FsSpreadsheet.CsvIO/FsExtension.fs b/src/FsSpreadsheet.CsvIO/FsExtension.fs new file mode 100644 index 00000000..05b81298 --- /dev/null +++ b/src/FsSpreadsheet.CsvIO/FsExtension.fs @@ -0,0 +1,112 @@ +namespace FsSpreadsheet.CsvIO + +open FsSpreadsheet + +[] +module FsExtensions = + + type FsRow with + + member self.ToSparseRow(cellCollection : FsCellsCollection) : seq = + + let maxColIndex = self.RangeAddress.LastAddress.ColumnNumber + let cells = self.Cells(cellCollection) + seq { + for i = 1 to maxColIndex do + cells + |> Seq.tryPick (fun cell -> + if cell.WorksheetColumn = i then + Option.Some cell.Value + else + None + ) + } + + type FsWorksheet with + + member self.ToSparseTable() : seq option>= + self.RescanRows() + self.SortRows() + let rows = self.GetRows() + let maxRowIndex = self.CellCollection.MaxRowNumber + seq { + for i = 1 to maxRowIndex do + rows + |> Seq.tryPick (fun row -> + if row.Index = i then + Some (row.ToSparseRow(self.CellCollection)) + else + None + ) + } + + member self.ToTableString(separator : char option) : string = + let separator = separator |> Option.defaultValue ',' + self.ToSparseTable() + |> Seq.map (fun row -> + match row with + | None -> "" + | Some s when Seq.isEmpty s -> "" + | Some row -> + row + |> Seq.map (fun cell -> cell |> Option.defaultValue "") + |> Seq.reduce (fun rowString cellString -> $"{rowString}{separator}{cellString}") + ) + |> Seq.reduce (fun tableString rowString -> + $"{tableString}\n{rowString}" + ) + + type FsWorkbook with + + member self.ToStream(stream : System.IO.MemoryStream,?Separator : char) = + let streamWriter = new System.IO.StreamWriter(stream) + self.GetWorksheets().Head.ToTableString(Separator) + |> streamWriter.Write + streamWriter.Flush() + + member self.ToBytes(?Separator : char) = + use memoryStream = new System.IO.MemoryStream() + match Separator with + | Some s -> self.ToStream(memoryStream,s) + | None -> self.ToStream(memoryStream) + memoryStream.ToArray() + + member self.ToFile(path,?Separator : char) = + match Separator with + | Some s -> self.ToBytes(s) + | None -> self.ToBytes() + |> fun bytes -> System.IO.File.WriteAllBytes (path, bytes) + + static member toStream(stream : System.IO.MemoryStream,workbook : FsWorkbook,?Separator : char) = + match Separator with + | Some s -> workbook.ToStream(stream,s) + | None -> workbook.ToStream(stream) + workbook.ToStream(stream) + + static member toBytes(workbook: FsWorkbook,?Separator : char) = + match Separator with + | Some s -> workbook.ToBytes(s) + | None -> workbook.ToBytes() + + static member toFile(path,workbook: FsWorkbook,?Separator : char) = + match Separator with + | Some s -> workbook.ToFile(path,s) + | None -> workbook.ToFile(path) + +type Writer = + + static member toStream(stream : System.IO.MemoryStream,workbook : FsWorkbook,?Separator : char) = + match Separator with + | Some s -> workbook.ToStream(stream,s) + | None -> workbook.ToStream(stream) + workbook.ToStream(stream) + + static member toBytes(workbook: FsWorkbook,?Separator : char) = + match Separator with + | Some s -> workbook.ToBytes(s) + | None -> workbook.ToBytes() + + static member toFile(path,workbook: FsWorkbook,?Separator : char) = + match Separator with + | Some s -> workbook.ToFile(path,s) + | None -> workbook.ToFile(path) \ No newline at end of file diff --git a/src/FsSpreadsheet.CsvIO/FsSpreadsheet.CsvIO.fsproj b/src/FsSpreadsheet.CsvIO/FsSpreadsheet.CsvIO.fsproj new file mode 100644 index 00000000..d4be8a15 --- /dev/null +++ b/src/FsSpreadsheet.CsvIO/FsSpreadsheet.CsvIO.fsproj @@ -0,0 +1,16 @@ + + + + netstandard2.0 + true + + + + + + + + + + + diff --git a/src/FsSpreadsheet.ExcelIO/FsExtensions.fs b/src/FsSpreadsheet.ExcelIO/FsExtensions.fs index c52d45cb..feeb076f 100644 --- a/src/FsSpreadsheet.ExcelIO/FsExtensions.fs +++ b/src/FsSpreadsheet.ExcelIO/FsExtensions.fs @@ -91,3 +91,14 @@ module FsExtensions = static member toFile(path,workbook: FsWorkbook) = workbook.ToFile(path) + +type Writer = + + static member toStream(stream : System.IO.MemoryStream,workbook : FsWorkbook) = + workbook.ToStream(stream) + + static member toBytes(workbook: FsWorkbook) = + workbook.ToBytes() + + static member toFile(path,workbook: FsWorkbook) = + workbook.ToFile(path) \ No newline at end of file