Skip to content

Commit 13933ec

Browse files
author
Olivier Chédru
authored
Merge pull request #66 from rzymek/support-sheet.xml-over4gb
writer support for xlsx with sheets.xml over 4GB
2 parents 3f8e489 + 47dfcb0 commit 13933ec

File tree

4 files changed

+42
-14
lines changed

4 files changed

+42
-14
lines changed

fastexcel-writer/pom.xml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,23 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
33
<modelVersion>4.0.0</modelVersion>
4-
4+
55
<parent>
66
<groupId>org.dhatim</groupId>
77
<artifactId>fastexcel-parent</artifactId>
88
<version>0-SNAPSHOT</version>
99
</parent>
10-
10+
1111
<artifactId>fastexcel</artifactId>
1212
<name>Fastexcel Writer</name>
1313
<packaging>jar</packaging>
1414

1515
<dependencies>
16+
<dependency>
17+
<groupId>com.github.rzymek</groupId>
18+
<artifactId>opczip</artifactId>
19+
<version>1.0.0</version>
20+
</dependency>
1621
<dependency>
1722
<groupId>org.apache.poi</groupId>
1823
<artifactId>poi-ooxml</artifactId>
@@ -52,7 +57,7 @@
5257
<scope>test</scope>
5358
</dependency>
5459
</dependencies>
55-
60+
5661
<build>
5762
<plugins>
5863
<plugin>

fastexcel-writer/src/main/java/org/dhatim/fastexcel/Workbook.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
*/
1616
package org.dhatim.fastexcel;
1717

18+
import com.github.rzymek.opczip.OpcOutputStream;
19+
1820
import java.io.IOException;
1921
import java.io.OutputStream;
20-
import java.nio.charset.Charset;
2122
import java.time.LocalDateTime;
2223
import java.time.format.DateTimeFormatter;
2324
import java.util.*;
2425
import java.util.stream.Collectors;
2526
import java.util.zip.ZipEntry;
26-
import java.util.zip.ZipOutputStream;
2727

2828
/**
2929
* A {@link Workbook} contains one or more {@link Worksheet} objects.
@@ -35,7 +35,7 @@ public class Workbook {
3535
private final List<Worksheet> worksheets = new ArrayList<>();
3636
private final StringCache stringCache = new StringCache();
3737
private final StyleCache styleCache = new StyleCache();
38-
private final ZipOutputStream os;
38+
private final OpcOutputStream os;
3939
private final Writer writer;
4040

4141
/**
@@ -50,7 +50,7 @@ public class Workbook {
5050
* page</a> for details.
5151
*/
5252
public Workbook(OutputStream os, String applicationName, String applicationVersion) {
53-
this.os = new ZipOutputStream(os, Charset.forName("UTF-8"));
53+
this.os = new OpcOutputStream(os);
5454
/* Tests showed that:
5555
* The default (-1) is level 6
5656
* Level 4 gives best size and very good time
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.apache.poi.openxml4j.util;
2+
3+
public class ZipSecureFileGateway {
4+
/**
5+
* Suppresses the following exception:
6+
* "java.io.IOException: Zip bomb detected! The file would exceed the max size of the expanded data in the zip-file.
7+
* This may indicates that the file is used to inflate memory usage and thus could pose a security risk.
8+
* You can adjust this limit via ZipSecureFile.setMaxEntrySize() if you need to work with files which are very large.
9+
* Uncompressed size: 4294970702, Raw/compressed size: 492446720
10+
* Limits: MAX_ENTRY_SIZE: 4294967295, Entry: xl/worksheets/sheet1.xml"
11+
*/
12+
public static void disableZipBombDetection() {
13+
ZipSecureFile.MAX_ENTRY_SIZE = Long.MAX_VALUE;
14+
}
15+
}

fastexcel-writer/src/test/java/org/dhatim/fastexcel/MemoryUsageTest.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
package org.dhatim.fastexcel;
22

33
import org.apache.poi.openxml4j.opc.OPCPackage;
4+
import org.apache.poi.openxml4j.opc.PackageAccess;
5+
import org.apache.poi.openxml4j.util.ZipSecureFileGateway;
46
import org.apache.poi.ss.usermodel.DataFormatter;
57
import org.apache.poi.ss.util.CellReference;
68
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
79
import org.apache.poi.xssf.eventusermodel.XSSFReader;
810
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
911
import org.apache.poi.xssf.model.StylesTable;
1012
import org.apache.poi.xssf.usermodel.XSSFComment;
13+
import org.junit.Before;
1114
import org.junit.Test;
1215
import org.xml.sax.ContentHandler;
1316
import org.xml.sax.InputSource;
@@ -26,9 +29,9 @@
2629

2730
public class MemoryUsageTest {
2831
private static final Logger LOG = Logger.getLogger(MemoryUsageTest.class.getName());
29-
private static final int ROWS = 500_000;
30-
private static final int COLS = 100;
31-
private static final int SHEETS = 2;
32+
private static final int ROWS = 600_000;
33+
private static final int COLS = 200;
34+
private static final int SHEETS = 1;
3235
private static final File FILE = new File("target/memtest" + ROWS + "x" + COLS + ".xlsx");
3336

3437
private class SheetContentHandler implements XSSFSheetXMLHandler.SheetContentsHandler {
@@ -43,7 +46,7 @@ public SheetContentHandler(int sheetIndex) {
4346

4447
@Override
4548
public void startRow(int rowNum) {
46-
printProgress("validating", sheetIndex * ROWS + rowNum, SHEETS * ROWS);
49+
printProgress("validating poi", sheetIndex * ROWS + rowNum, SHEETS * ROWS);
4750
}
4851

4952
@Override
@@ -59,16 +62,21 @@ public void cell(String cellReference, String formattedValue, XSSFComment commen
5962
}
6063
}
6164

65+
@Before
66+
public void disableZipBombDetection() {
67+
ZipSecureFileGateway.disableZipBombDetection();
68+
}
69+
6270
@Test
6371
public void run() throws Exception {
6472
try (OutputStream out = new FileOutputStream(FILE)) {
6573
generate(out);
6674
}
67-
validate();
75+
validateWithPOI();
6876
}
6977

70-
private void validate() throws Exception {
71-
try (OPCPackage pkg = OPCPackage.open(FILE)) {
78+
private void validateWithPOI() throws Exception {
79+
try (OPCPackage pkg = OPCPackage.open(FILE, PackageAccess.READ)) {
7280
ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(pkg);
7381
XSSFReader reader = new XSSFReader(pkg);
7482
StylesTable styles = reader.getStylesTable();

0 commit comments

Comments
 (0)