• 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();
            }
        }
    
  • 相关阅读:
    注册和登录与数据库内的链接
    数据访问
    马厩分配问题
    Codeforces Round #365 (Div. 2) D.Mishka and Interesting sum
    最优比例生成树模板
    01分数规划模板
    hiho一下第109周《Tower Defense Game》
    begin.BZOJ 1383: 三取方格数
    最小生成树
    Codeforces Round #364 (Div. 1)B. Connecting Universities
  • 原文地址:https://www.cnblogs.com/wangbiaohistory/p/16463301.html
Copyright © 2020-2023  润新知