I try to copy all worksheets from one workbook to another workbook. The thing is, it works normally if I read the workbooks via FileInputStreams, but it does not work with File Objects.
Consider the following method:
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataConsolidateFunction;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.usermodel.XSSFPivotTable;
import org.apache.poi.xssf.usermodel.XSSFSheet;
public void copyAllSheetsAcrossWorkbook(String oldWorkbook, String newWorkbook)
throws EncryptedDocumentException, InvalidFormatException, IOException {
FileInputStream fisOld = null;
FileInputStream fisNew = null;
Workbook oldWB = null;
Workbook newWB = null;
FileOutputStream fileOut = null;
System.out.println("oldWorkbook: " + oldWorkbook);
System.out.println("newWorkbook: " + newWorkbook);
fisOld = new FileInputStream(oldWorkbook);
fisNew = new FileInputStream(newWorkbook);
// THIS WORKS
// oldWB = WorkbookFactory.create(fisOld);
// newWB = WorkbookFactory.create(fisNew);
// THIS DOES NOT WORK
oldWB = WorkbookFactory.create(new File(oldWorkbook));
newWB = WorkbookFactory.create(new File(newWorkbook));
if (newWB == null) {
System.out.println("newWB is null");
}
// CellStyle newStyle = newWB.createCellStyle();
Row row;
Cell cell;
copiedSheets = new ArrayList<String>();
for (int i = 0; i < oldWB.getNumberOfSheets(); i++) {
XSSFSheet sheetFromOldWB = (XSSFSheet) oldWB.getSheetAt(i);
String sheetNameFromOldWB = sheetFromOldWB.getSheetName();
XSSFSheet sheetForNewWB = (XSSFSheet) newWB.getSheet(sheetNameFromOldWB);
if (sheetForNewWB != null) {
int sheetIndex = newWB.getSheetIndex(sheetNameFromOldWB);
newWB.removeSheetAt(sheetIndex);
}
LOGGER.info("Copying to new Workbook: " + sheetNameFromOldWB);
sheetForNewWB = (XSSFSheet) newWB.createSheet(sheetFromOldWB.getSheetName());
for (int rowIndex = 0; rowIndex < sheetFromOldWB.getPhysicalNumberOfRows(); rowIndex++) {
row = sheetForNewWB.createRow(rowIndex);
for (int colIndex = 0; colIndex < sheetFromOldWB.getRow(rowIndex).getPhysicalNumberOfCells(); colIndex++) {
cell = row.createCell(colIndex);
// get cell from old WB's sheet and when cell is null, return as blank cells.
Cell c = sheetFromOldWB.getRow(rowIndex).getCell(colIndex, Row.MissingCellPolicy.CREATE_NULL_AS_BLANK);
// Below is where all the copying is happening.
// CellStyle origStyle = c.getCellStyle();
// newStyle.cloneStyleFrom(origStyle);
// cell.setCellStyle(newStyle);
switch (c.getCellTypeEnum()) {
case STRING:
cell.setCellValue(c.getRichStringCellValue().getString());
break;
case NUMERIC:
if (DateUtil.isCellDateFormatted(cell)) {
cell.setCellValue(c.getDateCellValue());
} else {
cell.setCellValue(c.getNumericCellValue());
}
break;
case BOOLEAN:
cell.setCellValue(c.getBooleanCellValue());
break;
case FORMULA:
cell.setCellFormula(c.getCellFormula());
break;
default:
break;
}
}
}
copiedSheets.add(oldWB.getSheetName(i));
}
fileOut = new FileOutputStream(newWorkbook);
newWB.write(fileOut); // <------ HERE I GET NULLPOINTEREXCEPTION
fisOld.close();
fisNew.close();
oldWB.close();
fileOut.close();
newWB.close();
I get the following exception at newWB.write(fileOut);
:
Exception in thread "main" org.apache.poi.POIXMLException: java.lang.NullPointerException
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:168)
at org.apache.poi.POIXMLDocument.write(POIXMLDocument.java:246)
at com.capgemini.toolkit.App.copyAllSheetsAcrossWorkbook(App.java:263)
at com.capgemini.toolkit.App.main(App.java:58)
Caused by: java.lang.NullPointerException
at org.apache.poi.openxml4j.util.ZipSecureFile$ThresholdInputStream.read(ZipSecureFile.java:210)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager$RewindableInputStream.read(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at org.apache.poi.util.DocumentHelper.readDocument(DocumentHelper.java:140)
at org.apache.poi.POIXMLTypeLoader.parse(POIXMLTypeLoader.java:143)
at org.openxmlformats.schemas.officeDocument.x2006.extendedProperties.PropertiesDocument$Factory.parse(Unknown Source)
at org.apache.poi.POIXMLProperties.<init>(POIXMLProperties.java:78)
at org.apache.poi.POIXMLDocument.getProperties(POIXMLDocument.java:166)
... 3 more
In the POI documentation, it is always mentioned to better use a File
object due to lower memory consumption. That's why I'm wondering why it does not work with a File
object .
For testing, this is the only method which is running in the main method and I used 2 fresh Excel files (.xlsx) with some dummy data.
Does anyone see why it does not work with a File
object ? Am I doing something wrong?
FYI: I'm using POI 3.16.