The part /docProps/app.xml fail to be saved in the stream with marshaller org.ap

论坛 期权论坛 期权     
选择匿名的用户   2021-5-31 06:05   6105   0

使用 poi 保存 excel 内容时,出现类似的错误信息:

Exception in thread "main" org.apache.poi.openxml4j.exceptions.OpenXML4JRuntimeException: Fail to save: an error occurs while saving the package : The part /docProps/app.xml fail to be saved in the stream with marshaller org.apache.poi.openxml4j.opc.internal.marshallers.DefaultMarshaller@4fbf1942

网上很多都说是 输出流 在关闭的情况下继续使用的结果,目前我还没有找到合适的解决这个 错误的办法。

下面提供一个思路,可以绕过这个 bug 。

我的业务逻辑 读取 模板excel,编写新的 excel ,不可修改 模板 excel 的内容。

思路:

1,拷贝 模板 excel 到一个临时文件(a.excel)

2,根据临时文件填充内容,生成新的 excel (b.excel,确保 和 临时文件的名称不一样!这里很重要)

3,保存 新的 excel

4,关闭 poi 对象

5,删除临时文件 (a.excel)

核心代码如下:

1,拷贝 模板 excel 到一个临时文件(a.excel)

 private void copyExcel(String fromexcel, String newexcel) {  
  XSSFWorkbook wb = null;
        FileInputStream fis =null;
        FileOutputStream fos = null;
        try {  
         fis = new FileInputStream(fromexcel);
         fos = new FileOutputStream(newexcel);
            wb = new XSSFWorkbook(fis);  
            wb.write(fos);
            fis.close();
   fos.close();
        } catch (Exception e) {  
            e.printStackTrace();  
        }finally{
   try {
    wb.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
    }

2,根据临时文件填充内容,生成新的 excel (b.excel,确保 和 临时文件的名称不一样!这里很重要)

        String filePath = "D:\\template.xlsx";
  String destPath = "D:\\" + System.currentTimeMillis() + ".xlsx";
     this.copyExcel(filePath, destPath);//复制一份临时文件,避免修改原模板
  XSSFWorkbook wb = new XSSFWorkbook(destPath);
     XSSFSheet sheet = wb.getSheetAt(5);//从 0 开始,这里是获取第6个 sheet
     //如果 sheet 是 null 需要新建
     XSSFRow row = sheet.createRow(14);//根据 rownum 创建 行,这里是第 15 行
     XSSFCell firstC = row.createCell(0, CellType.NUMERIC);
     firstC.setCellValue("100.00");
     XSSFCell nC = row.createCell(5, CellType.NUMERIC);
     nC.setCellValue("100.00");

3,保存 新的 excel

        FileOutputStream outputStream = new FileOutputStream("D:template2.xlsx");
     wb.write(outputStream);
     outputStream.close();

4,关闭 poi 对象

wb.close();

5,删除临时文件 (a.excel)

new File(destPath).delete();//删除临时文件

6,import 的所有包(是不是很多朋友在看别人文档的时候找不到这个部分,感到很烦恼,哈哈哈)

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

最后,给几个建议,关于所有的 close 操作和删除临时文件操作,最好放到 finally 块中,这样保证它必然会操作;

另外,return 语句、break 语句、continue 语句,如果掌握不好代码流程最好不要用,会给自己刨坑!!!

希望给位越来越好!

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP