将XLSM转换为XLSX

时间:2012-06-24 06:06:50

标签: c# openxml xlsx epplus xlsm

我正在使用EPPLUS库从Excel读取数据以创建另一个文件。不幸的是,它不支持.XLSM扩展文件。有没有一种很好的方法将.XLSM文件转换为.XLSX文件,以便用EPPLUS读取文件?

(使用EPPLUS进行阅读会很好,因为我的所有代码都是用它编写的:))

3 个答案:

答案 0 :(得分:9)

为此,您需要使用Open XML SDK 2.0。下面是我尝试时为我工作的一段代码:

byte[] byteArray = File.ReadAllBytes("C:\\temp\\test.xlsm");
using (MemoryStream stream = new MemoryStream())
{
    stream.Write(byteArray, 0, (int)byteArray.Length);
    using (SpreadsheetDocument spreadsheetDoc = SpreadsheetDocument.Open(stream, true))
    {
       // Change from template type to workbook type
       spreadsheetDoc.ChangeDocumentType(SpreadsheetDocumentType.Workbook);
    }
    File.WriteAllBytes("C:\\temp\\test.xlsx", stream.ToArray()); 
}

此代码的作用是启用宏启用的工作簿文件并将其打开到SpreadsheetDocument对象中。此对象的类型为MacroEnabledWorkbook,但由于您希望将其作为Workbook,因此请调用ChangeDocumentType方法将其从MacroEnabledWorkbook更改为Workbook 。这将起作用,因为.xlsm和.xlsx文件之间的基础XML是相同的。

答案 1 :(得分:1)

使用Open XML SDK,就像阿穆拉的回答一样,但是 除了更改文档类型外,还应删除VbaDataPart和VbaProjectPart,否则Excel将显示文件已损坏的错误。

using (var inputStream = File.OpenRead("C:\\temp\\test.xlsm"))
using (var outStream = new MemoryStream()) {
    inputStream.CopyTo(outStream);
    using (var doc = SpreadsheetDocument.Open(outStream, true)) {
        doc.DeletePartsRecursivelyOfType<VbaDataPart>();
        doc.DeletePartsRecursivelyOfType<VbaProjectPart>();
        doc.ChangeDocumentType(DocumentFormat.OpenXml.SpreadsheetDocumentType.Workbook);
    }
    File.WriteAllBytes("C:\\temp\\test.xlsx", outStream.ToArray());
}

答案 2 :(得分:-1)

package xlsbtoxlsx;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.regex.Pattern;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbookType;

public class XlsbToXlsxConvertor {

    public static void main(String[] args) throws Exception {
        
        String inputpath="C:\\Excel Data Files\\XLSB\\CSD_TDR_20200823";
        String outputpath="C:\\Excel Data Files\\XLSB\\output";
        
       new XlsbToXlsxConvertor().xlsmToxlsxFileConvertor(inputpath, outputpath);
    }

    public void xlsmToxlsxFileConvertor(String inputpath, String outputpath) throws Exception {
        XSSFWorkbook workbook;
        FileOutputStream out;
        System.out.println("inputpath  " + inputpath);
        File directoryPath = new File(inputpath);
        // List of all files and directories
        String contents[] = directoryPath.list();
        System.out.println("List of files and directories in the specified directory:");
        for (int i = 0; i < contents.length; i++) {
            System.out.println(contents[i]);
            // create workbook from XLSM template
            workbook = (XSSFWorkbook) WorkbookFactory
                    .create(new FileInputStream(inputpath + File.separator + contents[i]));
            // save copy as XLSX ----------------START
            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);

            // write out the XLSX

            out = new FileOutputStream(outputpath + File.separator + contents[i].replace(".xlsm", "") + ".xlsx");
            workbook.write(out);
            out.close();
            System.out.println("done");
            workbook.close();
        }
    }

}