• 最近要求一次性导出50W以上的数据,TMD 开始用的是XSSFWorkbook瞬间内存暴涨到2G然后内存溢出了,嘎嘎…… 查了API才知道POI还有SXSSFWorkbook专门处理大数据,爱死你了POI,虽然之前都爱JXL!

    最近要求一次性导出50W以上的数据,TMD

    开始用的是XSSFWorkbook瞬间内存暴涨到2G然后内存溢出了,嘎嘎……

    查了API才知道POI还有SXSSFWorkbook专门处理大数据,爱死你了POI,虽然之前都爱JXL!

    贴下伪代码供大家参考:

    			OutputStream os = null;
    			try {
    				HttpServletResponse response = super.getResponse();
    				response.setContentType("application/force-download"); // 设置下载类型
    				String filename ="risk_event.xlsx";
    				response.setHeader("Content-Disposition","attachment;filename=" + filename); // 设置文件的名称
    				os = response.getOutputStream(); // 输出流
    				SXSSFWorkbook wb = new SXSSFWorkbook(1000);//内存中保留 1000 条数据,以免内存溢出,其余写入 硬盘
    		        //获得该工作区的第一个sheet   
    				Sheet sheet1 = wb.createSheet("sheet1"); 
    		        int excelRow = 0;
    		        //标题行
    		        Row titleRow = (Row) sheet1.createRow(excelRow++);
    				for (int i = 0; i < columnList.size(); i++) {
    					Cell cell = titleRow.createCell(i);  
    	                cell.setCellValue(columnList.get(i));
    				}
    				
    				for (int m = 0; m < cycleCount; m++) {
    					List<List<String>> eventStrList = this.convertPageModelStrList();
    					if (eventStrList!= null && eventStrList.size() > 0) {
    						for (int i = 0; i < eventStrList.size(); i++) {
    							//明细行
    					        Row contentRow = (Row) sheet1.createRow(excelRow++);
    							List<String> reParam = (List<String>) eventStrList.get(i);
    							for (int j = 0; j < reParam.size(); j++) {
    								Cell cell = contentRow.createCell(j);  
    				                cell.setCellValue(reParam.get(j));
    							}
    						}
    					}
    				}
    				wb.write(os);
    			} catch (Exception e) {
    				e.printStackTrace();
    			} finally {
    				try {
    					if (os != null) {
    						os.close();
    					}
    				} catch (IOException e) {
    					e.printStackTrace();
    				} // 关闭输出流
    			}
    
    

    展开全文
  • Java POI处理大量数据导入导出xls和xlsx导入数据(大量)导出数据(大量)总结 xls和xlsx xls是旧版Excel格式文件,xlsx是新版Excel格式文件;而xlsx新版格式其实是一系列文件压缩包, 如图: xls是以二进制的方式...

    xls和xlsx

    1. xls是旧版Excel格式文件,xlsx是新版Excel格式文件;而xlsx新版格式其实是一系列文件压缩包,
      如图:
      在这里插入图片描述
    2. xls是以二进制的方式存储,这种格式不易被其他软件读取使用;而xlsx采用了基于XML的ooxml开放文档标准,ooxml使用XML和ZIP技术结合进行文件存储,XML是一个基于文本的格式,而且ZIP容器支持内容的压缩,所以其一大优势是可以大大减小文件的尺寸;
    3. 使用POI来读写Excel文件有两种方式,一种用户模式(UserModel),读取时消耗大量内存,造成OOM问题;一种事件模式(SAX模式),仅仅关注文件内部数据,内存消耗很低;
    4. 导出文件同样如此,使用Workbook普通导出,数据量小的时候可以正常使用,但时间等待仍然很长,这时推荐使用POI提供的SXXFWorkbook处理,其使用时间窗口原理(具体可以查询)限制访问,刷出内存,降低内存消耗,提升效率。
      另外还需要注意,根据你使用的功能,仍然可能消耗大量内存,例如合并区域,超链接,注释……,这些内容只存储在内存中。
      在这里插入图片描述

    导入数据(大量)

    大量数据导入在网络上搜寻到的相关代码大部分通过集成POI原生的DefaultHandler重写其startElement, endElement, characters方法进行相关的解析,而POI已经将相关逻辑封装在XSSFSheetXMLHandler,只要实现暴露的接口SheetContentsHandler即可。
    使用SheetContentsHandler的例子可以参考官方的XLSX2CVS
    本例实现该接口:

    package cn.skio.venus.api;
    
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.util.SAXHelper;
    import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
    import org.apache.poi.xssf.eventusermodel.XSSFReader;
    import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
    import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
    import org.apache.poi.xssf.model.StylesTable;
    import org.apache.poi.xssf.usermodel.XSSFComment;
    import org.xml.sax.InputSource;
    import org.xml.sax.SAXException;
    import org.xml.sax.XMLReader;
    
    import javax.xml.parsers.ParserConfigurationException;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.LinkedList;
    import java.util.List;
    
    /**
     * @autor jasmine
     */
    public class ExcelEventParser {
        private String fileName;
        private SimpleSheetContentsHandler handler;
        // 测试使用对比使用SAX和UserModel模式选择(实际使用不需要)
        private Integer saxInterupt;
    	private void setHandler(SimpleSheetContentsHandler handler) {
    		this.handler = handler;
    	}
    
    	// 放置读取数据
        protected List<List<String>> table = new ArrayList<>();
    
        public ExcelEventParser(String filename, Integer saxInterupt){
            this.fileName = filename;
            this.saxInterupt = saxInterupt;
        }
    
        public List<List<String>> parse() {
            OPCPackage opcPackage = null;
            InputStream inputStream = null;
    
            try {
                FileInputStream fileStream = new FileInputStream(fileName);
                opcPackage = OPCPackage.open(fileStream);
                XSSFReader xssfReader = new XSSFReader(opcPackage);
    
                StylesTable styles = xssfReader.getStylesTable();
                ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(opcPackage);
                inputStream = xssfReader.getSheetsData().next();
    
                processSheet(styles, strings, inputStream);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (opcPackage != null) {
                    try {
                        opcPackage.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return table;
        }
    
    	// 确定XMLReader解析器,使用SAX模式解析xml文件
        private void processSheet(StylesTable styles, ReadOnlySharedStringsTable strings, InputStream sheetInputStream) throws SAXException, ParserConfigurationException, IOException {
            XMLReader sheetParser = SAXHelper.newXMLReader();
    
            if (handler == null) {
                setHandler(new SimpleSheetContentsHandler());
            }
            sheetParser.setContentHandler(new XSSFSheetXMLHandler(styles, strings, handler, false));
    
            try {
                sheetParser.parse(new InputSource(sheetInputStream));
            } catch (RuntimeException e) {
                System.out.println("---> 遇到空行读取文件结束!");
            }
        }
    
    	// 实现SheetContentsHandler
        public class SimpleSheetContentsHandler implements SheetContentsHandler{
            protected List<String> row;
            @Override
            public void startRow(int rowNum) {
                row = new LinkedList<>();
            }
    
            @Override
            public void endRow(int rowNum) {
            	// 判断是否使用异常作为文件读取结束(有些Excel文件格式特殊,导致很多空行,浪费内存)
                if (saxInterupt == 1) {
                    if (row.isEmpty()) {
                        throw new RuntimeException("Excel文件读取完毕");
                    }
                }
    			// 添加数据到list集合
                table.add(row);
            }
    
            /**
             * 所有单元格数据转换为string类型,需要自己做数据类型处理
             * @param cellReference 单元格索引
             * @param formattedValue 单元格内容(全部被POI格式化为字符串)
             * @param comment
             */
            @Override
            public void cell(String cellReference, String formattedValue, XSSFComment comment) {
                row.add(formattedValue);
            }
    
            @Override
            public void headerFooter(String text, boolean isHeader, String tagName) {
            }
        }
    }
    
    

    经测试结果,发现使用SAX模式(抛弃了样式等,只关注数据)仅仅消耗很少内存,效率高;而普通Workbook读取数据(测试文件为5.2MB的有大量空行文件)内存消耗 > 1GB(此时线上系统OOM概率非常大);
    在这里插入图片描述

    导出数据(大量)

    导出数据的话瓶颈主要在于数据写入Excel文件,代码(同样的74273条数据导出)如下:

    	// 使用SXSSFwrokbook,大量数据处理快速
    	@GetMapping("/outExcel")
        public void outPutExcel(HttpServletResponse response) throws Exception {
            // 每次写100行数据,就刷新数据出缓存
            SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk
            Sheet sh = wb.createSheet();
            List<Tmp> tmps = tmpDao.findAll();
            log.info("---> 数据量:{}", tmps.size());
    
            for(int rowNum = 0; rowNum < tmps.size(); rowNum++){
                Row row = sh.createRow(rowNum);
                Tmp tmp = tmps.get(rowNum);
                Cell cell1 = row.createCell(0);
                cell1.setCellValue(tmp.getSource());
    
                Cell cell2 = row.createCell(1);
                cell2.setCellValue(tmp.getName());
                Cell cell3 = row.createCell(2);
                cell3.setCellValue(tmp.getPhone());
                Cell cell4 = row.createCell(3);
                cell4.setCellValue(tmp.getCity());
            }
    
            String fileName = "sxssf.xlsx";
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            wb.write(response.getOutputStream());
            wb.close();
        }
    
    	// XSSFWorkbook, 效率低下
    	@GetMapping("/outExcel2")
        public void outPutExcel2(HttpServletResponse response) throws Exception {
            XSSFWorkbook wb = new XSSFWorkbook();
            Sheet sh = wb.createSheet();
            List<Tmp> tmps = tmpDao.findAll();
            log.info("---> 数据量:{}", tmps.size());
    
            for(int rowNum = 0; rowNum < tmps.size(); rowNum++){
                Row row = sh.createRow(rowNum);
                Tmp tmp = tmps.get(rowNum);
                Cell cell1 = row.createCell(0);
                cell1.setCellValue(tmp.getSource());
    
                Cell cell2 = row.createCell(1);
                cell2.setCellValue(tmp.getName());
                Cell cell3 = row.createCell(2);
                cell3.setCellValue(tmp.getPhone());
                Cell cell4 = row.createCell(3);
                cell4.setCellValue(tmp.getCity());
            }
    
            String fileName = "sxssf.xlsx";
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "GBK"));
            wb.write(response.getOutputStream());
            wb.close();
        }
    

    效率对比:

    对象 耗时
    SXSSFWorkbook 在这里插入图片描述
    XSSFWorkbook 在这里插入图片描述

    CPU和内存消耗对比:
    在这里插入图片描述

    总结

    1. 大文件读取使用SAX
    2. 大文件写入使用SXSSFWorkbook

    参考链接:
    [1]: https://blog.csdn.net/Holmofy/article/details/82532311
    [2]: https://blog.csdn.net/daiyutage/article/details/53010491
    [3]: https://www.cnblogs.com/yfrs/p/5689347.html
    [4]: easyexcel

    展开全文
  • poi导入、导出,支持百万级数据模板导出、合并excel。项目为spring-boot-2上开发。resource里面有模板,在junit测试类中修改为本地存在路径即可导出文件,在junit测试类中修改for循环的i可以模拟百万级数据导出。注意...
  • Java实现导出excel表格功能,大部分都会使用apache poi,apache poi API 地址 POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小效果也不是太好。3.8版本的POI新出来了...

    Java实现导出excel表格功能,大部分都会使用apache poi,apache poi API 地址 
    POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小效果也不是太好。3.8版本的POI新出来了SXSSFWorkbook,可以支持大数据量的操作,只是SXSSFWorkbook只支持.xlsx格式,不支持.xls格式。 
    3.8版本的POI对excel的导出操作,一般只使用HSSFWorkbook以及SXSSFWorkbook,HSSFWorkbook用来处理较少的数据量,SXSSFWorkbook用来处理大数据量以及超大数据量的导出。 
    代码: 
    git地址 有3.9jar包

    package qs.test;
     
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
     
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.util.CellReference;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
     
    /**
     * ClassName: SXSSFTest
     * @Description: TODO
     * @author qiaoshuai
     */
    public class SXSSFTest {
     
        public static void main(String[] args) throws IOException {
            // 创建基于stream的工作薄对象的
            SXSSFWorkbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory,
                                                        // exceeding rows will be
                                                        // flushed to disk
            // SXSSFWorkbook wb = new SXSSFWorkbook();
            // wb.setCompressTempFiles(true); // temp files will be gzipped
            Sheet sh = wb.createSheet();
            // 使用createRow将信息写在内存中。
            for (int rownum = 0; rownum < 1000; rownum++) {
                Row row = sh.createRow(rownum);
                for (int cellnum = 0; cellnum < 10; cellnum++) {
                    Cell cell = row.createCell(cellnum);
                    String address = new CellReference(cell).formatAsString();
                    cell.setCellValue(address);
                }
     
            }
     
            // Rows with rownum < 900 are flushed and not accessible
            // 当使用getRow方法访问的时候,将内存中的信息刷新到硬盘中去。
            for (int rownum = 0; rownum < 900; rownum++) {
                System.out.println(sh.getRow(rownum));
            }
     
            // ther last 100 rows are still in memory
            for (int rownum = 900; rownum < 1000; rownum++) {
                System.out.println(sh.getRow(rownum));
            }
            // 写入文件中
            FileOutputStream out = new FileOutputStream("G://sxssf.xlsx");
            wb.write(out);
            // 关闭文件流对象
            out.close();
            System.out.println("基于流写入执行完毕!");
        }
     
    }

    SXSSFWorkbook workbook = new SXSSFWorkbook(100);

     

    private void setSheetFinishStyle(Sheet sheet, int colSize)
    {
        for (int i = 0; i < colSize; i++)
        {
            if ((sheet instanceof SXSSFSheet)) {
                ((SXSSFSheet)sheet).trackAllColumnsForAutoSizing();
            }
            sheet.autoSizeColumn((short)i);
        }
    
        sheet.createFreezePane(0, 1, 0, 1);
    }
    展开全文
  • maven 依赖 (版本必须一致,否则使用SXSSFworkbook 时...org.apache.poi&lt;/groupId&gt; &lt;artifactId&gt;poi&lt;/artifactId&gt; &lt;version&gt;3.9&lt;/version&gt;

    maven 依赖 (版本必须一致

    ,否则使用SXSSFworkbook 时程序会报错)

    <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>3.9</version>
        </dependency>
        <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-ooxml</artifactId>
          <version>3.9</version>
        </dependency>

    HSSFworkbook,XSSFworkbook,SXSSFworkbook 三者 区别

    HSSFworkbook:操作Excel2003版本,扩展名为xls

    XSSFworkbook:操作Excel2007版本,扩展名为xlsx

    SXSSFworkbook :用于大数据量导出,当数据量超过 65536后 程序 会报错:Invalid row number (65536) outside allowable range (0..65535)


    例子1:简单导出Excel

    @Test
        public void test1() throws IOException {
            // 读取文件
            POIFSFileSystem fs = new POIFSFileSystem(Thread.currentThread().getContextClassLoader().getResourceAsStream("test.xls"));
            // 创建一个工作簿
            HSSFWorkbook workbook = new HSSFWorkbook(fs);
            // 获取第一个sheet
            HSSFSheet sheet = workbook.getSheetAt(0);
            System.out.println(sheet.getSheetName());
            // 获取第一行
            HSSFRow row = sheet.getRow(0);
            // 获取第一行第一列
            HSSFCell cell = row.getCell(0);
            System.out.println(cell.getStringCellValue());
    
            // 创建一行
            HSSFRow row1 = sheet.createRow(1);
            // 创建单元格
            HSSFCell cell1 = row1.createCell(0);
            // 单元格赋值
            cell1.setCellValue("我是程序创建的内容");
            System.out.println(cell1.getStringCellValue());
    
            // 创建输出流
            FileOutputStream os = new FileOutputStream(new File("D:\\8888.xls"));
            // 输出文件
            workbook.write(os);
        }

    例子2:导出查询数据

    @Test
        public void test2() {
            // 模拟导出数据
            Object[] obj = new Object[]{"哈哈", "呵呵", "哼哼"};
            List<Object[]> list = new ArrayList<Object[]>();
            // HSSFWorkbook 只支持2003版本及以下版本Excel 且容量最大为65536
            for (int i = 0; i < 65536; i++) {
                list.add(obj);
            }
    
            export("test.xls", list, 2);
        }
    
        /**
         * poi 导出
         * @param fileName
         * @param objs
         * @param rowIndex
         */
        private void export(String fileName, List<Object[]> objs, int rowIndex) {
            POIFSFileSystem fs = null;
            FileOutputStream os = null;
            try {
                fs = new POIFSFileSystem(Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName));
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 创建一个工作簿
            try {
                HSSFWorkbook workbook = new HSSFWorkbook(fs);
                HSSFCellStyle style = setCellStyle(workbook);
                // 获取一个sheet页
                HSSFSheet sheet = workbook.getSheetAt(0);
    
                for (int i = rowIndex - 1; i < objs.size(); i++) {
                    // 创建行
                    HSSFRow row = sheet.createRow(i);
    
                    // 创建列
                    for (int j = 0; j < objs.get(i).length; j++) {
                        HSSFCell cell = row.createCell(j);
                        // 设置单元格样式
                        cell.setCellStyle(style);
                        cell.setCellValue(objs.get(i)[j].toString());
                    }
                }
                // 创建输出流
                 os = new FileOutputStream(new File("D:\\8888.xls"));
                // 输出文件
                workbook.write(os);
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if (os != null) {
                    try {
                        os.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    
        /**
         * 设置样式
         * @param workbook
         */
        private HSSFCellStyle setCellStyle(HSSFWorkbook workbook) {
            HSSFCellStyle style = workbook.createCellStyle();
            HSSFFont font = workbook.createFont();
            // 字号
            font.setFontHeightInPoints((short) 12);
            style.setFont(font);
            // 左右居中 上下居中
            style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
            style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
            return style;
        }

    例子3:大数据量导出

    /**
         * 大数据量导出
         * @throws IOException
         */
        @Test
        public void text2() throws IOException {
    
            XSSFWorkbook xssfWorkbook = new   XSSFWorkbook(Thread.currentThread().getContextClassLoader().getResourceAsStream("bigdata.xlsx"));
            SXSSFWorkbook wb = new SXSSFWorkbook(xssfWorkbook, 100);
    
            Sheet sh = wb.getSheetAt(0);
            for(int rownum = 1; rownum < 75537; rownum++){
                Row row = sh.createRow(rownum);
                for(int cellnum = 0; cellnum < 10; cellnum++){
                    Cell cell = row.createCell(cellnum);
                    String address = new CellReference(cell).formatAsString();
                    cell.setCellValue(address);
                }
    
            }
    
    //        // Rows with rownum < 900 are flushed and not accessible
    //        for(int rownum = 0; rownum < 900; rownum++){
    //            Assert.assertNull(sh.getRow(rownum));
    //        }
    //
    //        // ther last 100 rows are still in memory
    //        for(int rownum = 900; rownum < 1000; rownum++){
    //            Assert.assertNotNull(sh.getRow(rownum));
    //        }
    
            FileOutputStream out = new FileOutputStream("D:\\sxssf.xlsx");
            wb.write(out);
            out.close();
    
            // dispose of temporary files backing this workbook on disk
            wb.dispose();
        }

    展开全文
  • POI 导入导出功能,引用jar包是关键,maven依赖支持1.37版. 介绍: 首先,理解一下一个Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(页/表)...

    POI 导入导出功能,引用jar包是关键,maven依赖支持3.17版.

    介绍:

    首先,理解一下一个Excel的文件的组织形式,一个Excel文件对应于一个workbook(HSSFWorkbook),一个workbook可以有多个sheet(页/表)(HSSFSheet)组成,一个sheet是由多个row(行)(HSSFRow)组成,一个row是由多个cell(单元格)(HSSFCell)组成。
    1、用HSSFWorkbook打开或者创建“Excel文件对象
    2、用HSSFWorkbook对象返回或者创建Sheet对象
    3、用Sheet对象返回行对象,用行对象得到Cell对象
    4、对Cell对象读写

    maven 依赖:

    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi</artifactId>
        <version>3.17</version>
    </dependency>
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.17</version>
    </dependency>
    

    mvc 依赖:

    poi-3.7-20101029.jar
    poi-3.9.jar
    poi-ooxml-3.9.jar
    poi-ooxml-schemas-3.9.jar
    

    ExcelUtil.java (导入导出工能封装)

    import com.alibaba.fastjson.JSONArray;
    import com.alibaba.fastjson.JSONObject;
    import org.apache.poi.common.usermodel.HyperlinkType;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.streaming.SXSSFCell;
    import org.apache.poi.xssf.streaming.SXSSFRow;
    import org.apache.poi.xssf.streaming.SXSSFSheet;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFHyperlink;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.math.BigDecimal;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    /**
     * Created by cdw on 2018/04/19.
     *
     * Apache POI操作Excel对象 HSSF:操作Excel 2007之前版本(.xls)格式,生成的EXCEL不经过压缩直接导出
     * XSSF:操作Excel 2007及之后版本(.xlsx)格式,内存占用高于HSSF SXSSF:从POI3.8
     * beta3开始支持,基于XSSF,低内存占用,专门处理大数据量(建议)。
     *
     * 注意: 值得注意的是SXSSFWorkbook只能写(导出)不能读(导入)
     *
     * 说明: .xls格式的excel(最大行数65536行,最大列数256列) .xlsx格式的excel(最大行数1048576行,最大列数16384列)
     * 这里引用的是阿里的json包,也可以自行转换成net.sf.json.JSONArray net.sf.json.JSONObject
     */
    public class ExcelUtil {
    
    	private final static String Excel_2003 = ".xls"; // 2003 版本的excel
    	private final static String Excel_2007 = ".xlsx"; // 2007 版本的excel
    
    	public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 默认日期格式(类型为Date即可转换)
    	public static final int DEFAULT_COLUMN_WIDTH = 17; // 默认列宽
    
    	/**
    	 * 导入Excel
    	 *
    	 * @param file
    	 *            输入文件流
    	 */
    	public static List<List<Object>> importExcel(@RequestParam(value = "file", required = false) MultipartFile file)
                throws Exception {
    		String fileName = file.getOriginalFilename();
    		String xls = fileName.substring(fileName.lastIndexOf('.'));
    		if (Excel_2003.equals(xls) || Excel_2007.equals(xls)) {
    			return ExcelUtil.getImportExcel(file);
    		} else {
    			// 导入格式不正确
    			System.out.println("导入格式不正确:导入失败!");
    		}
    		return null;
    	}
    
    	/**
    	 * 导出Excel
    	 *
    	 * @param titleList
    	 *            表格头信息集合
    	 * @param dataArray
    	 *            数据数组
    	 * @param os
    	 *            文件输出流
    	 */
    	public static void exportExcel(ArrayList<LinkedHashMap> titleList, JSONArray dataArray, OutputStream os)
    			throws Exception {
    		ExcelUtil.getExportExcel(titleList, dataArray, os);
    	}
    
    	/**
    	 * 导入Excel
    	 *
    	 * @param file
    	 *            导入文件流对象
    	 */
    	private static List<List<Object>> getImportExcel(MultipartFile file) throws Exception {
    		ImportExcelUtil util = new ImportExcelUtil();
    		String fileName = file.getOriginalFilename();
    		InputStream inputStream = file.getInputStream();
    		// 将导入的Excel数据转换成list集合
    		List<List<Object>> excelLists = util.getBankListByExcel(inputStream, fileName);
    		// 获取工作模板行数据对象
    //        HSSFWorkbook workbook = new HSSFWorkbook(new POIFSFileSystem(inputStream));
            // 或
    //        Workbook workbook = util.getWorkbook(inputStream, fileName);
    //
    //		for (int i = 0; i < excelLists.size(); i++) { // 循环行
    //			List<Object> list = excelLists.get(i); // 获取行级列集合
    //			for (int j = 0; j < list.size(); j++) {
    //				System.out.println("获取" + i + "行级" + j + "列的值:" + list.get(j));
    //			}
    //		}
    //
    //		for (List<Object> excelList : excelLists) { // 循环行
    //			for (Object obj : excelList) { // 循环列
    //				// 获取行级列的值
    //			}
    //		}
    //
    //        for (Sheet rows : workbook) { // 循环行
    //            for (Row row : rows) { // 循环列
    //                // 获取行级列的值
    //            }
    //        }
    		return excelLists;
    	}
    
    	/**
    	 * 导出Excel
    	 *
    	 * @param titleList
    	 *            表格头信息集合
    	 * @param dataArray
    	 *            数据数组
    	 * @param os
    	 *            文件输出流
    	 */
    	private static void getExportExcel(ArrayList<LinkedHashMap> titleList, JSONArray dataArray, OutputStream os)
    			throws Exception {
    		String datePattern = DEFAULT_DATE_PATTERN;
    		int minBytes = DEFAULT_COLUMN_WIDTH;
    
    		/**
    		 * 声明一个工作薄
    		 */
    		SXSSFWorkbook workbook = new SXSSFWorkbook(1000);// 大于1000行时会把之前的行写入硬盘
    		workbook.setCompressTempFiles(true);
    
    		// 表头1样式
    		CellStyle title1Style = workbook.createCellStyle();
    		title1Style.setAlignment(HorizontalAlignment.CENTER);// 水平居中
    		title1Style.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
    		Font titleFont = workbook.createFont();// 字体
    		titleFont.setFontHeightInPoints((short) 20);
    		titleFont.setBold(true);
    		titleFont.setFontHeight((short) 700);
    		title1Style.setFont(titleFont);
    
    		// 表头2样式
    		CellStyle title2Style = workbook.createCellStyle();
    		title2Style.setAlignment(HorizontalAlignment.CENTER);
    		title2Style.setVerticalAlignment(VerticalAlignment.CENTER);
    		title2Style.setBorderTop(BorderStyle.THIN);// 上边框
    		title2Style.setBorderRight(BorderStyle.THIN);// 右
    		title2Style.setBorderBottom(BorderStyle.THIN);// 下
    		title2Style.setBorderLeft(BorderStyle.THIN);// 左
    		Font title2Font = workbook.createFont();
    		title2Font.setUnderline((byte) 1);
    		title2Font.setColor(HSSFColor.BLUE.index);
    		title2Style.setFont(title2Font);
    
    		// head样式
    		CellStyle headerStyle = workbook.createCellStyle();
    		headerStyle.setAlignment(HorizontalAlignment.CENTER);
    		headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    		headerStyle.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);// 设置颜色
    		headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 前景色纯色填充
    		headerStyle.setBorderTop(BorderStyle.THIN);
    		headerStyle.setBorderRight(BorderStyle.THIN);
    		headerStyle.setBorderBottom(BorderStyle.THIN);
    		headerStyle.setBorderLeft(BorderStyle.THIN);
    		Font headerFont = workbook.createFont();
    		headerFont.setFontHeightInPoints((short) 12);
    		headerFont.setBold(true); // 是否加粗
    		headerFont.setFontHeight((short) 500); // 字体大小
    		headerStyle.setFont(headerFont);
    
    		// 单元格样式
    		CellStyle cellStyle = workbook.createCellStyle();
    		cellStyle.setAlignment(HorizontalAlignment.CENTER);
    		cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
    		cellStyle.setBorderTop(BorderStyle.THIN);
    		cellStyle.setBorderRight(BorderStyle.THIN);
    		cellStyle.setBorderBottom(BorderStyle.THIN);
    		cellStyle.setBorderLeft(BorderStyle.THIN);
    		Font cellFont = workbook.createFont();
    		cellFont.setBold(false); // 是否加粗
    		cellFont.setFontHeight((short) 300); // 字体大小
    		cellStyle.setFont(cellFont);
    
    		String title1 = (String) titleList.get(0).get("title1");
    		String title2 = (String) titleList.get(0).get("title2");
    		LinkedHashMap<String, String> headMap = titleList.get(1);
    
    		/**
    		 * 生成一个(带名称)表格
    		 */
    		SXSSFSheet sheet = (SXSSFSheet) workbook.createSheet(title1);
    		sheet.createFreezePane(0, 3, 0, 3);// (单独)冻结前三行
    
    		/**
    		 * 生成head相关信息+设置每列宽度
    		 */
    		int[] colWidthArr = new int[headMap.size()];// 列宽数组
    		String[] headKeyArr = new String[headMap.size()];// headKey数组
    		String[] headValArr = new String[headMap.size()];// headVal数组
    		int i = 0;
    		for (Map.Entry<String, String> entry : headMap.entrySet()) {
    			headKeyArr[i] = entry.getKey();
    			headValArr[i] = entry.getValue();
    
    			int bytes = headKeyArr[i].getBytes().length;
    			colWidthArr[i] = bytes < minBytes ? minBytes : bytes;
    			sheet.setColumnWidth(i, colWidthArr[i] * 256);// 设置列宽
    			i++;
    		}
    
    		/**
    		 * 遍历数据集合,产生Excel行数据,除去 title + head 数据起始行为0,赋值为3(即第四行起)
    		 */
    		int rowIndex = 0;
    		for (Object obj : dataArray) {
    			// 生成title+head信息
    			if (rowIndex == 0) {
    				SXSSFRow title1Row = (SXSSFRow) sheet.createRow(0);// title1行
    				title1Row.createCell(0).setCellValue(title1);
    				title1Row.getCell(0).setCellStyle(title1Style);
    				sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headMap.size() - 1));// 合并单元格
    
    				SXSSFRow title2Row = (SXSSFRow) sheet.createRow(1);// title2行
    				title2Row.createCell(0).setCellValue(title2);
    
    				CreationHelper createHelper = workbook.getCreationHelper();
    				XSSFHyperlink hyperLink = (XSSFHyperlink) createHelper.createHyperlink(HyperlinkType.URL);
    				hyperLink.setAddress(title2);
    				title2Row.getCell(0).setHyperlink(hyperLink);// 添加超链接
    
    				title2Row.getCell(0).setCellStyle(title2Style);
    				sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, headMap.size() - 1));// 合并单元格
    
    				SXSSFRow headerRow = (SXSSFRow) sheet.createRow(2);// head行
    				for (int j = 0; j < headValArr.length; j++) {
    					headerRow.createCell(j).setCellValue(headValArr[j]);
    					headerRow.getCell(j).setCellStyle(headerStyle);
    				}
    				rowIndex = 3;
    			}
    
    			JSONObject jo = (JSONObject) JSONObject.toJSON(obj);
    			// 生成数据
    			SXSSFRow dataRow = (SXSSFRow) sheet.createRow(rowIndex);// 创建行
    			for (int k = 0; k < headKeyArr.length; k++) {
    				SXSSFCell cell = (SXSSFCell) dataRow.createCell(k);// 创建单元格
    				Object o = jo.get(headKeyArr[k]);
    				String cellValue = "";
    
    				if (o == null) {
    					cellValue = "";
    				} else if (o instanceof Date) {
    					cellValue = new SimpleDateFormat(datePattern).format(o);
    				} else if (o instanceof Float || o instanceof Double) {
    					cellValue = new BigDecimal(o.toString()).setScale(2, BigDecimal.ROUND_HALF_UP).toString();
    				} else {
    					cellValue = o.toString();
    				}
    
    				cell.setCellValue(cellValue);
    				cell.setCellStyle(cellStyle);
    			}
    			rowIndex++;
    		}
    
    //      // 另外一种导出方式
    //		HSSFWorkbook workbook = new HSSFWorkbook();
    //		HSSFSheet sheet = workbook.createSheet("测试表");
    //		HSSFRow titleRow = sheet.createRow(0);
    //		sheet.setColumnWidth(titleRow.createCell(0).getColumnIndex(), 256 * 20);
    //		titleRow.createCell(0).setCellValue("名称");
    //		sheet.setColumnWidth(titleRow.createCell(1).getColumnIndex(), 256 * 20);
    //		titleRow.createCell(1).setCellValue("状态(0-已生成,1-待生成)");
    //		// 设置应用类型,以及编码
    //		response.setContentType("application/msexcel;charset=utf-8");
    //		response.setHeader("Content-Disposition", "filename=" + new String("测试表.xls".getBytes("gb2312"), "iso8859-1"));
    //		workbook.write(output);
    //		output.flush();
    //		output.close();
    
    		try {
    			workbook.write(os);
    			os.flush();// 刷新此输出流并强制将所有缓冲的输出字节写出
    			os.close();// 关闭流
    			workbook.dispose();// 释放workbook所占用的所有windows资源
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    
    }
    

    ImportExcelUtil.java (Excel数据转换类)

    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFDataFormat;
    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.xssf.usermodel.XSSFWorkbook;
    
    import java.io.InputStream;
    import java.text.DecimalFormat;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * Created by cdw on 2018/04/19.
     *
     * 转换类
     *
     * 说明: .xls格式的excel(最大行数65536行,最大列数256列) .xlsx格式的excel(最大行数1048576行,最大列数16384列)
     */
    public class ImportExcelUtil {
    	
    	private final static String Excel_2003 = ".xls"; //2003 版本的excel
    	private final static String Excel_2007 = ".xlsx"; //2007 版本的excel
    
    	/**
    	 * @param in
    	 * @param fileName
    	 *
    	 * @return
    	 */
    	public List<List<Object>> getBankListByExcel(InputStream in, String fileName) throws Exception {
    		List<List<Object>> list = null;
    
    		//创建Excel工作簿
    		Workbook work = this.getWorkbook(in, fileName);
    		if (work == null) {
    			throw new Exception("创建Excel工作簿为空!");
    		}
    		Sheet sheet = null;
    		Row row = null;
    		Cell cell = null;
    		list = new ArrayList<List<Object>>();
    		//遍历Excel中的所有sheet
    		for (int i = 0; i < work.getNumberOfSheets(); i++) {
    			sheet = work.getSheetAt(i);
    			if (sheet == null) {
    				continue;
    			}
    			//遍历当前sheet中的所有行
    			//int totalRow = sheet.getPhysicalNumberOfRows();//如果excel有格式,这种方式取值不准确
    			int totalRow = sheet.getPhysicalNumberOfRows();
    			for (int j = sheet.getFirstRowNum(); j < totalRow; j++) {
    				row = sheet.getRow(j);
    				if (!isRowEmpty(row)) {
    					//if(row != null && !"".equals(row)) {
    					//获取第一个单元格的数据是否存在
    					Cell fristCell = row.getCell(0);
    					if (fristCell != null) {
    						//遍历所有的列
    						List<Object> li = new ArrayList<Object>();
    						//int totalColum = row.getLastCellNum();
    						for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
    							cell = row.getCell(y);
    							String callCal = this.getCellValue(cell) + "";
    							li.add(callCal);
    						}
    						list.add(li);
    					}
    
    				} else if (isRowEmpty(row)) {
    					continue;
    				}
    
    			}
    		}
    		in.close();
    		return list;
    	}
    
    	/**
    	 * 判断行是否为空
    	 *
    	 * @param row
    	 *
    	 * @return
    	 */
    	public static boolean isRowEmpty(Row row) {
    		for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
    			Cell cell = row.getCell(c);
    			if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK)
    				return false;
    		}
    		return true;
    	}
    
    	/**
    	 * 描述:根据文件后缀,自动适应上传文件的版本
    	 *
    	 * @param inStr,fileName
    	 *
    	 * @return
    	 *
    	 * @throws Exception
    	 */
    	public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
    		Workbook work = null;
    		String fileType = fileName.substring(fileName.lastIndexOf("."));
    		if (Excel_2003.equals(fileType)) {
    			work = new HSSFWorkbook(inStr);//2003 版本的excel
    		} else if (Excel_2007.equals(fileType)) {
    			work = new XSSFWorkbook(inStr);//2007 版本的excel
    		} else {
    			throw new Exception("解析文件格式有误!");
    		}
    		return work;
    	}
    
    	/**
    	 * 描述:对表格中数值进行格式化
    	 *
    	 * @param cell
    	 *
    	 * @return
    	 */
    	public Object getCellValue(Cell cell) {
    		/*Object value = null;
    		DecimalFormat df1 = new DecimalFormat("0.00");//格式化number,string字符
    		SimpleDateFormat sdf = new  SimpleDateFormat("yyy-MM-dd");//日期格式化
    		DecimalFormat df2 = new DecimalFormat("0.00");//格式化数字
    		if(cell !=null && !"".equals(cell)) {
    			switch (cell.getCellType()) {
    			case Cell.CELL_TYPE_STRING:
    				value = cell.getRichStringCellValue().getString();
    				break;
    			case Cell.CELL_TYPE_NUMERIC:
    				if("General".equals(cell.getCellStyle().getDataFormatString())) {
    					value = df1.format(cell.getNumericCellValue());
    				}else if("m/d/yy".equals(cell.getCellStyle().getDataFormatString())) {
    					value = sdf.format(cell.getDateCellValue());
    				}else if(HSSFDateUtil.isCellDateFormatted(cell)){
    					Date date = cell.getDateCellValue();
    					value = sdf.format(date);				
    				}
    				else {
    					value = df2.format(cell.getNumericCellValue());
    				}
    				break;
    			case Cell.CELL_TYPE_BOOLEAN:
    				value = cell.getBooleanCellValue();
    				break;
    			case Cell.CELL_TYPE_BLANK:
    				value = "";
    				break;
    			default:
    				break;
    			}
    		}		
    		return value;*/
    		String result = new String();  
            switch (cell.getCellType()) {  
            case HSSFCell.CELL_TYPE_FORMULA:  //Excel公式
                try {  
                	result = String.valueOf(cell.getNumericCellValue());  
                } catch (IllegalStateException e) {  
                	result = String.valueOf(cell.getRichStringCellValue());
                }  
                break;
            case HSSFCell.CELL_TYPE_NUMERIC:// 数字类型  
                if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
                    SimpleDateFormat sdf;
                    if (cell.getCellStyle().getDataFormat() == HSSFDataFormat
                            .getBuiltinFormat("h:mm")) {  
                        sdf = new SimpleDateFormat("HH:mm");  
                    } else {// 日期  
                        sdf = new SimpleDateFormat("yyyy-MM-dd");  
                    }  
                    Date date = cell.getDateCellValue();  
                    result = sdf.format(date);  
                } else if (cell.getCellStyle().getDataFormat() == 58) {  
                    // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)  
                    SimpleDateFormat sdf = new SimpleDateFormat("M月d日");  
                    double value = cell.getNumericCellValue();  
                    Date date = org.apache.poi.ss.usermodel.DateUtil
                            .getJavaDate(value);  
                    result = sdf.format(date);  
                } else {  
                    double value = cell.getNumericCellValue();  
                    CellStyle style = cell.getCellStyle();
                    DecimalFormat format = new DecimalFormat();
                    String temp = style.getDataFormatString();  
                    // 单元格设置成常规  
                    if (temp.equals("General")) {  
                        format.applyPattern("#.##");  
                    }  
                    result = format.format(value);  
                }  
                break;  
            case HSSFCell.CELL_TYPE_STRING:// String类型  
                result = cell.getRichStringCellValue().toString();  
                break;  
            case HSSFCell.CELL_TYPE_BLANK:  
                result = "";  
            default:  
                result = "";  
                break;  
            }  
            return result;  
    	}
    	
    	public String getFormat(String str) {
    		if(str.equals("null")) {
    			str="";
    			return str;
    		}else{
    			return str;
    		}	
    	}
    	public Integer getFormats(Integer str) {
    		if(str==null) {
    			str=0;
    			return str;
    		}else{
    			return str;
    		}	
    	}
    
    	/**
    	 * 获取字符串中的数字订单号、数字金额等,如从"USD 374.69"中获取到374.69、从“交易单号:123456789”获取到123456789
    	 *
    	 * @return
    	 */
    	public static String getFormatNumber(String str){
    		str = str.trim();
    		 Pattern p = Pattern.compile("[0-9]");
    		 int indexNum = 0;
    		 int lenght = str.length();
    		 String num = "";
    		 for(int i=0;i<lenght;i++){
    			num += str.charAt(i);
    		 	Matcher m = p.matcher(num);
    		 	if(m.find()){
    		 		indexNum = i;
    		 		break;
    		 	}
    		  }
    		 String formatNumber = str.substring(indexNum,lenght);
    		 return formatNumber;
    	}
    }
    

    导出功能引用方法:

    // 导出
    @ResponseBody
    @RequestMapping(value = "/excelOut", method = RequestMethod.GET)
    public String excelOut(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 获得输出流
            OutputStream output = response.getOutputStream();
    
            ArrayList<LinkedHashMap> titleList = new ArrayList<LinkedHashMap>();
            LinkedHashMap<String, String> titleMap = new LinkedHashMap<String, String>();
            // title1设置标题,key固定
            titleMap.put("title1", "测试导出表");
            titleMap.put("title2", "测试导出表链接");
    
            LinkedHashMap<String, String> headMap = new LinkedHashMap<String, String>();
            headMap.put("ranking", "序号");
            headMap.put("posterName", "名称");
            headMap.put("status", "状态");
            titleList.add(titleMap);
            titleList.add(headMap);
    
            // 数据集合,下面的字段名必须和上面的map对象key或者数据实体类参数保持一致
            List<JSONObject> objects = new ArrayList<JSONObject>();
            for (int i = 0; i < 20; i++) {
                JSONObject result = new JSONObject();
                result.put("ranking", "value" + i);
                result.put("posterName", "value" + i);
                result.put("status", "value" + i);
                objects.add(result);
            }
            JSONArray objectsList = JSONArray.parseArray(objects.toString());
            // 设置应用类型,以及编码
            response.setContentType("application/msexcel;charset=utf-8");
            response.setHeader("Content-Disposition",
                    "filename=" + new String("测试导出表.xlsx/测试导出表.xls".getBytes("gb2312"), "iso8859-1"));
            ExcelUtil.exportExcel(titleList, objectsList, output);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }
    

    导入功能引用方法:

    // 导入
    @ResponseBody
    @RequestMapping(value = "/excelIn", method = RequestMethod.POST)
    public String excelIn(@RequestParam(value = "file", required = false) MultipartFile file,
                          HttpServletResponse response) {
        try {
            List<List<Object>> lists = ExcelUtil.importExcel(file);
            System.out.println("导入结果:" + lists.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }
    

    导入功能前台引用文件:

    文件引用
    jquery.min.js
    jquery.form.js
    

    导入功能前台处理方法:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <!DOCTYPE html>
    <head>
        <title>导入导出-导入页面</title>
        <script src="${pageContext.request.contextPath}/js/jquery.min.js?v=2.1.4"></script>
        <script src="${pageContext.request.contextPath}/js/jquery.form.js?v=2.1.4"></script>
        <script src="${pageContext.request.contextPath}/js/bootstrap.min.js?v=3.3.6"></script>
    </head>
    <body>
    <!--导入-->
    <form action="/user/excelIn" enctype="multipart/form-data" method="post" id="fileForm" name="fileForm">
        <input type="file" id="file" name="file" accept="application/vnd.ms-excel" onchange="chooseFile(this.value)">
        <input type="button" value="选择文件" class="filebtn" id="filebtn"/>
        <input type="text" id="filetxt" class="filetxt" readonly>
        <input type="submit" value="上传Excel" id="importbtn" class="importbtn"/>
    </form>
    <script>
        function exportExcel() {
            // 导出接口地址
            window.location.href = "http://127.0.0.1:8081/user/excelIn";
        }
    
        //触发file change事件
        function chooseFile(path) {
            if (path) {
                $('#filetxt').val(path);
            } else {
                $('#filetxt').attr('readonly', true);
            }
        }
    
        $(function () {
            $("#fileForm").ajaxForm({
                beforeSubmit: function () {
                    // 表单数据提交之前的操作
                },
                success: function (obj) {
                    console.log("导入结果:" + obj);
                },
                error: function (msg) {
                    console.log("导入错误:" + msg);
                }
            });
        });
    </script>
    </body>
    </html>
    

    示例:

    导入结果:[[测试导出表], [测试导出表链接], [序号, 名称, 状态], [value0, value0, value0], [value1, value1, value1], [value2, value2, value2], [value3, value3, value3], [value4, value4, value4], [value5, value5, value5], [value6, value6, value6], [value7, value7, value7], [value8, value8, value8], [value9, value9, value9], [value10, value10, value10], [value11, value11, value11], [value12, value12, value12], [value13, value13, value13], [value14, value14, value14], [value15, value15, value15], [value16, value16, value16], [value17, value17, value17], [value18, value18, value18], [value19, value19, value19]]

    导出结果:
    导出结果展示

    以上就是完整的导入导出功能,支持大数据量快速导出,导入.

    转载请注明出处!

    展开全文
  • 官网介绍地址(页面最下方SXSSF (Since POI 3.8 beta3) 从3.8-beta3版本开始,POI提供了一个低内存的SXSSF API构建在XSSF之上。 SXSSF是XSSF的API兼容的流扩展,当必须产生非常大的sheet表格,并且堆空间有限时使用...
  • Java当中常用的Excel文档导出主要有POI、JXL和“直接IO流”这三种方式,三种方式各自分别有不同的优势与缺点,下面将分行对其进行单介绍。 导出常用文件格式 1. Excel2003格式 Excel2003支持每个工作表中最多有 ...
  • /** * @author one.xu ... * @description excel 导出支持多excel 多sheet * @date 2019/4/3 16:14 */ @Slf4j public abstract class AbstractPoiExcelExport<T> { public static final String...
  • Excel2003版最大行数是65536行。Excel2007开始的版本最大行数是...poi导出excel,不使用模板的 http://happyqing.iteye.com/blog/2075985   xls格式导出使用HSSFWorkbook,(这个暂时没有好办法)   xlsx格式...
  • 转载地址http://blog.csdn.net/yys79/article/details/26443603
  • POI导出大数据量excel(注:项目源码及后续更新请点击)1、ExcelUtils类:package Utils; import com.alibaba.fastjson.JSONArray; ... import org.apache.poi.common.usermodel.Hyperlink; import org....
  • POI3.8的SXSSF包是XSSF的一个扩展版本,支持流处理,在生成大数据量的电子表格且堆空间有限时使用。SXSSF通过限制内存中可访问的记录行数来实现其低内存利用,当达到限定值时,新一行数据的加入会引起老一行的数据...
  • 问题: 当数据量大的时候用POI工具包提供的API创建Excel报错原因分析: 可能数据量大导致数据查询超时或者是请求超时系统采用的是Apache POI工具进行Excel的创建和导出,会不会是提供的API不能满足大数据处理的...
  • 今天博主在研究Excel大数据导出性能,发现个意外惊喜,给大家分享下。 第一次博主使用的是POI ExcelHSSF的导出方式: 这种方法是Excel 2003版本常用的一种导出方式。 以19.5W数据为例,导出耗时36秒 ...
  •  pmdb项目中需要导出excel文件,因为文件格式为最简单的表格样式,所以编写了一个通用的方法,通过输入查询出来的数据,生成excel,使用自适应的方式设置列宽。这时候虽然根据表格内容设置的列宽满足要求,但是表头...
  • POI3.8解决导出大数据量excel文件时内存溢出的问题 博客分类: 2012年10月 poiexcel大数据量导出内存溢出 POI3.8的SXSSF包是XSSF的一个扩展版本,支持流处理,在生成大数据量的电子表格且堆空间有限时使用。SXSSF...
  •  上面两个类导出excel的时候数据会驻留在内存中,所以当数据量大的时候容易造成内存溢出。SXSSFWorkbook是用来生成海量excel数据文件,主要原理是借助临时存储空间生成excel。POI要求3.8以上,生成的文件格式要求是07...
  • for (int col = 0; col &lt; 20; ++col) { detailSheet.autoSizeColumn(col);//只支持英文和数字 int columnWidth = detailSheet.getColumnWidth(col) / 256; for (int row = 0; row &...
  • 注意使用SXSSFWorkbook此类在构造表格和处理行高的时候效率极高,刚开始时我使用的XSSFWorkbook 就出现构造表格效率极低,一万行基本需要3秒左右,那当导出百万级数据就慢的要死啦,而且他会让内存溢出 POI3.8的...
1 2 3 4 5
收藏数 96
精华内容 38