Skip to content

Commit a33e104

Browse files
authored
Merge pull request #157 from LeandroC89/ExcelWriteNewSheet
Excel add new sheet without overwriting the file
2 parents 0ae24d3 + 3d740c2 commit a33e104

File tree

4 files changed

+61
-10
lines changed
  • dataframe-excel/src
    • main/kotlin/org/jetbrains/kotlinx/dataframe/io
    • test/kotlin/org/jetbrains/kotlinx/dataframe/io
  • docs/StardustDocs/topics
  • tests/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api

4 files changed

+61
-10
lines changed

dataframe-excel/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/xlsx.kt

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,9 @@ public fun <T> DataFrame<T>.writeExcel(
306306
sheetName: String? = null,
307307
writeHeader: Boolean = true,
308308
workBookType: WorkBookType = WorkBookType.XLSX,
309+
keepFile: Boolean = false,
309310
) {
310-
return writeExcel(File(path), columnsSelector, sheetName, writeHeader, workBookType)
311+
return writeExcel(File(path), columnsSelector, sheetName, writeHeader, workBookType, keepFile)
311312
}
312313

313314
public enum class WorkBookType {
@@ -320,16 +321,22 @@ public fun <T> DataFrame<T>.writeExcel(
320321
sheetName: String? = null,
321322
writeHeader: Boolean = true,
322323
workBookType: WorkBookType = WorkBookType.XLSX,
324+
keepFile: Boolean = false,
323325
) {
324-
val factory = when (workBookType) {
325-
WorkBookType.XLS -> {
326-
{ HSSFWorkbook() }
327-
}
328326

329-
WorkBookType.XLSX -> {
330-
{ XSSFWorkbook() }
327+
val factory =
328+
if (keepFile){
329+
when (workBookType) {
330+
WorkBookType.XLS -> HSSFWorkbook(file.inputStream())
331+
WorkBookType.XLSX -> XSSFWorkbook(file.inputStream())
332+
}
333+
}
334+
else {
335+
when (workBookType) {
336+
WorkBookType.XLS -> HSSFWorkbook()
337+
WorkBookType.XLSX -> XSSFWorkbook()
338+
}
331339
}
332-
}
333340
return file.outputStream().use {
334341
writeExcel(it, columnsSelector, sheetName, writeHeader, factory)
335342
}
@@ -340,9 +347,9 @@ public fun <T> DataFrame<T>.writeExcel(
340347
columnsSelector: ColumnsSelector<T, *> = { all() },
341348
sheetName: String? = null,
342349
writeHeader: Boolean = true,
343-
factory: () -> Workbook,
350+
factory: Workbook
344351
) {
345-
val wb: Workbook = factory()
352+
val wb: Workbook = factory
346353
writeExcel(wb, columnsSelector, sheetName, writeHeader)
347354
wb.write(outputStream)
348355
wb.close()

dataframe-excel/src/test/kotlin/org/jetbrains/kotlinx/dataframe/io/XlsxTest.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,21 @@ class XlsxTest {
133133
}
134134
}
135135

136+
@Test
137+
fun `write to new sheet when keepFile is true`() {
138+
val names = (1..5).map { "column$it" }
139+
val df = dataFrameOf(names).randomDouble(7)
140+
val fileLoc = Files.createTempFile("generated_wb", ".xlsx").toFile()
141+
142+
df.writeExcel(fileLoc, sheetName = "TestSheet1")
143+
df.writeExcel(fileLoc, sheetName = "TestSheet2", keepFile = true)
144+
145+
val testSheet1Df = DataFrame.readExcel(fileLoc, sheetName = "TestSheet1")
146+
val testSheet2Df = DataFrame.readExcel(fileLoc, sheetName = "TestSheet2")
147+
148+
testSheet1Df.columnNames() shouldBe testSheet2Df.columnNames()
149+
}
150+
136151
@Test
137152
fun `read xlsx file with duplicated columns and repair column names`() {
138153
shouldThrow<DuplicateColumnNamesException> {

docs/StardustDocs/topics/write.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,21 @@ wb.close()
117117

118118
<!---END-->
119119

120+
Add new sheets without using Apache POI directly by using a parameter to keep using the same file if it already exists
121+
122+
<!---FUN writeXlsWithMultipleSheets-->
123+
124+
```kotlin
125+
// Create a new Excel workbook with a single sheet called "allPersons", replacing the file if it already exists -> Current sheets: allPersons
126+
df.writeExcel(file, sheetName = "allPersons")
127+
// Add a new sheet to the previous file without replacing it, by setting keepFile = true -> Current sheets: allPersons, happyPersons
128+
df.filter { person -> person.isHappy }.remove("isHappy").writeExcel(file, sheetName = "happyPersons", keepFile = true)
129+
// Add a new sheet to the previous file without replacing it, by setting keepFile = true -> Current sheets: allPersons, happyPersons, unhappyPersons
130+
df.filter { person -> !person.isHappy }.remove("isHappy").writeExcel(file, sheetName = "unhappyPersons", keepFile = true)
131+
```
132+
133+
<!---END-->
134+
120135
### Writing to Apache Arrow formats
121136

122137
Add dependency:

tests/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Write.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,20 @@ class Write : TestBase() {
219219
}
220220
}
221221

222+
@Test
223+
fun writeXlsWithMultipleSheets() {
224+
useTempFile { file ->
225+
// SampleStart
226+
// Create a new Excel workbook with a single sheet called "allPersons", replacing the file if it already exists -> Current sheets: allPersons
227+
df.writeExcel(file, sheetName = "allPersons")
228+
// Add a new sheet to the previous file without replacing it, by setting keepFile = true -> Current sheets: allPersons, happyPersons
229+
df.filter { person -> person.isHappy }.remove("isHappy").writeExcel(file, sheetName = "happyPersons", keepFile = true)
230+
// Add a new sheet to the previous file without replacing it, by setting keepFile = true -> Current sheets: allPersons, happyPersons, unhappyPersons
231+
df.filter { person -> !person.isHappy }.remove("isHappy").writeExcel(file, sheetName = "unhappyPersons", keepFile = true)
232+
// SampleEnd
233+
}
234+
}
235+
222236
companion object {
223237
private fun String.rejoinWithSystemLineSeparator() = rejoinWithLineSeparator(System.lineSeparator())
224238

0 commit comments

Comments
 (0)