2017-09-19 44 views
0

ユーザー定義のExcelファイルを開き、データを入力してユーザー指定のパス、ファイル名で保存するJavaプログラムを作成していますと拡張。入力ファイルがxlsmだったとしても、出力をxlsxとして保存することを宣言することは可能ですが、そうではありません。Poi:xlsmからExcelファイルを開いた後、Excelファイルを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); 
} 

へのワークブックの設定:ワークブックを開く

The file 'FileName.xlsx' is a macro-free file, but contains macro-enabled content

キーコードのセグメント:私は以下のようにコードでそれをしようとすると、ファイルを開くと、私はエラーになります右のタイプ:

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

WorkbookTypeを設定するとコンテンツタイプのみが変更されますが、XLSMファイルコンテンツからVBAプロジェクトが削除されません。

次のコードは、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(); 

} 
} 
関連する問題