• Java实现导出excel表格功能,大部分都会使用apache poi, apache poi API 地址

    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("基于流写入执行完毕!");
        }
    
    }
    

    在此基础上再优化的方案是导出的Excel表格生成多个工作表即生成多个sheet。
    代码:

    import java.io.IOException;
    import java.io.UnsupportedEncodingException;
    import java.net.URLEncoder;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.LinkedHashMap;
    import java.util.List;
    
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    
    import com.common.DateFormatUtil;
    
    public class ExlUtil2 {
    
        /**
         * @param excelHeader
         *            表头信息
         * @param list
         *            要导出到excel的数据源,List类型
         * @param sheetName
         *            表名
         * @return
         */
        public static ResponseEntity<byte[]> getDataStream(ExcelHeader excelHeader,
                List list, String sheetName) {
            LinkedHashMap<String, List> map = new LinkedHashMap<String, List>();
            List<String[]> headNames = new ArrayList<String[]>();
            List<String[]> fieldNames = new ArrayList<String[]>();
            String[] sheetNames = new String[100];
            //处理Excel生成多个工作表 
            //定义为每个工作表数据为50000条
            if (list.size() > 50000) {
                int k = (list.size() + 50000) / 50000;
                for (int i = 1; i <= k; i++) {
                    if (i < k) {
                        map.put(sheetName + i,
                                list.subList((i - 1) * 50000, i * 50000));
                    } else {
                        map.put(sheetName + i,
                                list.subList((i - 1) * 50000, list.size()));
                    }
    
                    headNames.add(excelHeader.getHeadNames().get(0));
                    fieldNames.add(excelHeader.getFieldNames().get(0));
                    sheetNames[i - 1] = sheetName;
                }
    
            } else {
                map.put(sheetName, list);
                headNames.add(excelHeader.getHeadNames().get(0));
                fieldNames.add(excelHeader.getFieldNames().get(0));
                sheetNames[0] = sheetName;
            }
    
            byte[] buffer = null;
    
            try {
                buffer = ExcelUtil2.output(headNames, fieldNames, sheetNames, map);
    
            } catch (IllegalArgumentException | IllegalAccessException
                    | IOException e) {
                e.printStackTrace();
            }
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    
            /*
             * try { sheetName=URLEncoder.encode(sheetName,"UTF8"); } catch
             * (UnsupportedEncodingException e) { e.printStackTrace(); }
             */
            try {
                sheetName = new String(sheetName.getBytes("gbk"), "iso-8859-1");
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            String fileGenerateTime = DateFormatUtil.toStr(new Date());
            headers.setContentDispositionFormData("attachment", sheetName
                    + fileGenerateTime + ".xlsx");
            return new ResponseEntity<byte[]>(buffer, headers, HttpStatus.CREATED);
        };
    
    }
    

    代码

    展开全文
  • POI 提供了 好几种生成Excel的方式,查看官方的API可以发现 第一种:HSSFWorkbook  针对是 EXCEL2003 版本,扩展名为 .xls;所以 此种的局限就是 导出的行数 至多为 65535 行,此种 因为行数不足七万行 所以 一般...

    POI 提供了 好几种生成Excel的方式,查看官方的API可以发现

    第一种:HSSFWorkbook 

    针对是 EXCEL2003 版本,扩展名为 .xls;所以 此种的局限就是 导出的行数 至多为 65535 行,此种 因为行数不足七万行 所以 一般不会发生 内存不足的情况(OOM)

    第二种:XSSFWorkbook 

    这种形式的出现 是由于 第一种HSSFWorkbook 的局限性而产生的,因为其所导出的行数比较少,所以 XSSFWookbook应运而生 其 对应的是EXCEL2007+(1048576行,16384列)扩展名 .xlsx,最多可以 导出 104 万行,不过 这样 就伴随着一个问题---OOM 内存溢出,原因是 你所 创建的 book sheet row cell 等 此时是存在 内存的 并没有 持久化,那么 随着 数据量增大  内存的需求量也就增大,那么很大可能就是要 OOM了,那么 怎么解决呢?

    第三种:SXSSFWorkbook  poi.jar 3.8+

    第二种遇到的问题该如何解决呢? 因为数据量过大 导致内存吃不消 那么 可以 让内存 到量持久化 吗? 

    答案是 肯定的,

    此种的情况 就是 设置 最大 内存条数 比如  设置 最大内存量为5000 rows  --new SXSSFWookbook(5000),此时 当 行数 达到 5000 时,把 内存 持久化 写到 文件中,以此 逐步 写入  避免OOM,那么这样 就完美解决了 大数据下 导出 的问题;


    明显发现最后一种是处理大数据的最好方式:

    //创建Excel的workbook 对象
    SXSSFWorkbook workbook = new SXSSFWorkbook(1000);
    //循环生成多个Sheet 页  如果需要
    			for(Map<String, Object> sheetTempMap : sheetList){
                    创建sheet 页名字
    				Sheet sheet = createSheetName(workbook, sheetTempMap);
    				//get column map 获取列头和列属性的Map 这部分的数据可以放到数据库里面,也可以写道js 文件上,方便灵活的生成列头,线上也可直接修改。
    				Map<String, String> columnMap = getColumnMap(sheetTempMap,outputVO);
    				if(CollectionUtils.isEmpty(columnMap)){
    					m_Logger.error("Column Map is empty,please setup.");
    					return outputVO; 
    				}
    				//create header
    				createHeader(columnMap, workbook, sheet,0);
    				//create line and write data 
                    //这里使用Mybatis返回Map 的数据类型,这样就可通过上面的columnMap直接获取数据
    				List<Map<String, Object>> resultMap = getResultListMap(sheetTempMap);
    				createLine(columnMap, resultMap, workbook, sheet);
    			}
    			List<File> files = new ArrayList<File>();
    			writeExcel(workbook,params,files);
    
    
    /**
    	 * create Header
    	 * @param workbook
    	 * @param sheetTempMap
    	 * @return
    	 */
    private void createHeader(Map<String, String> columnMap,SXSSFWorkbook workbook, Sheet sheet,int currentRow) {
    		CellStyle columnTopStyle = getColumnTopStyle(workbook);
    		Row rowRowName = sheet.createRow(currentRow);
    		int columnTemp = 0;
    		for (Map.Entry<String, String> headerMap : columnMap.entrySet()) {
    			Cell cellRowName = rowRowName.createCell(columnTemp);
    			cellRowName.setCellType(1);
    			XSSFRichTextString text = new XSSFRichTextString((String) headerMap.getKey());
    			cellRowName.setCellValue(text);
    			cellRowName.setCellStyle(columnTopStyle);
    			sheet.autoSizeColumn(columnTemp);
    			columnTemp++;
    		}
    	}
    
    private void createLine(Map<String, String> columnMap,List<Map<String, Object>> resultMap, SXSSFWorkbook workbook,Sheet sheet) {
    		CellStyle columnStyle = getStyle(workbook);
    		int rowCount = 1;
    		for (Map<String, Object> dataMap : resultMap) {
    			int rowColunmCount = 0;
    			Row row = sheet.createRow(rowCount);
    			for (Map.Entry<String, String> rowMap : columnMap.entrySet()) {
    				Cell cell = row.createCell(rowColunmCount);
    				cell.setCellType(1);
    				String currentValue = String.valueOf(dataMap.get(rowMap.getValue()));
    				XSSFRichTextString text = new XSSFRichTextString(currentValue);
    				if (String.valueOf(text).trim().equals("null".trim())) {
    					text = new XSSFRichTextString("");
    				}
    				cell.setCellValue(text);
    				cell.setCellStyle(columnStyle);
    				sheet.autoSizeColumn(rowColunmCount);
    				rowColunmCount++;
    			}
    			rowCount++;
    		}
    	}
    
    /**
    	 * create sheet name 
    	 * default vale is sheet1
    	 * @param workbook
    	 * @param sheetTempMap
    	 * @return
    	 */
    	private Sheet createSheetName(SXSSFWorkbook workbook,Map<String, Object> sheetTempMap) {
    		String sheetName = "sheet1";
    		if(sheetTempMap.containsKey("sheetName")){
    			sheetName = String.valueOf(sheetTempMap.get("sheetName"));
    		}
    		Sheet sheet = workbook.createSheet(sheetName);
    		return sheet;
    	}
    
    
    private Map<String,String> getColumnMap (){
        //这里使用了一个LinkedHashMap 使得数据有序化。
        Map<String,String> columnMap = new LinkedHashMap<String, String>();
        columnMap.put("列头","列属性");
        return columnMap ;
    }
    
    //以下是header 和 row data 的style 可以参考下
    public CellStyle getColumnTopStyle(SXSSFWorkbook workbook) {
    		Font font = workbook.createFont();
    		font.setFontHeightInPoints((short) 11);
    		font.setBoldweight((short) 700);
    		font.setFontName("Courier New");
    		CellStyle style = workbook.createCellStyle();
    		style.setBorderBottom((short) 1);
    		style.setBottomBorderColor((short) 10);
    		style.setBorderLeft((short) 1);
    		style.setLeftBorderColor((short) 8);
    		style.setBorderRight((short) 1);
    		style.setRightBorderColor((short) 8);
    		style.setBorderTop((short) 1);
    		style.setTopBorderColor((short) 8);
    		style.setFont(font);
    		style.setWrapText(false);
    		style.setAlignment(CellStyle.ALIGN_CENTER);
    		style.setVerticalAlignment((short) 1);
    		style.setFillForegroundColor((short) 10);
    		style.setFillPattern((short) 1);
    		return style;
    	}
    
    	public CellStyle getStyle(SXSSFWorkbook workbook) {
    		Font font = workbook.createFont();
    		font.setFontName("Courier New");
    		CellStyle style = workbook.createCellStyle();
    		style.setBorderBottom((short) 1);
    		style.setBottomBorderColor((short) 8);
    		style.setBorderLeft((short) 1);
    		style.setLeftBorderColor((short) 1);
    		style.setBorderRight((short) 1);
    		style.setRightBorderColor((short) 8);
    		style.setBorderTop((short) 1);
    		style.setTopBorderColor((short) 8);
    		style.setFont(font);
    		style.setWrapText(false);
    		style.setAlignment(CellStyle.ALIGN_CENTER);
    		style.setVerticalAlignment((short) 1);
    		return style;
    	}

     

    最终导出的样子

    结语:

    一切实现在于自己,路人只留下脚印。

     

    展开全文
  • [url=http://www.neverevernote.com/?p=12]excel的大数据量用POI写入 香菜个人博客[/url] 有50万的数据需要分析处理。 处理完毕后写入excel中,excel里需要用一个sheet放所有数据(excel用的是2007以后的版本,行数...
    [url=http://www.neverevernote.com/?p=12]excel的大数据量用POI写入 香菜个人博客[/url] 
    有50万的数据需要分析处理。
    处理完毕后写入excel中,excel里需要用一个sheet放所有数据(excel用的是2007以后的版本,行数限制从老版的6万多突破到了100多万)
    直接写入跑了一会就OUTOFMEMORY了


    多番寻找终于找到poi 3.6,这个版本已经支持了使用XSSF(支持07及以后的excel版本)来写入,并且提供了一个DEMO叫BigGridDemo(网上比较多,知名的DEMO)。这玩意使用XML方式先生成数据,然后再和一个xlsx的模版进行合并生成最终的xlsx。这种做法由于生成XML后还进行了压缩,基本上还是比较节省内存资源的。反正我50万数据是跑过了..百万级的数据问题应该也不大..

    但BigGridDemo.java(http://libjakarta-poi-java.sourcearchive.com/documentation/3.6plus-pdfsg/BigGridDemo_8java-source.html有源码,google也有一把)
    这个例子很方便,仿造它改一下generate方法就好了..
    但有个致命的bug,就是没有对String的value进行XMLencode..一旦你的数据里出现了XML的标准字符(一共五个),你的数据格式就会乱掉...

    贴一下需要修正的代码(把所有的value都先XMLEncoder一下)


    public void createCell(int columnIndex, String value, int styleIndex) throws IOException {
    String ref = new CellReference(_rownum, columnIndex).formatAsString();
    _out.write("<c r=\"" + ref + "\" t=\"inlineStr\"");
    if (styleIndex != -1) _out.write(" s=\"" + styleIndex + "\"");
    _out.write(">");
    _out.write("<is><t>" + XMLEncoder.encode(value)+ "</t></is>");
    _out.write("</c>");
    }


    附上XMLEncoder的实现(模仿htmlEncoder写的)


    public class XMLEncoder {

    private static final String[] xmlCode = new String[256];

    static {
    // Special characters
    xmlCode['\''] = "&apos;";
    xmlCode['\"'] = """; // double quote
    xmlCode['&'] = "&"; // ampersand
    xmlCode['<'] = "<"; // lower than
    xmlCode['>'] = ">"; // greater than
    }

    /**
    * <p>
    * Encode the given text into xml.
    * </p>
    *
    * @param string the text to encode
    * @return the encoded string
    */
    public static String encode(String string) {
    if (string == null) return "";
    int n = string.length();
    char character;
    String xmlchar;
    StringBuffer buffer = new StringBuffer();
    // loop over all the characters of the String.
    for (int i = 0; i < n; i++) {
    character = string.charAt(i);
    // the xmlcode of these characters are added to a StringBuffer one by one
    try {
    xmlchar = xmlCode[character];
    if (xmlchar == null) {
    buffer.append(character);
    } else {
    buffer.append(xmlCode[character]);
    }
    } catch (ArrayIndexOutOfBoundsException aioobe) {
    buffer.append(character);
    }
    }
    return buffer.toString();
    }

    public static void main(String[] args) {
    String test = "\'\"4&<2>1";
    System.out.println(encode(test));
    }

    }
    展开全文
  • POI处理大数据excel

    2020-03-19 17:01:18
    1:xls是旧版Excel格式文件,xlsx是新版Excel格式文件;而xlsx新版格式其实是一系列文件压缩包, 如图: 2:xls是以二进制的方式存储,这种格式不易被其他软件读取使用;而xlsx采用了基于XML的ooxml开放文档标准,...

    xls和xlsx
    1:xls是旧版Excel格式文件,xlsx是新版Excel格式文件;而xlsx新版格式其实是一系列文件压缩包,
    如图:
    在这里插入图片描述
    2:xls是以二进制的方式存储,这种格式不易被其他软件读取使用;而xlsx采用了基于XML的ooxml开放文档标准,ooxml使用XML和ZIP技术结合进行文件存储,XML是一个基于文本的格式,而且ZIP容器支持内容的压缩,所以其一大优势是可以大大减小文件的尺寸;
    3:使用POI来读写Excel文件有两种方式,一种用户模式(UserModel),读取时消耗大量内存,造成OOM问题;一种事件模式(SAX模式),仅仅关注文件内部数据,内存消耗很低;
    导出文件同样如此,使用Workbook普通导出,数据量小的时候可以正常使用,但时间等待仍然很长,这时推荐使用POI提供的SXXFWorkbook处理,其使用时间窗口原理(具体可以查询)限制访问,刷出内存,降低内存消耗,提升效率。
    4:另外还需要注意,根据你使用的功能,仍然可能消耗大量内存,例如合并区域,超链接,注释……,这些内容只存储在内存中。
    在这里插入图片描述
    大量数据导入在网络上搜寻到的相关代码大部分通过集成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);
                //可以补全空格
                //            int thisCol = (new CellReference(cellReference)).getCol();
    //           int sun=thisCol-i;
    //            for (int i1 = 0; i1 < sun; i1++,i++) {
    //                row.add("");
    //            }
    //            row.add(formattedValue);
    //            i++;
            }
    
            @Override
            public void headerFooter(String text, boolean isHeader, String tagName) {
            }
        }
    }
    

    导出数据(大量)
    导出数据的话瓶颈主要在于数据写入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();
        }
    

    大文件读取使用SAX
    大文件写入使用SXSSFWorkbook

    源码:XLSX2CSV.java的源码

    展开全文
  • poi大数据导出excel

    2019-08-02 14:49:48
    前提: 由于本人采取的是利用反射的方式,这样的好处,可以兼容,导出所有类型的数据,例如,订单,充值记录等等。 既然是公有的接口,肯定有一定的约束规范。 (1)导出的表头需要自己设置一个动态数组 ...

    前提:

    由于本人采取的是利用反射的方式,这样的好处,可以兼容,导出所有类型的数据,例如,订单,充值记录等等。

    既然是公有的接口,肯定有一定的约束规范。

    (1)导出的表头需要自己设置一个动态数组

    (2) 头部的宽度需要自己设置,也可以自己写一个方法,根据字体的长度,形成一个头部的动态数组长度。

    (3)返回的实体类,一定要遵循,跟头部一一对应的原则,例如:

    导出的实体类,name要显示在excel的第一列,名字就得放在number这个字段的前面

    1.pom.xml配置

    <!-- poi -->
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi</artifactId>
    			<version>3.8</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml</artifactId>
    			<version>3.8</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-scratchpad</artifactId>
    			<version>3.8</version>
    		</dependency>
    		<dependency>
    			<groupId>org.apache.poi</groupId>
    			<artifactId>poi-ooxml-schemas</artifactId>
    			<version>3.8</version>
    		</dependency>

    2.前端代码

    2.1jsp页面代码

     <div class="float-r">
    		<a class="red_btn_big addOrEditFoodCategory" type="add" onclick="list.exportReCharge()">+ 导出充值记录</a>
    </div>

    2.2 js代码

    	/**
    		 * 导出充值交易信息
    		 */
    		exportReCharge : function() {
    			var methodOfPayment = $('#methodOfPayment option:selected').val();
    			var paymentStatus = $('#paymentStatus option:selected').val();
    			var serviceType = $('#serviceType option:selected').val();
    			var startTime = $('#date0').val();
    			var endTime = $('#date1').val();
    			var keywords = $('#keywords').val();
    			layer.confirm('确定导出充值数据吗?', {
    				icon : 3,
    				title : '提示'
    			}, function(index) {
    				window.location.href = "export?search=" + keywords
    						+ "&channels=" + methodOfPayment + "&state="
    						+ paymentStatus + "&serviceType=" + serviceType
    						+ "&startTime=" + startTime + "&endTime=" + endTime;
    				layer.close(index);
    			});
    		}

    2.3后台controller代码

    @RequestMapping("export")
    	public void exportCharge(HttpServletRequest request, HttpServletResponse response, OrderExportVo exportVo) {
    		Principal principal = getLoginAdminInfo();
    		if (null == principal) {
    			logger.info("--------------获取登录用户身份信息为空!");
    			return;
    		}
    		HashMap<String, Object> conditionMap = new HashMap<>();
    
    		try {
    			boolean superAdmin = false; // 是否为超级管理员
    			if(principal.getOperatorId() != null && StringUtils.isBlank(principal.getTreeIds())){// 非超级管理员
    				superAdmin = true;
    			} 
    
    			PayOrderInfo payOrderInfo = new PayOrderInfo();
    			payOrderInfo.setState(exportVo.getState());
    			payOrderInfo.setServiceType(exportVo.getServiceType());
    			payOrderInfo.setChannels(exportVo.getChannels());
    			
    			conditionMap.put("payOrderInfo", payOrderInfo);
    			conditionMap.put("superAdmin", superAdmin);
    			conditionMap.put("operatorId", principal.getOperatorId());
    			conditionMap.put("adminId", principal.getTreeIds());
    			conditionMap.put("search", exportVo.getSearch());
    			conditionMap.put("startTime", exportVo.getStartTime());
    			conditionMap.put("endTime", exportVo.getEndTime());
    			Collection<OrderVo> dataset = payOrderInfoMapper.getPayOrderList(conditionMap);
    			
    			
    			for (OrderVo orderVo : dataset) {
    				String channelsName = "";
    				if(orderVo.getChannels() != null){
    					channelsName = ChannelsType.getType(orderVo.getChannels()).getDesc();
    				}
    				orderVo.setChannelsName(channelsName);
    				orderVo.setStateName(OrderState.getType(orderVo.getState()).getDesc());
    				String serviceTypeName="";
    				if(orderVo.getServiceType() != null){
    					serviceTypeName = ServiceType.getType(orderVo.getServiceType()).getDesc();
    				}
    				orderVo.setServiceTypeName(serviceTypeName);
    			}
    			
    			ExportExcelUtils<OrderVo> excelUtils = new ExportExcelUtils<>();
    			SXSSFWorkbook exportExcel = null;
    			String[] headers = { "用户名","手机号","充值金额","退款金额", "余额", "充值平台", "订单号", "支付时间", "支付状态", "支付类型", "操作者" };
    			int[] widths = {68,90,80,80,80,85,189,140,68,68,68};
    			exportExcel = excelUtils.exportExcel("充值", headers,widths, dataset, response.getOutputStream());
    			String currentDate = TimeUtils.getCurrentTimeStr("yyyyMMddHHmmss");
    			excelUtils.createSXSSFWorkbook(exportExcel, response, "充值记录" + currentDate + ".xlsx");
    		} catch (IOException e) {
    			logger.info("导出充值交易记录失败!", e.getMessage());
    		}
    	}

    2.4 excel辅助类

    package com.parwa.web.util;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.sql.Timestamp;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Collection;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFPatriarch;
    import org.apache.poi.hssf.usermodel.HSSFRichTextString;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Drawing;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.usermodel.IndexedColors;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
    import org.apache.poi.xssf.usermodel.XSSFRichTextString;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    /**
     * 导出Excel工具 
     * @author wude
     *
     * @param <T>
     */
    public class ExportExcelUtils<T> {
    	private static final Logger logger = LoggerFactory.getLogger(ExportExcelUtils.class);
    
    	public void exportExcel(String title, Collection<T> dataset, OutputStream out) {
    		exportExcel(title, null, dataset, out, "yyyy-MM-dd HH:mm:ss");
    	}
    	
    	public void exportExcel(String title, String[] headers, Collection<T> dataset, OutputStream out) {
    		exportExcel(title, headers, dataset, out, "yyyy-MM-dd HH:mm:ss");
    	}
    	
    	/**
    	 * 生成excel
    	 * @param title     sheet名称
    	 * @param headers   表头
    	 * @param width     宽
    	 * @param dataset   当前list对象
    	 * @param out 
    	 * @return
    	 */
    	public SXSSFWorkbook exportExcel(String title, String[] headers,int[] width,Collection<T> dataset, OutputStream out) {
    		SXSSFWorkbook exportExcel = exportBigDataExcel(title, headers,width,dataset, out, "yyyy-MM-dd HH:mm:ss");
    		return exportExcel;
    	}
    	
    	/**
    	 * 创建excel文档
    	 * @param wb
    	 * @param response
    	 * @param fileName   文件名称
    	 * @throws IOException
    	 */
        public  void createSXSSFWorkbook(Workbook wb,HttpServletResponse response,String fileName) throws IOException {
            ServletOutputStream out = null;
            try {
                // 设置响应头
                response.addHeader("Content-Disposition", "attachment;filename="
                        + new String(fileName.getBytes("GBK"), "ISO8859_1"));
                out = response.getOutputStream();
                wb.write(out);
            } catch (Exception e) {
            	logger.info("导出excel报错!",e.getMessage());
            } finally {
                if (out != null) {
                        out.close();
                }
            }
        }
    	
    	
    	/**
    	 * 利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
    	 * @param title 表格标题名
    	 * @param title 列宽度
    	 * @param headers 表格属性列名数组
    	 * @param dataset 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
    	 * @param out 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
    	 * @param pattern 如果有时间数据,设定输出格式。默认为"yyy-MM-dd HH:mm:ss"
    	 */
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public SXSSFWorkbook exportBigDataExcel(String title, String[] headers,int[] width,Collection<T> dataset, OutputStream out, String pattern) {
    		/** 声明一个工作簿 **/
    		SXSSFWorkbook workbook = new SXSSFWorkbook(100);   //100为内存缓存数据
    		if (dataset == null || dataset.size() == 0) {
    	            // 防止数据为空的情况下,excel无法打开
    			workbook.createSheet();
    	        return workbook;
    	    }
    		/** 声明一个表格 **/
    		Sheet sheet = workbook.createSheet(title);
    		/** 设置表格默认列宽度为15个字节 **/
    		sheet.setDefaultColumnWidth((int) 16);
    		sheet.autoSizeColumn(1);
    		/** 生成样式,用于表格标题行 **/
    		CellStyle style = workbook.createCellStyle();
    		/** 设置样式 **/
    		style.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.index);
    	    style.setFillPattern(CellStyle.SOLID_FOREGROUND);
    	    style.setBorderBottom(CellStyle.BORDER_THIN);
    	    style.setBorderLeft(CellStyle.BORDER_THIN);
    	    style.setBorderRight(CellStyle.BORDER_THIN);
    	    style.setBorderTop(CellStyle.BORDER_THIN);
    	    style.setAlignment(CellStyle.ALIGN_CENTER);
    	    /** 生成字体 **/
    	    Font font = workbook.createFont();
    	    font.setColor(IndexedColors.VIOLET.index);
    	    font.setFontHeightInPoints((short) 13);
    	    font.setBoldweight(Font.BOLDWEIGHT_BOLD);
    	    /** 将字体应用到样式中 **/
    	    style.setFont(font);
    	    
    	    /** 样式二,用于表格内容行 **/
    	    CellStyle style2 = workbook.createCellStyle();
    	    style2.setFillForegroundColor(IndexedColors.WHITE.index);
    	    style2.setFillPattern(CellStyle.SOLID_FOREGROUND);
    	    style2.setBorderBottom(CellStyle.BORDER_THIN);
    	    style2.setBorderLeft(CellStyle.BORDER_THIN);
    	    style2.setBorderRight(CellStyle.BORDER_THIN);
    	    style2.setBorderTop(CellStyle.BORDER_THIN);
    	    style2.setAlignment(CellStyle.ALIGN_CENTER); //水平布局:居中;
    	    style2.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
          	/** 字体二 **/
    	    Font font2 = workbook.createFont();
    	    font.setFontHeightInPoints((short) 12);
    	    font2.setBoldweight(Font.BOLDWEIGHT_NORMAL);
    	    font2.setColor(IndexedColors.BLACK.index);
    	    style2.setFont(font2);
    	    /** 声明画图顶级管理器 **/
    	    Drawing patriarch = sheet.createDrawingPatriarch();
    	    
    	    /** 设置表格标题行 **/
    	    Row row = sheet.createRow(0);
    	    for (int i = 0; i < headers.length; i++) {
    	       Cell cell = row.createCell(i);
    	       cell.setCellStyle(style);
    	       XSSFRichTextString text = new XSSFRichTextString(headers[i]);
    	       cell.setCellValue(text);
    	       sheet.setColumnWidth(i, (int) (width[i] * 35.7));
    	    }
    	    
    	    /** 以下是数据内容 **/
    	    Iterator<T> it = dataset.iterator();
    	    int index = 0;
    	    while(it.hasNext() && it != null){
    	    	index++;
    	    	row = sheet.createRow(index);
    	    	T t = (T) it.next();
    	    	/** 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 **/
    	    	Field[] fields = t.getClass().getDeclaredFields();
    	    	for(int i = 0;i < fields.length;i++){
    	    		if(i == headers.length){
    	    			break;
    	    		}
    	    		Cell cell = row.createCell(i);
    	            
    	            Field field = fields[i];
    	            String fieldName = field.getName();
    	            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    	            
    	            try {
    	                Class tCls = t.getClass();
    	                Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
    	                Object value = getMethod.invoke(t, new Object[] {});
    	                /** 判断值的类型后进行强制类型转换 **/
    	                String textValue = null;
    	                if (value instanceof Boolean) {
    	                	boolean bValue = (Boolean) value;
    	                	textValue = "是";
    	                	if (!bValue) {
    	                		textValue ="否";
    	                	}
    	                } else if (value instanceof Date) {
    	                	Date date = (Date) value;
    	                	SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    	                    textValue = sdf.format(date);
    	                } else if (value instanceof byte[]) {
    	                	/** 有图片时,设置行高为60px **/
    	                	row.setHeightInPoints(60);
    	                	/** 设置图片所在列宽度为80px,注意这里单位的一个换算 **/
    	                	sheet.setColumnWidth(i, (short) (35.7 * 80));
    	                	byte[] bsValue = (byte[]) value;
    	                	XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 255, (short) 6, index, (short) 6, index);
    	                 	anchor.setAnchorType(2);
    	                	patriarch.createPicture(anchor, workbook.addPicture(bsValue, Workbook.PICTURE_TYPE_JPEG));
    	                } else if(value instanceof Calendar){
    	                	Calendar cale = Calendar.getInstance();  
    	                	Date tasktime = cale.getTime();  
    	                	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	                	textValue = df.format(tasktime);
    	                } else{
    	                	/** 其它数据类型都当作字符串简单处理 **/
    	                	if(value != null){
    	                		textValue = value.toString();
    	                	}
    	                }
    	                /** 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 **/
    	                if(textValue!=null){
    	                	Pattern p = Pattern.compile("^//d+(//.//d+)?$");  
    	                	Matcher matcher = p.matcher(textValue);
    	                	if(matcher.matches()){
    	                		/** 是数字当作double处理 **/
    	                		cell.setCellValue(Double.parseDouble(textValue));
    	                   }else{
    	                	   XSSFRichTextString richString = new XSSFRichTextString(textValue);
    	                	   Font font3 = workbook.createFont();
    	                	   font3.setColor(IndexedColors.BLACK.index);
    	                	   richString.applyFont(font3);
    	                	   cell.setCellValue(richString);
    	                   }
    	                }else{
    	                	cell.setCellValue("");
    	                }
    	            } catch (Exception e) {
    	            	e.printStackTrace();
    	            	logger.info("导出excel报错!",e.getMessage());
    	            } finally {
    	                //清理资源
    	            }
    	            cell.setCellStyle(style2);
    	    	}
    	    }
    		return workbook;
    	}
    	
    	/**
    	 * 利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
    	 * @param title 表格标题名
    	 * @param headers 表格属性列名数组
    	 * @param dataset 需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。此方法支持的javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
    	 * @param out 与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
    	 * @param pattern 如果有时间数据,设定输出格式。默认为"yyy-MM-dd HH:mm:ss"
    	 */
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public HSSFWorkbook exportExcel(String title, String[] headers, Collection<T> dataset, OutputStream out, String pattern) {
    		/** 声明一个工作簿 **/
    		HSSFWorkbook workbook = new HSSFWorkbook();
    		/** 声明一个表格 **/
    		HSSFSheet sheet = workbook.createSheet(title);
    		/** 设置表格默认列宽度为15个字节 **/
    		sheet.setDefaultColumnWidth((int) 16);
    		sheet.autoSizeColumn(1);
    		/** 生成样式,用于表格标题行 **/
    		HSSFCellStyle style = workbook.createCellStyle();
    		/** 设置样式 **/
    		style.setFillForegroundColor(HSSFColor.LEMON_CHIFFON.index);
    	    style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    	    style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    	    style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    	    style.setBorderRight(HSSFCellStyle.BORDER_THIN);
    	    style.setBorderTop(HSSFCellStyle.BORDER_THIN);
    	    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    	    /** 生成字体 **/
    	    HSSFFont font = workbook.createFont();
    	    font.setColor(HSSFColor.VIOLET.index);
    	    font.setFontHeightInPoints((short) 12);
    	    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    	    /** 将字体应用到样式中 **/
    	    style.setFont(font);
    	    
    	    /** 样式二,用于表格内容行 **/
    	    HSSFCellStyle style2 = workbook.createCellStyle();
    	    style2.setFillForegroundColor(HSSFColor.WHITE.index);
    	    style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    	    style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    	    style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    	    style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
    	    style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
    	    style2.setAlignment(HSSFCellStyle.ALIGN_LEFT);
    	    style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
          	/** 字体二 **/
    	    HSSFFont font2 = workbook.createFont();
    	    font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
    	    font2.setColor(HSSFColor.BLACK.index);
    	    style2.setFont(font2);
    	    /** 声明画图顶级管理器 **/
    	    HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
    	    
    	    /** 设置表格标题行 **/
    	    HSSFRow row = sheet.createRow(0);
    	    for (int i = 0; i < headers.length; i++) {
    	       HSSFCell cell = row.createCell(i);
    	       cell.setCellStyle(style);
    	       HSSFRichTextString text = new HSSFRichTextString(headers[i]);
    	       cell.setCellValue(text);
    	    }
    	    
    	    /** 以下是数据内容 **/
    	    Iterator<T> it = dataset.iterator();
    	    int index = 0;
    	    while(it.hasNext() && it != null){
    	    	index++;
    	    	row = sheet.createRow(index);
    	    	T t = (T) it.next();
    	    	/** 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 **/
    	    	Field[] fields = t.getClass().getDeclaredFields();
    	    	for(int i = 0;i < fields.length;i++){
    	    		HSSFCell cell = row.createCell(i);
    	            
    	            Field field = fields[i];
    	            String fieldName = field.getName();
    	            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    	            
    	            try {
    	                Class tCls = t.getClass();
    	                Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
    	                Object value = getMethod.invoke(t, new Object[] {});
    	                /** 判断值的类型后进行强制类型转换 **/
    	                String textValue = null;
    	                if (value instanceof Boolean) {
    	                	boolean bValue = (Boolean) value;
    	                	textValue = "是";
    	                	if (!bValue) {
    	                		textValue ="否";
    	                	}
    	                } else if (value instanceof Date) {
    	                	Date date = (Date) value;
    	                	SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    	                    textValue = sdf.format(date);
    	                } else if (value instanceof byte[]) {
    	                	/** 有图片时,设置行高为60px **/
    	                	row.setHeightInPoints(60);
    	                	/** 设置图片所在列宽度为80px,注意这里单位的一个换算 **/
    	                	sheet.setColumnWidth(i, (short) (35.7 * 80));
    	                	byte[] bsValue = (byte[]) value;
    	                	HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) 6, index, (short) 6, index);
    	                 	anchor.setAnchorType(2);
    	                	patriarch.createPicture(anchor, workbook.addPicture(bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG));
    	                } else if(value instanceof Calendar){
    	                	Calendar cale = Calendar.getInstance();  
    	                	Date tasktime = cale.getTime();  
    	                	SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	                	textValue = df.format(tasktime);
    	                } else{
    	                	/** 其它数据类型都当作字符串简单处理 **/
    	                	if(value != null){
    	                		textValue = value.toString();
    	                	}
    	                }
    	                /** 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 **/
    	                if(textValue!=null){
    	                	Pattern p = Pattern.compile("^//d+(//.//d+)?$");  
    	                	Matcher matcher = p.matcher(textValue);
    	                	if(matcher.matches()){
    	                		/** 是数字当作double处理 **/
    	                		cell.setCellValue(Double.parseDouble(textValue));
    	                   }else{
    	                	   HSSFRichTextString richString = new HSSFRichTextString(textValue);
    	                	   HSSFFont font3 = workbook.createFont();
    	                	   font3.setColor(HSSFColor.BLACK.index);
    	                	   richString.applyFont(font3);
    	                	   cell.setCellValue(richString);
    	                   }
    	                }else{
    	                	cell.setCellValue("");
    	                }
    	            } catch (SecurityException e) {
    	                e.printStackTrace();
    	            } catch (NoSuchMethodException e) {
    	                e.printStackTrace();
    	            } catch (IllegalArgumentException e) {
    	                e.printStackTrace();
    	            } catch (IllegalAccessException e) {
    	                e.printStackTrace();
    	            } catch (InvocationTargetException e) {
    	                e.printStackTrace();
    	            } finally {
    	                //清理资源
    	            }
    	    	}
    	    }
    		return workbook;
    	}
    	
    	
    	public static void main(String[] args) {
    		Timestamp time = TimeUtils.getCurrentTime();
    		if(time instanceof Date){
    			System.out.println("时间类型");
    		}
    	}
    }
    

    可能存在问题 

    实体类

     因为set get是遵守驼峰规则的,按道理生成的get方法应该是getHMaxTemp,但是这里却不是,就是因为h后面接的是大写字母,如果是thMaxTemp,生成的get方法,就是getThMaxTemp,所以编码的时候,保持一个良好的习惯很重要,但是,项目用了一段时间,如果只是这个大小写的问题,就大改动,这样改动量也太大勒,这里我分享另外一种方法。

    找到这个工具类的String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);,如上图所示换成下面的图片效果

    需要增加一个辅助反射类

    ReflectUtil.java

    
    package com.cloudtech.web.util;
     
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    
    import com.cloudtech.web.entity.RuleCode;
     
    public class ReflectUtil {
     
        /**
         * 使用反射设置变量值
         *
         * @param target 被调用对象
         * @param fieldName 被调用对象的字段,一般是成员变量或静态变量,不可是常量!
         * @param value 值
         * @param <T> value类型,泛型
         */
        public static <T> void setValue(Object target,String fieldName,T value) {
            try {
                Class c = target.getClass();
                Field f = c.getDeclaredField(fieldName);
                f.setAccessible(true);
                f.set(target, value);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
     
        /**
         * 使用反射获取变量值
         *
         * @param target 被调用对象
         * @param fieldName 被调用对象的字段,一般是成员变量或静态变量,不可以是常量
         * @param <T> 返回类型,泛型
         * @return 值
         */
        public static <T> T getValue(Object target,String fieldName) {
            T value = null;
            try {
                Class c = target.getClass();
                Field f = c.getDeclaredField(fieldName);
                f.setAccessible(true);
                value = (T) f.get(target);
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            return value;
        }
        
        public static void main(String[] args) {
    		RuleCode code = new RuleCode();
    		code.setId(1234);
    		//Object value = ReflectUtil.getValue(code, "id");
    		System.out.println(code.getId());
        /*	String s ="avgSpd gt hThreeMaxSpd";
        	String replace = s.replace("gt", "");
        	String[] split = replace.split(" ");
        	System.out.println();*/
    	}
    }

     3.对比

    建议用后面这种,毕竟可以兼容实体类字段命名不规范的问题

    4.优化后excel辅助类

    注意:使用的时候,使用反射方式,去掉多余的代码,使用SXSSFWorkbook,性能更优

    package com.cloudtech.web.util;
    
    import java.io.IOException;
    import java.io.OutputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.math.BigDecimal;
    import java.sql.Timestamp;
    import java.text.SimpleDateFormat;
    import java.util.Calendar;
    import java.util.Collection;
    import java.util.Date;
    import java.util.Iterator;
    import java.util.LinkedHashMap;
    import java.util.Map.Entry;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import javax.servlet.ServletOutputStream;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFPatriarch;
    import org.apache.poi.hssf.usermodel.HSSFRichTextString;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Drawing;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.usermodel.IndexedColors;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFRichTextString;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    /**
     * 导出Excel工具
     * 
     * @author wude
     *
     * @param <T>
     */
    public class ExportExcelUtils<T> {
    	private static final Logger logger = LoggerFactory.getLogger(ExportExcelUtils.class);
    
    	public void exportExcel(String title, Collection<T> dataset, OutputStream out) {
    		exportExcel(title, null, dataset, out, "yyyy-MM-dd HH:mm:ss");
    	}
    
    	/**
    	 * 生成excel
    	 * 
    	 * @param title
    	 *            sheet名称
    	 * @param headers
    	 *            表头
    	 * @param width
    	 *            宽
    	 * @param dataset
    	 *            当前list对象
    	 * @param out
    	 * @return
    	 */
    	public SXSSFWorkbook exportExcel(String title, String[] headers, int[] width, Collection<T> dataset,
    			OutputStream out) {
    		SXSSFWorkbook exportExcel = exportBigDataExcel(title, headers, width, dataset, out, "yyyy-MM-dd HH:mm:ss");
    		return exportExcel;
    	}
    
    	public SXSSFWorkbook exportMapExcel(String title, String[] headers, int[] width,
    			LinkedHashMap<String, LinkedHashMap<String, Object>> dataset, OutputStream out) {
    		SXSSFWorkbook exportExcel = exportBigMapDataExcel(title, headers, width, dataset, out, "yyyy-MM-dd HH:mm:ss");
    		return exportExcel;
    	}
    
    	/**
    	 * 创建excel文档
    	 * 
    	 * @param wb
    	 * @param response
    	 * @param fileName
    	 *            文件名称
    	 * @throws IOException
    	 */
    	public void createSXSSFWorkbook(Workbook wb, HttpServletResponse response, String fileName) throws IOException {
    		ServletOutputStream out = null;
    		try {
    			// 设置响应头
    			response.addHeader("Content-Disposition",
    					"attachment;filename=" + new String(fileName.getBytes("GBK"), "ISO8859_1"));
    			out = response.getOutputStream();
    			wb.write(out);
    		} catch (Exception e) {
    			logger.info("导出excel报错!", e.getMessage());
    		} finally {
    			if (out != null) {
    				out.close();
    			}
    		}
    	}
    
    	/**
    	 * 利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
    	 * 
    	 * @param title
    	 *            表格标题名
    	 * @param title
    	 *            列宽度
    	 * @param headers
    	 *            表格属性列名数组
    	 * @param dataset
    	 *            需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。
    	 *            此方法支持的javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
    	 * @param out
    	 *            与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
    	 * @param pattern
    	 *            如果有时间数据,设定输出格式。默认为"yyy-MM-dd HH:mm:ss"
    	 */
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public SXSSFWorkbook exportBigDataExcel(String title, String[] headers, int[] width, Collection<T> dataset,
    			OutputStream out, String pattern) {
    		/** 声明一个工作簿 **/
    		SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 100为内存缓存数据
    		if (dataset == null || dataset.size() == 0) {
    			// 防止数据为空的情况下,excel无法打开
    			workbook.createSheet();
    			return workbook;
    		}
    		/** 声明一个表格 **/
    		Sheet sheet = workbook.createSheet(title);
    		/** 设置表格默认列宽度为15个字节 **/
    		sheet.setDefaultColumnWidth((int) 16);
    		sheet.autoSizeColumn(1);
    		/** 生成样式,用于表格标题行 **/
    		CellStyle style = workbook.createCellStyle();
    		/** 设置样式 **/
    		style.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.index);
    		style.setFillPattern(CellStyle.SOLID_FOREGROUND);
    		style.setBorderBottom(CellStyle.BORDER_THIN);
    		style.setBorderLeft(CellStyle.BORDER_THIN);
    		style.setBorderRight(CellStyle.BORDER_THIN);
    		style.setBorderTop(CellStyle.BORDER_THIN);
    		style.setAlignment(CellStyle.ALIGN_CENTER);
    		/** 生成字体 **/
    		Font font = workbook.createFont();
    		font.setColor(IndexedColors.VIOLET.index);
    		font.setFontHeightInPoints((short) 13);
    		font.setBoldweight(Font.BOLDWEIGHT_BOLD);
    		/** 将字体应用到样式中 **/
    		style.setFont(font);
    
    		/** 样式二,用于表格内容行 **/
    		CellStyle style2 = workbook.createCellStyle();
    		style2.setFillForegroundColor(IndexedColors.WHITE.index);
    		style2.setFillPattern(CellStyle.SOLID_FOREGROUND);
    		style2.setBorderBottom(CellStyle.BORDER_THIN);
    		style2.setBorderLeft(CellStyle.BORDER_THIN);
    		style2.setBorderRight(CellStyle.BORDER_THIN);
    		style2.setBorderTop(CellStyle.BORDER_THIN);
    		style2.setAlignment(CellStyle.ALIGN_CENTER); // 水平布局:居中;
    		style2.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
    		/** 字体二 **/
    		Font font2 = workbook.createFont();
    		font.setFontHeightInPoints((short) 12);
    		font2.setBoldweight(Font.BOLDWEIGHT_NORMAL);
    		font2.setColor(IndexedColors.BLACK.index);
    		style2.setFont(font2);
    		/** 声明画图顶级管理器 **/
    		Drawing patriarch = sheet.createDrawingPatriarch();
    
    		/** 设置表格标题行 **/
    		Row row = sheet.createRow(0);
    		for (int i = 0; i < headers.length; i++) {
    			Cell cell = row.createCell(i);
    			cell.setCellStyle(style);
    			XSSFRichTextString text = new XSSFRichTextString(headers[i]);
    			cell.setCellValue(text);
    			sheet.setColumnWidth(i, (int) (width[i] * 35.7));
    		}
    
    		/** 以下是数据内容 **/
    		Iterator<T> it = dataset.iterator();
    		int index = 0;
    		while (it.hasNext() && it != null) {
    			index++;
    			row = sheet.createRow(index);
    			T t = (T) it.next();
    			/** 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 **/
    			Field[] fields = t.getClass().getDeclaredFields();
    			for (int i = 0; i < fields.length; i++) {
    				if (i == headers.length) {
    					break;
    				}
    				Cell cell = row.createCell(i);
    
    				Field field = fields[i];
    				String fieldName = field.getName();
    
    				try {
    					Object value = ReflectUtil.getValue(t, fieldName);
    					/** 判断值的类型后进行强制类型转换 **/
    					String textValue = null;
    					if (value == null) {
    						cell.setCellValue("");
    					} else {
    						if (value instanceof Boolean) {
    							boolean bValue = (Boolean) value;
    							textValue = "是";
    							if (!bValue) {
    								textValue = "否";
    							}
    							cell.setCellValue(textValue);
    						} else if (value instanceof Date) {
    							Date date = (Date) value;
    							SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    							textValue = sdf.format(date);
    							cell.setCellValue(textValue);
    						} else if (value instanceof Integer) {
    							if (value != null) {
    								int intValue = new BigDecimal(value.toString()).intValue();
    								cell.setCellValue(intValue);
    							}
    						} else {
    							/** 其它数据类型都当作字符串简单处理 **/
    							if (value != null) {
    								textValue = value.toString();
    								cell.setCellValue(textValue);
    							}
    						}
    					}
    				} catch (Exception e) {
    					e.printStackTrace();
    					logger.info("导出excel报错!", e.getMessage());
    				} finally {
    					// 清理资源
    				}
    				cell.setCellStyle(style2);
    			}
    		}
    		return workbook;
    	}
    
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public SXSSFWorkbook exportBigMapDataExcel(String title, String[] headers, int[] width,
    			LinkedHashMap<String, LinkedHashMap<String, Object>> dataset, OutputStream out, String pattern) {
    		/** 声明一个工作簿 **/
    		SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 100为内存缓存数据
    		if (dataset == null || dataset.size() == 0) {
    			// 防止数据为空的情况下,excel无法打开
    			workbook.createSheet();
    			return workbook;
    		}
    		/** 声明一个表格 **/
    		Sheet sheet = workbook.createSheet(title);
    		/** 设置表格默认列宽度为15个字节 **/
    		sheet.setDefaultColumnWidth((int) 16);
    		sheet.autoSizeColumn(1);
    		/** 生成样式,用于表格标题行 **/
    		CellStyle style = workbook.createCellStyle();
    		/** 设置样式 **/
    		style.setFillForegroundColor(IndexedColors.LEMON_CHIFFON.index);
    		style.setFillPattern(CellStyle.SOLID_FOREGROUND);
    		style.setBorderBottom(CellStyle.BORDER_THIN);
    		style.setBorderLeft(CellStyle.BORDER_THIN);
    		style.setBorderRight(CellStyle.BORDER_THIN);
    		style.setBorderTop(CellStyle.BORDER_THIN);
    		style.setAlignment(CellStyle.ALIGN_CENTER);
    		/** 生成字体 **/
    		Font font = workbook.createFont();
    		font.setColor(IndexedColors.VIOLET.index);
    		font.setFontHeightInPoints((short) 13);
    		font.setBoldweight(Font.BOLDWEIGHT_BOLD);
    		/** 将字体应用到样式中 **/
    		style.setFont(font);
    
    		/** 样式二,用于表格内容行 **/
    		CellStyle style2 = workbook.createCellStyle();
    		style2.setFillForegroundColor(IndexedColors.WHITE.index);
    		style2.setFillPattern(CellStyle.SOLID_FOREGROUND);
    		style2.setBorderBottom(CellStyle.BORDER_THIN);
    		style2.setBorderLeft(CellStyle.BORDER_THIN);
    		style2.setBorderRight(CellStyle.BORDER_THIN);
    		style2.setBorderTop(CellStyle.BORDER_THIN);
    		style2.setAlignment(CellStyle.ALIGN_CENTER); // 水平布局:居中;
    		style2.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
    		/** 字体二 **/
    		Font font2 = workbook.createFont();
    		font.setFontHeightInPoints((short) 12);
    		font2.setBoldweight(Font.BOLDWEIGHT_NORMAL);
    		font2.setColor(IndexedColors.BLACK.index);
    		style2.setFont(font2);
    		/** 声明画图顶级管理器 **/
    		Drawing patriarch = sheet.createDrawingPatriarch();
    
    		/** 设置表格标题行 **/
    		Row row = sheet.createRow(0);
    		for (int i = 0; i < headers.length; i++) {
    			Cell cell = row.createCell(i);
    			cell.setCellStyle(style);
    			XSSFRichTextString text = new XSSFRichTextString(headers[i]);
    			cell.setCellValue(text);
    			sheet.setColumnWidth(i, (int) (width[i] * 35.7));
    		}
    
    		/** 以下是数据内容 **/
    		int index = 0;
    		for (Entry<String, LinkedHashMap<String, Object>> key : dataset.entrySet()) {
    			index++;
    			row = sheet.createRow(index);
    
    			Cell cell = row.createCell(0);
    			cell.setCellValue(key.getKey());
    			cell.setCellStyle(style2);
    
    			LinkedHashMap<String, Object> hourValues = key.getValue();
    			int i = 1;
    			for (Entry<String, Object> hourKey : hourValues.entrySet()) {
    				cell = row.createCell(i);
    				try {
    					/** 判断值的类型后进行强制类型转换 **/
    					String textValue = hourKey.getValue().toString();
    					cell.setCellValue(textValue);
    				} catch (Exception e) {
    					e.printStackTrace();
    					logger.info("导出excel报错!", e.getMessage());
    				} finally {
    					// 清理资源
    				}
    				cell.setCellStyle(style2);
    				i++;
    			}
    		}
    		/*
    		 * Iterator<T> it = (Iterator<T>) dataset.keySet().iterator(); int index
    		 * = 0; while (it.hasNext() && it != null) { index++; row =
    		 * sheet.createRow(index); T t = (T) it.next();
    		 *//** 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 **/
    		/*
    		 * Field[] fields = t.getClass().getDeclaredFields(); for (int i = 0; i
    		 * < fields.length; i++) { if (i == headers.length) { break; } Cell cell
    		 * = row.createCell(i);
    		 * 
    		 * Field field = fields[i]; String fieldName = field.getName(); //
    		 * String getMethodName = "get" + fieldName.substring(0, //
    		 * 1).toUpperCase() + fieldName.substring(1);
    		 * 
    		 * try { Class tCls = t.getClass(); Object value =
    		 * ReflectUtil.getValue(t, fieldName); // Method getMethod =
    		 * tCls.getMethod(getMethodName, new // Class[] {}); // Object value =
    		 * getMethod.invoke(t, new Object[] {});
    		 *//** 判断值的类型后进行强制类型转换 **/
    		/*
    		 * String textValue = null; if (value instanceof Boolean) { boolean
    		 * bValue = (Boolean) value; textValue = "是"; if (!bValue) { textValue =
    		 * "否"; } } else if (value instanceof Date) { Date date = (Date) value;
    		 * SimpleDateFormat sdf = new SimpleDateFormat(pattern); textValue =
    		 * sdf.format(date); } else if (value instanceof byte[]) {
    		 *//** 有图片时,设置行高为60px **/
    		/*
    		 * row.setHeightInPoints(60);
    		 *//** 设置图片所在列宽度为80px,注意这里单位的一个换算 **/
    		/*
    		 * sheet.setColumnWidth(i, (short) (35.7 * 80)); byte[] bsValue =
    		 * (byte[]) value; XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0,
    		 * 1023, 255, (short) 6, index, (short) 6, index);
    		 * anchor.setAnchorType(2); patriarch.createPicture(anchor,
    		 * workbook.addPicture(bsValue, Workbook.PICTURE_TYPE_JPEG)); } else if
    		 * (value instanceof Calendar) { Calendar cale = Calendar.getInstance();
    		 * Date tasktime = cale.getTime(); SimpleDateFormat df = new
    		 * SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); textValue =
    		 * df.format(tasktime); } else {
    		 *//** 其它数据类型都当作字符串简单处理 **/
    		/*
    		 * if (value != null) { textValue = value.toString(); } }
    		 *//** 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 **/
    		/*
    		 * if (textValue != null) { Pattern p =
    		 * Pattern.compile("^//d+(//.//d+)?$"); Matcher matcher =
    		 * p.matcher(textValue); if (matcher.matches()) {
    		 *//** 是数字当作double处理 **//*
    								 * cell.setCellValue(Double.parseDouble(
    								 * textValue)); } else { XSSFRichTextString
    								 * richString = new
    								 * XSSFRichTextString(textValue); Font font3 =
    								 * workbook.createFont();
    								 * font3.setColor(IndexedColors.BLACK.index);
    								 * richString.applyFont(font3);
    								 * cell.setCellValue(richString); } } else {
    								 * cell.setCellValue(""); } } catch (Exception
    								 * e) { e.printStackTrace();
    								 * logger.info("导出excel报错!", e.getMessage()); }
    								 * finally { // 清理资源 }
    								 * cell.setCellStyle(style2); } }
    								 */
    		return workbook;
    	}
    
    	/**
    	 * 利用了JAVA的反射机制,可以将放置在JAVA集合中并且符号一定条件的数据以EXCEL 的形式输出到指定IO设备上
    	 * 
    	 * @param title
    	 *            表格标题名
    	 * @param headers
    	 *            表格属性列名数组
    	 * @param dataset
    	 *            需要显示的数据集合,集合中一定要放置符合javabean风格的类的对象。
    	 *            此方法支持的javabean属性的数据类型有基本数据类型及String,Date,byte[](图片数据)
    	 * @param out
    	 *            与输出设备关联的流对象,可以将EXCEL文档导出到本地文件或者网络中
    	 * @param pattern
    	 *            如果有时间数据,设定输出格式。默认为"yyy-MM-dd HH:mm:ss"
    	 */
    	@SuppressWarnings({ "rawtypes", "unchecked" })
    	public HSSFWorkbook exportExcel(String title, String[] headers, Collection<T> dataset, OutputStream out,
    			String pattern) {
    		/** 声明一个工作簿 **/
    		HSSFWorkbook workbook = new HSSFWorkbook();
    		/** 声明一个表格 **/
    		HSSFSheet sheet = workbook.createSheet(title);
    		/** 设置表格默认列宽度为15个字节 **/
    		sheet.setDefaultColumnWidth((int) 16);
    		sheet.autoSizeColumn(1);
    		/** 生成样式,用于表格标题行 **/
    		HSSFCellStyle style = workbook.createCellStyle();
    		/** 设置样式 **/
    		style.setFillForegroundColor(HSSFColor.LEMON_CHIFFON.index);
    		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
    		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
    		style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    		/** 生成字体 **/
    		HSSFFont font = workbook.createFont();
    		font.setColor(HSSFColor.VIOLET.index);
    		font.setFontHeightInPoints((short) 12);
    		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    		/** 将字体应用到样式中 **/
    		style.setFont(font);
    
    		/** 样式二,用于表格内容行 **/
    		HSSFCellStyle style2 = workbook.createCellStyle();
    		style2.setFillForegroundColor(HSSFColor.WHITE.index);
    		style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
    		style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    		style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    		style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
    		style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
    		style2.setAlignment(HSSFCellStyle.ALIGN_LEFT);
    		style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    		/** 字体二 **/
    		HSSFFont font2 = workbook.createFont();
    		font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
    		font2.setColor(HSSFColor.BLACK.index);
    		style2.setFont(font2);
    		/** 声明画图顶级管理器 **/
    		HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
    
    		/** 设置表格标题行 **/
    		HSSFRow row = sheet.createRow(0);
    		for (int i = 0; i < headers.length; i++) {
    			HSSFCell cell = row.createCell(i);
    			cell.setCellStyle(style);
    			HSSFRichTextString text = new HSSFRichTextString(headers[i]);
    			cell.setCellValue(text);
    		}
    
    		/** 以下是数据内容 **/
    		Iterator<T> it = dataset.iterator();
    		int index = 0;
    		while (it.hasNext() && it != null) {
    			index++;
    			row = sheet.createRow(index);
    			T t = (T) it.next();
    			/** 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 **/
    			Field[] fields = t.getClass().getDeclaredFields();
    			for (int i = 0; i < fields.length; i++) {
    				HSSFCell cell = row.createCell(i);
    
    				Field field = fields[i];
    				String fieldName = field.getName();
    				String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
    
    				try {
    					Class tCls = t.getClass();
    					Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
    					Object value = getMethod.invoke(t, new Object[] {});
    					/** 判断值的类型后进行强制类型转换 **/
    					String textValue = null;
    					if (value instanceof Boolean) {
    						boolean bValue = (Boolean) value;
    						textValue = "是";
    						if (!bValue) {
    							textValue = "否";
    						}
    					} else if (value instanceof Date) {
    						Date date = (Date) value;
    						SimpleDateFormat sdf = new SimpleDateFormat(pattern);
    						textValue = sdf.format(date);
    					} else if (value instanceof byte[]) {
    						/** 有图片时,设置行高为60px **/
    						row.setHeightInPoints(60);
    						/** 设置图片所在列宽度为80px,注意这里单位的一个换算 **/
    						sheet.setColumnWidth(i, (short) (35.7 * 80));
    						byte[] bsValue = (byte[]) value;
    						HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) 6, index, (short) 6,
    								index);
    						anchor.setAnchorType(2);
    						patriarch.createPicture(anchor, workbook.addPicture(bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG));
    					} else if (value instanceof Calendar) {
    						Calendar cale = Calendar.getInstance();
    						Date tasktime = cale.getTime();
    						SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    						textValue = df.format(tasktime);
    					} else {
    						/** 其它数据类型都当作字符串简单处理 **/
    						if (value != null) {
    							textValue = value.toString();
    						}
    					}
    					/** 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 **/
    					if (textValue != null) {
    						Pattern p = Pattern.compile("^//d+(//.//d+)?$");
    						Matcher matcher = p.matcher(textValue);
    						if (matcher.matches()) {
    							/** 是数字当作double处理 **/
    							cell.setCellValue(Double.parseDouble(textValue));
    						} else {
    							HSSFRichTextString richString = new HSSFRichTextString(textValue);
    							HSSFFont font3 = workbook.createFont();
    							font3.setColor(HSSFColor.BLACK.index);
    							richString.applyFont(font3);
    							cell.setCellValue(richString);
    						}
    					} else {
    						cell.setCellValue("");
    					}
    				} catch (SecurityException e) {
    					e.printStackTrace();
    				} catch (NoSuchMethodException e) {
    					e.printStackTrace();
    				} catch (IllegalArgumentException e) {
    					e.printStackTrace();
    				} catch (IllegalAccessException e) {
    					e.printStackTrace();
    				} catch (InvocationTargetException e) {
    					e.printStackTrace();
    				} finally {
    					// 清理资源
    				}
    			}
    		}
    		return workbook;
    	}
    
    	public static void main(String[] args) {
    		Timestamp time = TimeUtils.getCurrentTime();
    		if (time instanceof Date) {
    			System.out.println("时间类型");
    		}
    	}
    
    }
    

    4.性能分析

    列有69列,导出excel分析

    优化前:

    通过图片,我们可以发现sql的时间很长,当然跟我的列有关,69列

    5w数据需要31.42s,而1w数据是6.5s,我们是不是可以做一些优化。列入拿1w作为切割,5w数据分为5次查询出来,再组装数据,是不是可以提升查询数据。所以,这里需要使用多线程。这样整个导出的时长就短了不少。

     

    优化后:

    通过数据分析,发现,性能方面有质的提高,而且缓存数大小,性能没有什么明显的提示,所以建议缓存数还是设置为100把 

     

    缓存数:

    设置为100后,超过100的部分会写入硬盘,而不是所有的都存放在内存中

    性能优化部分: 

    /** 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 **/
    					if (textValue != null) {
    						Pattern p = Pattern.compile("^//d+(//.//d+)?$");
    						Matcher matcher = p.matcher(textValue);
    						if (matcher.matches()) {
    							/** 是数字当作double处理 **/
    							cell.setCellValue(Double.parseDouble(textValue));
    						} else {
    							XSSFRichTextString richString = new XSSFRichTextString(textValue);
    							Font font3 = workbook.createFont();
    							font3.setColor(IndexedColors.BLACK.index);
    							richString.applyFont(font3);
    							cell.setCellValue(richString);
    						}
    					} else {
    						cell.setCellValue("");
    					}

    主要是正则方面的判断,消耗勒大量的数据,导致时间很长

    展开全文
  • import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; import org....
  • 直接贴代码: package jp.co.misumi.mdm.batch.common.jobrunner; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; ...import java.ut...
  • poi的读取的三种模式 模式 说明 读写性 SXSSF 内存中保留一定行数数据,超过行数,将索引最低的数据刷入硬盘 只写 eventmodel 基于事件驱动,SAX的方式解析excel,cup和内存消耗低 只读 ...
  • 大数据Excel操作POI插件并导入到数据库
  • Java POI处理大量数据导入导出xls和xlsx导入数据(大量)导出数据(大量)总结 xls和xlsx xls是旧版Excel格式文件,xlsx是新版Excel格式文件;而xlsx新版格式其实是一系列文件压缩包, 如图: xls是以二进制的方式...
  • POI读写大数据量EXCEL

    2018-05-07 17:38:19
    大数据量的excel一般都是.xlsx格式的,网上使用POI读写的例子比较多,但是很少提到读写非常大数据量的excel的例子,POI官网上提到XSSF有三种读写excelPOI地址:http://poi.apache.org/spreadsheet/index.html...
  • apache POI学习(六)——大数据存储到Excel
  • POI读写大数据Excel

    2015-04-10 22:38:09
    目前处理Excel的开源javaAPI主要有两种,一是Jxl(Java Excel API),Jxl只支持Excel2003以下的版本。另外一种是Apache的Jakarta POI,相比于Jxl,POI对微软办公文档的支持更加强大,但是它使用复杂,上手慢。PO...
  • 工作中遇到大数据导出excel内存溢出的问题,在使用jxl和POI3.8之前的版本都找不到很好的解决办法,通过设置jvm内存效果也不理想。但是在POI3.8以上版本中提供了SXSSFWorkbook的新类,可以通过参数设置常驻内存中的...
  • POI 写大量数据到excel

    2019-01-26 08:01:37
    poi操作excel,有多套方法,应用场景和性能对比见 https://www.cnblogs.com/tootwo2/p/6683143.html   &lt;dependency&gt; &lt;groupId&gt;org.apache.poi&lt;/groupId&gt; &...
  • poi导出大数据 1000万

    2017-11-20 19:13:38
    @RequestMapping("exportUserToExcel.do")   public void exportUserToExcel(UserBean userBean,HttpServletRequest request,HttpServletResponse response) throws Exception{   SXSSFWorkbook wb =...
  • 大数据写入Excel

    2012-10-23 15:11:44
    import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.OutputStreamWriter;...
  • POI导出大数据量excel(注:项目源码及后续更新请点击)1、ExcelUtils类:package Utils; import com.alibaba.fastjson.JSONArray; ... import org.apache.poi.common.usermodel.Hyperlink; import org....
  • http://thinkgem.iteye.com/blog/2150940前端时间写了注解方式Excel的读取和写入,它是根据注解完成Excel的操作,虽说支持大数据,但对于超大数据就无能为力了,因为它的读写期间都是将所有数据放入系统内存的,除非...
  • POI读写大数据量excel,解决超过几万行而导致内存溢出的问题
1 2 3 4 5 ... 20
收藏数 477
精华内容 190