How to save an xslm file as xslx in Apache POI

2019-08-16 16:37发布

问题:

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

回答1:

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();

 }
}


标签: apache-poi