Skip to content

Commit

Permalink
Enable to specify an origin point to start the export
Browse files Browse the repository at this point in the history
  • Loading branch information
amanteaux committed Dec 29, 2017
1 parent 80169e2 commit b2ba92a
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,15 +100,18 @@ private void writeRow(T row) {
}

private void initializeExcelRow() {
int rowIndex = currentExcelRow == null ? 0 : currentExcelRow.getRowNum() + 1;
int rowIndex = currentExcelRow == null ? sheetConfig.rowOrigin() : currentExcelRow.getRowNum() + 1;
currentExcelRow = sheetConfig.sheet().getRow(rowIndex);
if(currentExcelRow == null) {
currentExcelRow = sheetConfig.sheet().createRow(rowIndex);
}
}

private void setCellValue(final Object value, final int columnIndex) {
Cell cell = currentExcelRow.getCell(columnIndex, MissingCellPolicy.CREATE_NULL_AS_BLANK);
Cell cell = currentExcelRow.getCell(
sheetConfig.columnOrigin() + columnIndex,
MissingCellPolicy.CREATE_NULL_AS_BLANK
);
sheetConfig.cellStyler().style(cell);

if(value == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,15 @@ public final class ExportExcelConfig {

private final Sheet sheet;
private ExcelCellStyler cellStyler;
private int columnOrigin;
private int rowOrigin;

ExportExcelConfig(Sheet sheet) {
this.sheet = sheet;
this.cellStyler = ExcelCellStyler.bordersStyle();
this.cellStyler.initialize(sheet.getWorkbook());
this.columnOrigin = 0;
this.rowOrigin = 0;
}

Sheet sheet() {
Expand All @@ -40,11 +44,36 @@ ExcelCellStyler cellStyler() {
return this.cellStyler;
}

int columnOrigin() {
return this.columnOrigin;
}

int rowOrigin() {
return this.rowOrigin;
}

public ExportExcelConfig withCellStyler(ExcelCellStyler cellStyler) {
this.cellStyler = cellStyler;
return this;
}

/**
* Indicates to export data from the origin point.
* By default the origin is the point (0, 0).
* That enables to leave the first columns/rows of the Excel sheet untouched by the export.
*
* @throws IllegalArgumentException If the origin point contains negative coordinates
*/
public ExportExcelConfig withOrigin(int columnIndex, int rowIndex) {
if(columnIndex < 0 || rowIndex < 0) {
throw new IllegalArgumentException("The origin point coordinates must be positive");
}

this.columnOrigin = columnIndex;
this.rowOrigin = rowIndex;
return this;
}

// config building starting points

/**
Expand Down
64 changes: 53 additions & 11 deletions src/test/java/com/coreoz/windmill/WindmillTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import com.coreoz.windmill.exports.config.ExportConfig;
import com.coreoz.windmill.exports.config.ExportHeaderMapping;
import com.coreoz.windmill.exports.exporters.excel.ExportExcelConfig;
import com.coreoz.windmill.files.FileSource;
import com.coreoz.windmill.files.ParserGuesserTest;
import com.coreoz.windmill.imports.Cell;
Expand All @@ -20,16 +21,19 @@

import lombok.Value;

/**
* Integration tests for Windmill
*/
public class WindmillTest {

@Test
public void should_export_as_xlsx_with_header() {
byte[] xlsExport = exportBase()
byte[] xlsxExport = exportBase()
.withHeaderMapping(exportHeaderMapping())
.asExcel()
.toByteArray();

tryParseHeaderFile(FileSource.of(xlsExport));
tryParseHeaderFile(FileSource.of(xlsxExport));
}

@Test
Expand All @@ -44,12 +48,12 @@ public void should_export_as_csv_with_header() {

@Test
public void should_export_as_xlsx_no_header() {
byte[] xlsExport = exportBase()
byte[] xlsxExport = exportBase()
.withNoHeaderMapping(exportNoHeaderMapping())
.asExcel()
.toByteArray();

tryParseNoHeaderFile(FileSource.of(xlsExport));
tryParseNoHeaderFile(FileSource.of(xlsxExport));
}

@Test
Expand All @@ -62,6 +66,40 @@ public void should_export_as_csv_with_no_header() {
tryParseNoHeaderFile(FileSource.of(csvExport));
}

@Test
public void should_export_excel_data_starting_from_a_non_origin_point() {
byte[] xlsxExport = exportBase()
.withNoHeaderMapping(exportNoHeaderMapping())
// we are using an existing file to write the new data,
// else POI will simply ignore the first empty rows and the test will be biased
.asExcel(ExportExcelConfig.fromWorkbook(loadFile("/import.xlsx")).build("Feuil1").withOrigin(6, 3))
.toByteArray();

// check that the first rows are not modified
try (Stream<Row> rowStream = Windmill.parse(FileSource.of(xlsxExport))) {
List<Import> result = rowStream
.skip(1)
.limit(2)
.map(this::parsingFunction)
.collect(Collectors.toList());

assertThat(result).containsExactlyElementsOf(data());
}

try (Stream<Row> rowStream = Windmill.parse(FileSource.of(xlsxExport))) {
List<Import> result = rowStream.skip(3).map(row -> Import.of(
row.cell(6).asString(),
row.cell(7).asString(),
row.cell(8).asString(),
row.cell(9).asInteger().value(),
row.cell(10).asDouble().value()
))
.collect(Collectors.toList());

assertThat(result).containsExactlyElementsOf(data());
}
}

@Test
public void should_parse_xls() {
tryParseFile("/import.xls");
Expand Down Expand Up @@ -165,19 +203,23 @@ private void tryParseHeaderFile(FileSource fileSource) {

private void tryParseNoHeaderFile(FileSource fileSource) {
try (Stream<Row> rowStream = Windmill.parse(fileSource)) {
List<Import> result = rowStream.map(row -> Import.of(
row.cell(0).asString(),
row.cell(1).asString(),
row.cell(2).asString(),
row.cell(3).asInteger().value(),
row.cell(4).asDouble().value()
))
List<Import> result = rowStream.map(this::parsingFunction)
.collect(Collectors.toList());

assertThat(result).containsExactlyElementsOf(data());
}
}

private Import parsingFunction(Row row) {
return Import.of(
row.cell(0).asString(),
row.cell(1).asString(),
row.cell(2).asString(),
row.cell(3).asInteger().value(),
row.cell(4).asDouble().value()
);
}

private void checkInexistantCell(String fileName) {
Row firstRow = Windmill
.parse(loadFile(fileName))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.coreoz.windmill.exports.exporters.excel;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

import org.junit.Test;

import com.coreoz.windmill.files.FileSource;

public class ExportExcelConfigTest {

@Test
public void withOrigin_check_that_negative_coordinates_are_not_accepted() {
ExportExcelConfig exportConfig = ExportExcelConfig.newXlsxFile().build();

try {
exportConfig.withOrigin(1, -1);
fail("Should not accept negative row index");
} catch (IllegalArgumentException e) {
// as expected
}

try {
exportConfig.withOrigin(-1, 0);
fail("Should not accept negative column index");
} catch (IllegalArgumentException e) {
// as expected
}
}

@Test
public void withOrigin_check_that_positive_coordinates_are_accepted() {
ExportExcelConfig exportConfig = ExportExcelConfig.newXlsxFile().build();

exportConfig.withOrigin(0, 0);
assertThat(exportConfig.columnOrigin()).isZero();
assertThat(exportConfig.rowOrigin()).isZero();

exportConfig.withOrigin(3, 5);
assertThat(exportConfig.columnOrigin()).isEqualTo(3);
assertThat(exportConfig.rowOrigin()).isEqualTo(5);
}

@Test
public void fromWorkbook_check_that_xlsx_files_are_accepted() {
ExportExcelConfigBuilder configBuilder = ExportExcelConfig.fromWorkbook(
FileSource.of(ExportExcelConfigTest.class.getResourceAsStream("/import.xlsx"))
);

assertThat(configBuilder).isNotNull();
}

@Test
public void fromWorkbook_check_that_xls_files_are_accepted() {
ExportExcelConfigBuilder configBuilder = ExportExcelConfig.fromWorkbook(
FileSource.of(ExportExcelConfigTest.class.getResourceAsStream("/import.xls"))
);

assertThat(configBuilder).isNotNull();
}

@Test
public void fromWorkbook_check_that_non_excel_files_are_not_accepted() {
try {
ExportExcelConfig.fromWorkbook(
FileSource.of(ExportExcelConfigTest.class.getResourceAsStream("/import.csv"))
);
fail("Should not accept non excel files");
} catch (IllegalArgumentException e) {
// as expected
}
}

}

0 comments on commit b2ba92a

Please sign in to comment.