同声 2019-08-28 21:20 采纳率: 66.7%
浏览 530

POI 读取Excel文件,导致内存突然增大

1、目标

 主要实现 替换excel2003与excel2007文件中某些字符,excel文件大概15M,并且包含一些图片。首先需要读取一个excel文件映射表(不包含图片),将该映射表内容读入Map中,然后再读取待替换excel文件,并根据Map中内容替换excel文件中字符串,最后输出处理好的EXCEL文件(包含图片).

2、问题描述

1、本机计算机内存24G,JDK8, 在eclispe环境中运行时,可以读取并解析EXCEL映射文件,并按照Map替换目标excel文件中字符串。
2、 但是我用exe4j将项目jar打包成exe文件,在内存为8G的测试计算机上运行时,读取excel映射文件时就会导致内存占用很大,内存占用增长速度很快,瞬间导致计算机内存占满。
3、 exe4j打包使用了本地安装解压的jre包,没有把jdk打包进去。
4、 在本机(24G内存)用eclipse运行和用exe运行时,用jconsole监测了一下,读取excel映射文件时内存占用率不是很高,大概400M左右,最高不会超过1G内存。excel映射文件只有200kb左右。

3 问题

请问这中情况是否与exe4j只打包了jre有关,能否用我本地安装的jre库打包到exe文件中。
    为什么在我本机内存不会占满,而在其它测试机上内存过分的高。这个可能与excel文件解析的方法有关,但我不是很明白不同计算机测试效果差别这么大。

4 解析excel相关代码如下

    //存储映射表Map,WeakHashMap <String, String> valueMap = new WeakHashMap<>() 
        valueMap.clear(); 
        File savedFile = new File(path);
        InputStream ins = null;
        try {
            ins = new FileInputStream(savedFile);
        } catch (FileNotFoundException e) {         
            throw new DefException("文件"+path+"不存在",e);
        }
        Workbook wb = null;
        try {
            wb = WorkbookFactory.create(ins);
        } catch (InvalidFormatException e) {
            throw new DefException("文件"+path+"格式错误",e);
        } catch (IOException e) {
            throw new DefException("文件"+path+"导入异常",e);         
        }

        //HSSFWorkbook wb = new HSSFWorkbook(ins);
        Sheet sheet = null;
        int sheetNumber = wb.getNumberOfSheets();
        for (int i = 0; i < sheetNumber; i++) {
            sheet = wb.getSheetAt(i);

            //行数
            int lastRowNum = sheet.getPhysicalNumberOfRows();
            //读取body
            for (int rowNum = 1; rowNum < lastRowNum; rowNum++) {
                //获得当前行
                Row row = sheet.getRow(rowNum);   //index序列号从0开始,跳过首行,取1
                if (row == null) {
                    continue;
                }
                Cell oldm = row.getCell(1);
                if (oldm == null) {
                    continue;
                } else {
                    oldm.setCellType(HSSFCell.CELL_TYPE_STRING);
                }
                Cell newm = row.getCell(3);
                if (newm == null) {
                    continue;
                } else {
                    newm.setCellType(HSSFCell.CELL_TYPE_STRING);
                }
                String oldValue = oldm.getStringCellValue().toString();
                String newValue = newm.getStringCellValue().toString();
                if (!"".equals(oldValue) && !"".equals(newValue)) {
                    valueMap.put(oldValue, newValue);
                }

            }
        }

        try {           
               ins.close();     
        } catch (IOException e) {
            throw new DefException("关闭映射文件"+path+"错误",e);
        }

  • 写回答

2条回答

  • 日落西风又在吹 2019-08-29 11:59
    关注

    -Xms1024m -Xmx2048m 
    调大堆栈内存

    评论

报告相同问题?

悬赏问题

  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!