poi导入导出excel

    /**
     * #description 参数校验
     *
     * @param fileName   文件名
     * @param list       数据
     * @param titleName  列名
     * @param suffix     后缀
     * @param exportDesc 到处目的地
     * @param keys       数据map对应的key
     * @return
     */
    public static Map verificateParams(String fileName, List<Map> list,
                                       String[] titleName, String suffix,
                                       String exportDesc, String[] keys, HttpServletResponse response) {
        Map map = new HashMap(2);
        if (CollectionUtils.isEmpty(list)) {
            System.out.println("数据不能为空");
            return null;
        }
        if (keys.length != titleName.length) {
            System.out.println("表头长度与字段长度不对应");//不烦导出数据与表头不对应,后台不会报错
            return null;
        }
        if (keys.length > list.get(0).size()) {
            System.out.println("数据导出字段数目小于keys数目");//即map的key小于keys  会抛出空指针异常
            return null;
        }

        //1.创建工作簿对象
        Workbook wb;
        if (suffix.length() <= 0 || ".xls".equals(suffix) || StringUtils.isEmpty(suffix)) {
            System.out.println("创建2003excel");//最大每个sheet36655行
            suffix = ".xls";
            wb = new HSSFWorkbook();
        } else {
            System.out.println("创建2007excel");
//            wb= new XSSFWorkbook();//最大每个sheet1048576行

//            SXSSF与XSSF的对比:
//            a. 在一个时间点上,只可以访问一定数量的数据
//            b. 不再支持Sheet.clone()
//            c. 不再支持公式的求值
//            d. 在使用Excel模板下载数据时将不能动态改变表头,因为这种方式已经提前把excel写到硬盘的了就不能再改了
            suffix = ".xlsx";
            wb = new SXSSFWorkbook(1000);//保证内存不会溢出。设置每1000行就保存到磁盘
        }

        if (null == response) {
            if (exportDesc.length() <= 0 || exportDesc == null || exportDesc == "") {
                System.out.println("导出到桌面");
                File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory();
                String absolutePath = homeDirectory.getAbsolutePath();
                exportDesc = absolutePath + "\\" + fileName + suffix;
                map.put("exportDesc", exportDesc);
            } else {
                exportDesc = exportDesc + "\\" + fileName + suffix;
            }
            map.put("exportDesc", exportDesc);
        }

        map.put("wb", wb);
        return map;
    }

 

缺点: 2003版本:超过36635会出现oom异常 
2007版本:写入非常慢,耗内存也会发生oom 
SXSSFWorkbook:写数据非常慢,非常耗内存,百万级也会发生oom 
优点: 
2003版本过程写入缓存,不操作磁盘,最后一次像写入,速度快
 2007版本:可以写较大数据量十几二十万条写入 
SXSSFWorkbook大文件写入:数据量大几十万条写入

 

 


HSSFWorkbook  :每个sheet36655行   对应版本2003  文件后缀:.xls
XSSFWorkbook:每个sheet1048576行  对应版本2007  文件后缀:.xlsx
SXSSFWorkbook:保证内存不会溢出《SXSSFWorkbook(1000)》默认每100行就会保存到磁盘中(会有临时文件注意清除)

 

导出逻辑:

 

下面介绍关键代码
逻辑思路:
1.创建工作薄                            Workbook 
2.创建table工作表(sheet)               Sheet sheet = wb.createSheet
3.创建行  row                          sheet.createRow(0);
4.列                                   cell = row.createCell(i)

 

    /**
     * @param fileName   文件名称
     * @param sheetName  工作表
     * @param list       要导出的数据 (里面每个map都是一行数据)
     * @param columName  列名
     * @param keys       列对应的key
     * @param exportDesc 导出目的地
     */
    public static void ExportExcelWithholdsOrXls(String fileName, String sheetName,
                                                  List<Map> list, String[] columName,
                                                  String[] keys, String suffix,
                                                  String exportDesc) {
        //1.创建工作薄
        Map map = verificateParams(fileName, list, columName, suffix, exportDesc, keys);
        if (CollectionUtils.isEmpty(map)) {
            return;
        }
        exportDesc = (String) map.get("exportDesc");
        Workbook wb = (Workbook) map.get("wb");


        //总数据条数
        int totalSize = list.size();
        //sheetSize 多少个工作表sheet
        int i = totalSize % 100000;//默认每个sheet10W行
        //有多少个sheet就有多少个表头sheetSize==rowSize
        int sheetSize = i == 0 ? totalSize/100000 : totalSize/100000 + 1;
        int constant = 100000;
        for (int j = 0; j < sheetSize; j++) {
            //2.创建table工作表(sheet)
            Sheet sheet = wb.createSheet(sheetName+j);
            CellStyle borderStyle = wb.createCellStyle();
            CellStyle style = wb.createCellStyle();

            // sheet.setColumnWidth(0, 3766); //第一个参数代表列id(从0开始),第2个参数代表宽度值
            setStyle(wb, sheet, style, borderStyle);

            //3.创建第一行  每个sheet都是从row==0开始
            Row row = sheet.createRow(0);
            //表头,即各个列的列名独占一行 第一行从索引0开始
            row.setHeight((short) 400); //目的是想把行高设置成25px
            setRow(columName, borderStyle, row);

            //4.列
            // 表格内容填充
            //每个sheet数据需要由总数截取存放  所以这里每个sheet吸入1W条
            if(j+1==sheetSize){
                List<Map> maps = list.subList(constant * j, totalSize);
                setCell(maps, keys, sheet, style);
            }else{
                List<Map> maps = list.subList(constant * j, constant * j+constant);
                setCell(maps, keys, sheet, style);
            }

        }


        try {
            OutputStream fileOut = new FileOutputStream(exportDesc);
            wb.write(fileOut);
            fileOut.flush();
            fileOut.close();
            //清楚临时文件
            if (wb instanceof SXSSFWorkbook) {
                ((SXSSFWorkbook) wb).dispose();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

送大家一个二维数组的导出方式:

 

    /**
     * 二维数组导出
      *?代表你有多少列
     *【0】【?】第一行都是列名
      *【1】【?】第二行都是数据
     */

    public static void Export(Object[][] data) {
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFSheet sheet = wb.createSheet("table");  //创建table工作薄
        Object[][] datas = {
                             {"区域", "总销售额(万元)", "总利润(万元)简单的表格"},
                             {"江苏省", 9045, 2256}, {"广东省", 3000, 690}
                           };
        HSSFRow row;
        HSSFCell cell;
        //行循环
        for (int i = 0; i < datas.length; i++) {
            row = sheet.createRow(i);//创建表格行
            //列循环
            for (int j = 0; j < datas[i].length; j++) {
                cell = row.createCell(j);//根据表格行创建单元格
                cell.setCellValue(String.valueOf(datas[i][j]));
            }
        }
        try {
            File homeDirectory = FileSystemView.getFileSystemView().getHomeDirectory();
            String absolutePath = homeDirectory.getAbsolutePath();
            String path = absolutePath + "sd.xls";
            wb.write(new FileOutputStream(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

posted @ 2022-07-10 15:42  余生请多指教ANT  阅读(95)  评论(0编辑  收藏  举报