use try-with-resources in more places

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1817247 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2017-12-05 22:31:59 +00:00
parent 89a788ea5b
commit 5f4f1b5846
3 changed files with 136 additions and 132 deletions

View File

@ -209,12 +209,12 @@ public class XLSX2CSV {
XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData(); XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
int index = 0; int index = 0;
while (iter.hasNext()) { while (iter.hasNext()) {
InputStream stream = iter.next(); try (InputStream stream = iter.next()) {
String sheetName = iter.getSheetName(); String sheetName = iter.getSheetName();
this.output.println(); this.output.println();
this.output.println(sheetName + " [index=" + index + "]:"); this.output.println(sheetName + " [index=" + index + "]:");
processSheet(styles, strings, new SheetToCSV(), stream); processSheet(styles, strings, new SheetToCSV(), stream);
stream.close(); }
++index; ++index;
} }
} }
@ -237,9 +237,9 @@ public class XLSX2CSV {
minColumns = Integer.parseInt(args[1]); minColumns = Integer.parseInt(args[1]);
// The package open is instantaneous, as it should be. // The package open is instantaneous, as it should be.
OPCPackage p = OPCPackage.open(xlsxFile.getPath(), PackageAccess.READ); try (OPCPackage p = OPCPackage.open(xlsxFile.getPath(), PackageAccess.READ)) {
XLSX2CSV xlsx2csv = new XLSX2CSV(p, System.out, minColumns); XLSX2CSV xlsx2csv = new XLSX2CSV(p, System.out, minColumns);
xlsx2csv.process(); xlsx2csv.process();
p.close(); }
} }
} }

View File

@ -21,7 +21,10 @@ import java.util.Iterator;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.poi.openxml4j.opc.PackageAccess; import org.apache.poi.openxml4j.opc.PackageAccess;
import org.apache.poi.util.SAXHelper;
import org.apache.poi.xssf.eventusermodel.XLSX2CSV; import org.apache.poi.xssf.eventusermodel.XLSX2CSV;
import org.apache.poi.xssf.eventusermodel.XSSFReader; import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable; import org.apache.poi.xssf.model.SharedStringsTable;
@ -33,7 +36,6 @@ import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory;
/** /**
* XSSF and SAX (Event API) basic example. * XSSF and SAX (Event API) basic example.
@ -41,122 +43,122 @@ import org.xml.sax.helpers.XMLReaderFactory;
* XSLX processing with the XSSF Event code. * XSLX processing with the XSSF Event code.
*/ */
public class FromHowTo { public class FromHowTo {
public void processFirstSheet(String filename) throws Exception { public void processFirstSheet(String filename) throws Exception {
try (OPCPackage pkg = OPCPackage.open(filename, PackageAccess.READ)) { try (OPCPackage pkg = OPCPackage.open(filename, PackageAccess.READ)) {
XSSFReader r = new XSSFReader(pkg); XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable(); SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst); XMLReader parser = fetchSheetParser(sst);
// process the first sheet // process the first sheet
InputStream sheet2 = r.getSheetsData().next(); try (InputStream sheet = r.getSheetsData().next()) {
InputSource sheetSource = new InputSource(sheet2);
parser.parse(sheetSource);
sheet2.close();
}
}
public void processAllSheets(String filename) throws Exception {
try (OPCPackage pkg = OPCPackage.open(filename, PackageAccess.READ)) {
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
Iterator<InputStream> sheets = r.getSheetsData();
while (sheets.hasNext()) {
System.out.println("Processing new sheet:\n");
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet); InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource); parser.parse(sheetSource);
sheet.close();
System.out.println("");
} }
} }
} }
public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException { public void processAllSheets(String filename) throws Exception {
XMLReader parser = XMLReaderFactory.createXMLReader(); try (OPCPackage pkg = OPCPackage.open(filename, PackageAccess.READ)) {
ContentHandler handler = new SheetHandler(sst); XSSFReader r = new XSSFReader(pkg);
parser.setContentHandler(handler); SharedStringsTable sst = r.getSharedStringsTable();
return parser;
}
/** XMLReader parser = fetchSheetParser(sst);
* See org.xml.sax.helpers.DefaultHandler javadocs
*/
private static class SheetHandler extends DefaultHandler {
private final SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private boolean inlineStr;
private final LruCache<Integer,String> lruCache = new LruCache<>(50);
private static class LruCache<A,B> extends LinkedHashMap<A, B> { Iterator<InputStream> sheets = r.getSheetsData();
private final int maxEntries; while (sheets.hasNext()) {
System.out.println("Processing new sheet:\n");
public LruCache(final int maxEntries) { try (InputStream sheet = sheets.next()) {
super(maxEntries + 1, 1.0f, true); InputSource sheetSource = new InputSource(sheet);
this.maxEntries = maxEntries; parser.parse(sheetSource);
}
@Override
protected boolean removeEldestEntry(final Map.Entry<A, B> eldest) {
return super.size() > maxEntries;
}
}
private SheetHandler(SharedStringsTable sst) {
this.sst = sst;
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if(name.equals("c")) {
// Print the cell reference
System.out.print(attributes.getValue("r") + " - ");
// Figure out if the value is an index in the SST
String cellType = attributes.getValue("t");
nextIsString = cellType != null && cellType.equals("s");
inlineStr = cellType != null && cellType.equals("inlineStr");
}
// Clear contents cache
lastContents = "";
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// Process the last contents as required.
// Do now, as characters() may be called more than once
if(nextIsString) {
Integer idx = Integer.valueOf(lastContents);
lastContents = lruCache.get(idx);
if (lastContents == null && !lruCache.containsKey(idx)) {
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
lruCache.put(idx, lastContents);
} }
nextIsString = false; System.out.println("");
} }
}
}
// v => contents of a cell public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException, ParserConfigurationException {
// Output after we've seen the string contents XMLReader parser = SAXHelper.newXMLReader();
if(name.equals("v") || (inlineStr && name.equals("c"))) { ContentHandler handler = new SheetHandler(sst);
System.out.println(lastContents); parser.setContentHandler(handler);
} return parser;
} }
@Override /**
* See org.xml.sax.helpers.DefaultHandler javadocs
*/
private static class SheetHandler extends DefaultHandler {
private final SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private boolean inlineStr;
private final LruCache<Integer,String> lruCache = new LruCache<>(50);
private static class LruCache<A,B> extends LinkedHashMap<A, B> {
private final int maxEntries;
public LruCache(final int maxEntries) {
super(maxEntries + 1, 1.0f, true);
this.maxEntries = maxEntries;
}
@Override
protected boolean removeEldestEntry(final Map.Entry<A, B> eldest) {
return super.size() > maxEntries;
}
}
private SheetHandler(SharedStringsTable sst) {
this.sst = sst;
}
@Override
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if(name.equals("c")) {
// Print the cell reference
System.out.print(attributes.getValue("r") + " - ");
// Figure out if the value is an index in the SST
String cellType = attributes.getValue("t");
nextIsString = cellType != null && cellType.equals("s");
inlineStr = cellType != null && cellType.equals("inlineStr");
}
// Clear contents cache
lastContents = "";
}
@Override
public void endElement(String uri, String localName, String name)
throws SAXException {
// Process the last contents as required.
// Do now, as characters() may be called more than once
if(nextIsString) {
Integer idx = Integer.valueOf(lastContents);
lastContents = lruCache.get(idx);
if (lastContents == null && !lruCache.containsKey(idx)) {
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
lruCache.put(idx, lastContents);
}
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v") || (inlineStr && name.equals("c"))) {
System.out.println(lastContents);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException { // NOSONAR public void characters(char[] ch, int start, int length) throws SAXException { // NOSONAR
lastContents += new String(ch, start, length); lastContents += new String(ch, start, length);
} }
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
FromHowTo howto = new FromHowTo(); FromHowTo howto = new FromHowTo();
howto.processFirstSheet(args[0]); howto.processFirstSheet(args[0]);
howto.processAllSheets(args[0]); howto.processAllSheets(args[0]);
} }
} }

View File

@ -39,22 +39,24 @@ public class HybridStreaming {
private static final String SHEET_TO_STREAM = "large sheet"; private static final String SHEET_TO_STREAM = "large sheet";
public static void main(String[] args) throws IOException, SAXException { public static void main(String[] args) throws IOException, SAXException {
InputStream sourceBytes = new FileInputStream("workbook.xlsx"); try (InputStream sourceBytes = new FileInputStream("workbook.xlsx")) {
XSSFWorkbook workbook = new XSSFWorkbook(sourceBytes) { XSSFWorkbook workbook = new XSSFWorkbook(sourceBytes) {
/** Avoid DOM parse of large sheet */ /**
@Override * Avoid DOM parse of large sheet
public void parseSheet(java.util.Map<String,XSSFSheet> shIdMap, CTSheet ctSheet) { */
if (!SHEET_TO_STREAM.equals(ctSheet.getName())) { @Override
super.parseSheet(shIdMap, ctSheet); public void parseSheet(java.util.Map<String, XSSFSheet> shIdMap, CTSheet ctSheet) {
if (!SHEET_TO_STREAM.equals(ctSheet.getName())) {
super.parseSheet(shIdMap, ctSheet);
}
} }
} };
};
// Having avoided a DOM-based parse of the sheet, we can stream it instead.
// Having avoided a DOM-based parse of the sheet, we can stream it instead. ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(workbook.getPackage());
ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(workbook.getPackage()); new XSSFSheetXMLHandler(workbook.getStylesSource(), strings, createSheetContentsHandler(), false);
new XSSFSheetXMLHandler(workbook.getStylesSource(), strings, createSheetContentsHandler(), false); workbook.close();
workbook.close(); }
sourceBytes.close();
} }
private static SheetContentsHandler createSheetContentsHandler() { private static SheetContentsHandler createSheetContentsHandler() {