All:
I am pretty new to Excel and APche POI, I wonder how to read in Excel .xlsm file(Macro Enable excel) and save it as .xlsx file using Apache POI?
Any example will be appreciated
All:
I am pretty new to Excel and APche POI, I wonder how to read in Excel .xlsm file(Macro Enable excel) and save it as .xlsx file using Apache POI?
Any example will be appreciated
Making an answer from my comments. Hope it will be more clear then.
The following code does creating a XSSFWorkbook
from a Workbook.xlsm
template which remains unchanged.
It does changings in this workbook then and, before saving a copy as *.xlsx
, the current state will be saved as WorkbookNew.xlsm
file. So the macros stays preserved.
Then the VBA
will be removed, the content type will be set to XLSX
and further changings will be made. Then this copy will be saved as WorkbookNew.xlsx
file.
After that, the previous workbook state will be got back by creating the workbook again from the previous saved WorkbookNew.xlsm
file. Then further changings will be made and after all the final state of the WorkbookNew.xlsm
file will be written out.
So we have the unchanged Workbook.xlsm
template, the WorkbookNew.xlsx
and the WorkbookNew.xlsm
then.
Example:
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.regex.Pattern;
class ReadXSLMWriteXLSXWorkbook {
public static void main(String[] args) throws Exception {
XSSFWorkbook workbook;
Sheet sheet;
Row row;
Cell cell;
FileOutputStream out;
//create workbook from XLSM template
workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("Workbook.xlsm"));
//do changings
sheet = workbook.getSheetAt(0);
row = sheet.getRow(0);
if (row == null) row = sheet.createRow(0);
cell = row.getCell(0);
if (cell == null) cell = row.createCell(0);
cell.setCellValue("changed in XLSM before writing as XLSX");
//write out the current state
out = new FileOutputStream("WorkbookNew.xlsm");
workbook.write(out);
out.close();
//save copy as XLSX ----------------START
//remove VBA
OPCPackage opcpackage = workbook.getPackage();
//get and remove the vbaProject.bin part from the package
PackagePart vbapart = opcpackage.getPartsByName(Pattern.compile("/xl/vbaProject.bin")).get(0);
opcpackage.removePart(vbapart);
//get and remove the relationship to the removed vbaProject.bin part from the package
PackagePart wbpart = workbook.getPackagePart();
PackageRelationshipCollection wbrelcollection = wbpart.getRelationshipsByType("http://schemas.microsoft.com/office/2006/relationships/vbaProject");
for (PackageRelationship relship : wbrelcollection) {
wbpart.removeRelationship(relship.getId());
}
//set content type to XLSX
workbook.setWorkbookType(XSSFWorkbookType.XLSX);
//do changings only in XLSX
sheet = workbook.getSheetAt(0);
row = sheet.getRow(1);
if (row == null) row = sheet.createRow(1);
cell = row.getCell(1);
if (cell == null) cell = row.createCell(1);
cell.setCellValue("changed before writing as XLSX");
//write out the XLSX
out = new FileOutputStream("WorkbookNew.xlsx");
workbook.write(out);
out.close();
//save copy as XLSX ----------------END
//get back the previous saved state
workbook = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("WorkbookNew.xlsm"));
//do changings
sheet = workbook.getSheetAt(0);
row = sheet.getRow(2);
if (row == null) row = sheet.createRow(1);
cell = row.getCell(2);
if (cell == null) cell = row.createCell(1);
cell.setCellValue("changed in XLSM after writing as XLSX");
//write out the XLSM
out = new FileOutputStream("WorkbookNew.xlsm");
workbook.write(out);
out.close();
workbook.close();
}
}