Java “如何修复”;我们发现';abc.xlsm';。你想让我们尽力恢复吗?

Java “如何修复”;我们发现';abc.xlsm';。你想让我们尽力恢复吗?,java,excel,xls,xlsm,apache-poi-4,Java,Excel,Xls,Xlsm,Apache Poi 4,我的代码中有以下方法(createAdditionalSheetsInExcel),该方法尝试为特定场景创建其他工作表(runOutputNumber>1)。它最终会创建excel,但问题是,当您尝试打开excel时,最终会出现以下错误: workBookObj.cloneSheet(index,sheetName)不会在java代码中抛出错误,但当我尝试打开excel文件时,会出现以下错误: 我试图删除工作表中表格的格式,然后错误消失。因此,这一定与工作表中表格的格式有关 private st

我的代码中有以下方法(
createAdditionalSheetsInExcel
),该方法尝试为特定场景创建其他工作表(
runOutputNumber>1
)。它最终会创建excel,但问题是,当您尝试打开excel时,最终会出现以下错误:

workBookObj.cloneSheet(index,sheetName)
不会在java代码中抛出错误,但当我尝试打开excel文件时,会出现以下错误:

我试图删除工作表中表格的格式,然后错误消失。因此,这一定与工作表中表格的格式有关

private static void createAdditionalSheetsInExcel(String tempOutputFileName, String outputFileName, int runOutputNumber) throws IOException {

    FileInputStream fileIn = new FileInputStream(tempOutputFileName);
    XSSFWorkbook workBookObj = new XSSFWorkbook(fileIn);
    workBookObj.setWorkbookType(XSSFWorkbookType.XLSM);

    runOutputNumber = 2;//Hard coded for clarification
    if (runOutputNumber > 1) {

        int initialNoOfSheets = workBookObj.getNumberOfSheets();

        for (int runIndex = 2; runIndex <= runOutputNumber; runIndex++) {

            for (int index = 0; index < initialNoOfSheets; index++) {
                XSSFSheet sheet = workBookObj.getSheetAt(index);

                String sheetName = sheet.getSheetName().trim()
                                    .substring(0, sheet.getSheetName().length() - 1) + runIndex;
                workBookObj.cloneSheet(index, sheetName);
            }
        }
    }

    FileOutputStream fileOut = new FileOutputStream(outputFileName);
    workBookObj.write(fileOut);

    fileOut.close();
    workBookObj.close();
    deleteTempExcel(tempOutputFileName);
}
private static void createAdditionalSheetsInXcel(字符串tempOutputFileName、字符串outputFileName、int runOutputNumber)引发IOException{
FileInputStream fileIn=新的FileInputStream(tempOutputFileName);
XSSFWorkbook workBookObj=新XSSFWorkbook(fileIn);
workBookObj.setWorkbookType(XSSFWorkbookType.XLSM);
runOutputNumber=2;//硬编码以便于澄清
如果(runOutputNumber>1){
int initialNoOfSheets=workBookObj.getNumberOfSheets();
对于(int runIndex=2;runIndex

最后,通过使用jacob api和对模板进行更改,解决了这个问题。问题在于Excel中定义的局部变量,我可以通过转到(公式->名称管理器)访问该变量并删除了变量。即使在删除变量后,我也无法让它与Apache POI一起工作,因此最终使用了Jacob api。代码如下:

    package com.ford.ltdrive.model.output.excel.excelenum;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

public class CloneSheet {

    public void backup(String filepath) {
        try {
            Date d = new Date();
            String dateString = (d.getYear() + 1900) + "_" + d.getMonth() + "_" + d.getDate();
           // String backupfilepath = filepath.replace(".xlsm", "_backup_" + dateString + ".xlsm");
            //Path copied = Paths.get(backupfilepath);
            Path copied1 = Paths.get(filepath + "_tmp");
            Path originalPath = Paths.get(filepath);
           // Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING);
            Files.copy(originalPath, copied1, StandardCopyOption.REPLACE_EXISTING);
            Files.delete(Paths.get(filepath));
        } catch (IOException ex) {
            Logger.getLogger(CloneSheet.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public void cloneSheets(String xlsfile, java.util.List<String> list,int copynum) {
        ActiveXComponent app = new ActiveXComponent("Excel.Application");
        try {
            backup(xlsfile);

            app.setProperty("Visible", new Variant(false));
            Dispatch excels = app.getProperty("Workbooks").toDispatch();
            Dispatch excel = Dispatch.invoke(
                    excels,
                    "Open",
                    Dispatch.Method,
                    new Object[]{xlsfile + "_tmp", new Variant(false),
                        new Variant(true)}, new int[1]).toDispatch();
            //Dispatch sheets = Dispatch.get((Dispatch) excel, "Worksheets").toDispatch();
            int sz = list.size();//"Angle_1pc_SBC_R1"
            for (int i = 0; i < sz; i++) {
                Dispatch sheet = Dispatch.invoke(excel, "Worksheets", Dispatch.Get,
                        new Object[]{list.get(i)}, new int[1]).toDispatch();//Whatever sheet you    //wanted the new sheet inserted after

                //Dispatch workbooksTest = app.getProperty("Sheets").toDispatch();//Get the workbook
                //Dispatch sheet2 = Dispatch.call(workbooksTest, "Add").toDispatch();
                for(int k=0;k<copynum -1;k++)
                {
                    Dispatch.call(sheet, "Copy", sheet);
                }
            }
            //Moves the sheet behind the desired sheet
            Dispatch.invoke(excel, "SaveAs", Dispatch.Method, new Object[]{xlsfile, new Variant(52)}, new int[1]);
            Variant f = new Variant(false);
            Dispatch.call(excel, "Close", f);
            Files.delete(Paths.get(xlsfile + "_tmp"));

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            app.invoke("Quit", new Variant[]{});
        }
    }
   /* public static void main(String args[])
    {
        java.util.ArrayList<String> list = new java.util.ArrayList();
        list.add("Angle_1pc_SBC_R1");
        new CloneSheet().cloneSheets("C:\\LTDrive2_4\\Excel\\Test.xlsm", list, 2);
    }*/
}
package com.ford.ltdrive.model.output.excel.excelenum;
导入com.jacob.activeX.ActiveXComponent;
导入com.jacob.com.Dispatch;
导入com.jacob.com.Variant;
导入java.io.File;
导入java.io.IOException;
导入java.nio.file.Files;
导入java.nio.file.Path;
导入java.nio.file.path;
导入java.nio.file.StandardCopyOption;
导入java.util.Date;
导入java.util.logging.Level;
导入java.util.logging.Logger;
公共级克隆片{
公共无效备份(字符串文件路径){
试一试{
日期d=新日期();
字符串日期字符串=(d.getYear()+1900)+“”+d.getMonth()+“”+d.getDate();
//String backupfilepath=filepath.replace(“.xlsm”、“_backup_quo+dateString+”.xlsm”);
//Path copied=Path.get(backupfilepath);
Path copied1=Path.get(filepath+“_tmp”);
Path originalPath=Path.get(filepath);
//复制(原始路径、复制、标准复制选项。替换现有文件);
文件。复制(原始路径,复制1,标准复制选项。替换现有文件);
delete(path.get(filepath));
}捕获(IOEX异常){
Logger.getLogger(CloneSheet.class.getName()).log(Level.SEVERE,null,ex);
}
}
公共无效克隆表(字符串xlsfile、java.util.List列表、int copynum){
ActiveXComponent应用程序=新的ActiveXComponent(“Excel.Application”);
试一试{
备份(xlsfile);
app.setProperty(“可见”,新变体(假));
Dispatch excels=app.getProperty(“工作簿”).toDispatch();
Dispatch excel=Dispatch.invoke(
卓越,
“开放”,
调度方法,
新对象[]{xlsfile+“_tmp”,新变量(false),
新变量(true)},新int[1])。toDispatch();
//分派工作表=分派.get((分派)excel,“工作表”).toDispatch();
int sz=list.size();/“角度1pc\SBC\u R1”
对于(int i=0;i对于(int k=0;k一些信息缺失,比如您遇到的错误,但我想知道您是否为所有工作表指定了唯一的名称?@David感谢您的回复,Java代码中没有错误。从Java程序的角度来看,一切都很顺利,没有任何错误和异常。但是,当我尝试打开excel时,我得到了error消息