我正在编写一个java程序,它打开一个用户定义的excel文件,用数据填充它,然后将其保存在用户指定的路径,文件名和扩展名下。即使输入文件是xlsm,也应该(但不是)可以声明输出保存为xlsx。如果我尝试使用下面的代码,打开文件会给我错误:
文件'FileName.xlsx'是一个无宏文件,但包含 启用宏的内容
代码的关键部分:
打开工作簿:
try (Workbook workbook = WorkbookFactory.create( new FileInputStream( templateFile ) )) {
// ...processing the file here,
// including a call of stripMacros, c.f. below
} catch ( IOException | EncryptedDocumentException | InvalidFormatException ex ) {
throw new TemplateNotFoundException( "Template not found. Please check property templatePath: " + templateFile, ex );
}
将工作簿设置为正确的类型:
private Workbook stripMacros( final Workbook wb, final String outputFormat ) {
Workbook workbook = wb;
if ( "xlsx".equals( outputFormat ) && ( workbook.getClass() == XSSFWorkbook.class ) ) {
XSSFWorkbook wbx = (XSSFWorkbook) workbook;
wbx.setWorkbookType( XSSFWorkbookType.valueOf( "XLSX" ) );
return wbx;
} else if ( "xlsm".equals( outputFormat ) && ( workbook.getClass() == XSSFWorkbook.class ) ) {
XSSFWorkbook wbm = (XSSFWorkbook) workbook;
wbm.setWorkbookType( XSSFWorkbookType.valueOf( "XLSM" ) );
return wbm;
} else {
return wb;
}
}
保存工作簿:
File outFile = new File( destinationPath, fileName + "." + outputFormat );
outFile.getParentFile().mkdirs();
if ( workbook != null ) {
try {
workbook.write( new FileOutputStream( outFile ) );
workbook.close();
} catch ( IOException ex ) {
throw new FileInaccessibleException( "Workbook could not be saved. Please check if the workbook under " + destinationPath + fileName + "." + outputFormat + " is not open in any program.", ex );
}
}
我需要添加什么才能正确打开文件?我是否需要手动删除宏,如果是这样,怎么做?
答案 0 :(得分:2)
设置WorkbookType
只会更改内容类型,但不会从VBA
文件内容中删除XLSM
项目。
以下代码通过从包中获取和删除vbaProject.bin部分来完成此操作。然后它获取并删除与包中已删除的vbaProject.bin部分的关系。
此后,新的XLSX
文件不再包含VBA
代码。
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 = (XSSFWorkbook)WorkbookFactory.create(new FileInputStream("Workbook.xlsm"));
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);
Sheet sheet = workbook.getSheetAt(0);
Row row = sheet.getRow(0);
if (row == null) row = sheet.createRow(0);
Cell cell = row.getCell(0);
if (cell == null) cell = row.createCell(0);
cell.setCellValue("changed");
workbook.write(new FileOutputStream("Workbook.xlsx"));
workbook.close();
}
}