poi技术

poi技术

其实生活中不乏很多需要从数据库向excel导入数据的情况,但是如果数据库的东西很多且字段很长,会造成卡死机的状态。
那么如何解决这个一问题呢,其实网络上有一门技术叫做poi,官方介绍是:
Apache POIApache软件基金会的开放源码函式库,poi提供API给Java程序对Microsoft Office格式档案读和写的功能。
其实可以把它理解为JavaMicrosoft之间互相沟通的一门技术
Microsoft其实除了excel 还有ppt,word, 相互对应的列举如下:
结构:

HSSF - 提供读写Microsoft Excel格式档案的功能。

XSSF - 提供读写Microsoft Excel OOXML格式档案的功能。

HWPF - 提供读写Microsoft Word格式档案的功能。

HSLF - 提供读写Microsoft PowerPoint格式档案的功能。

HDGF - 提供读写Microsoft Visio格式档案的功能。

那我今天为大家简单的介绍一下如何优化poi导出问题

1. 常用类说明

类名 说明
HSSFWorkbook Excel的文档对象
HSSFSheet sheet页
HSSFRow Excel的行
HSSFCell Excel的格子单元
HSSFFont Excel字体
HSSFDataFormat 格子单元的日期格式
HSSFHeader Excel文档Sheet的页眉
HSSFFooter Excel文档Sheet的页脚
HSSFCellStyle 格子单元样式
HSSFDateUtil 日期
HSSFPrintSetup 打印
HSSFErrorConstants 错误信息表

2. 新建一个表格

首先要将下载好的jar包,解压将根目录下的所有包,以及将lib目录下的commons-logging-1.2.jar 和 junit-4.12.jar 以及 log4j1.2.17.jar 这三个通用包导入到项目的lib的目录下,poi-4.0.0.jar包是最重要的。
主要介绍HSSFWorkbook

  • 多态实现
  • HSSFWorkbook 是对于xls进行操作
  • 导出所以用到输出流
  • 参数为输出的地址
Workbook wb=new HSSFWorkbook();//新建一个工作簿
FileOutputStream fout=new FileOutputStream(“E:\Demo\poi.xls”);
wb.write(fout);//Workbook提供了write的方法
fout.close();//将输出流关闭

3. 新建sheet页

在新建工作簿的基础上新建sheet页,wb.createSheet() 返回一个Sheet()如果不进行操作不用接收

  • 多态实现
  • HSSFWorkbook 是对于xls进行操作
  • Workbook wb=new HSSFWorkbook();//新建一个工作簿
  • 导出所以用到输出流
  • FileOutputStream fout=new FileOutputStream(“E:\Demo\poi.xls”);
  • 有有参和无参数两种
  • 参数为sheet页的名字
  • 不写参数默认名字为sheet0到n

Sheet sheet1 = wb.createSheet();//创建一个sheet页
Sheet sheet2 = wb.createSheet(“第二个sheet页”);//创建第二个sheet页
wb.write(fout);
fout.close();//将输出流关闭
//一些工作表的方法
workbook.setActiveSheet(工作表下标);//设置默认工作表
workbook.setSheetName(2(工作表下标), “1234”(新名字));//重命名工作表
sheet1.setZoom(1,2);//50%显示比例
sheet2.setZoom(2,1);//200%显示比例
sheet3.setZoom(1,10);//10%显示比例

优化之后的方法


package com.lrc.excel;

import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

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.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class Excel {

	/**
	 * 
	* @Title: export
	* @Description: (通用导出excel)
	* @param excelName  导出文件名
	* @param list   数据集合 
	* @param fieldMap   表头字段   数据库字段为键  表头字段为值
	* @param response   浏览器下载
	* @return void
	 */
	   public static  void export(String excelName,List> list,LinkedHashMap fieldMap,HttpServletResponse response){
		   // 设置默认文件名为当前时间:年月日时分秒
	        if (excelName==null || excelName=="") {
	            excelName = new SimpleDateFormat("yyyyMMddhhmmss").format(
	                    new Date()).toString();
	        }
	        int total=list.size();  //总记录数
	        int  excelBig=10000;    //excel划分的大小

	        //判断需要分成多少个excel
	        int excelCount=(total%excelBig==0)?(total/excelBig):(total/excelBig+1);
           
	        //定义一个excel集合
	        List  excelList=new ArrayList();
	        
	        HSSFWorkbook wb=null;  //excel工作表
	        int begin = 0;   //数据源的开始位置
	        int end = 0;      //数据源的结束位置
		   
		   
	        //循环得到excel集合
	        for(int i=0;ilist.size()){
	                end=list.size();
	            }
	            //生成excel
	            wb=createExcel(excelName+(i+1), list,begin,end, fieldMap);
	            //将生成的excel添加到集合
	            excelList.add(wb);
	        } 
		   
	        //生成压缩文件,并导出
	        toZipOut(excelName, excelList, response);   
	        
	   }
	   /**
	    * 
	   * @Title: toZipOut
	   * @Description: (压缩文件)
	   * @param excelName  文件命
	   * @param excelList    wb工作簿集合
	   * @param response  将数据发送到页面上
	   * @return void
	    */
	    private static void toZipOut(String excelName, List excelList, HttpServletResponse response) {
	
	    	 try {
	             //将压缩包的名字默认为日期时间串
	             String fieldName=new SimpleDateFormat("yyyyMMddhhmmss").format(
	                     new Date()).toString();
	             /**设置response头信息**/
	             response.reset();  
	             //自己写状态码
	             response.setStatus(HttpServletResponse.SC_OK);  
	             //使客户端浏览器,区分不同种类的数据,并根据不同的MIME调用浏览器内不同的程序嵌入模块来处理相应的数据。
	             //ZIP与EXE文件的MIME类型同为application/octet-stream
	             response.setContentType( "application/octet-stream "); 
	             //Content-disposition 是 MIME 协议的扩展,MIME 协议指示 MIME 用户代理如何显示附加的文件。
	             //Content-disposition其实可以控制用户请求所得的内容存为一个文件的时候提供一个默认的文件名,文件直接在浏览器上显示或者在访问时弹出文件下载对话框。 
	             //此处设置下载文件的格式为.zip
	             response.setHeader("Content-Disposition","attachment;filename=\""+fieldName+".zip"+"\"");  

	             //生成输出流
	             OutputStream ouputStream = response.getOutputStream();
	             //生成压缩包
	             ZipOutputStream zip = new ZipOutputStream(ouputStream);
//	             zip.setEncoding("GBK");//指定编码为gbk,否则部署到linux下会出现乱码
	             int i = 1;
	             String eName;
	             //循环文件列表,添加到压缩包中
	             for(HSSFWorkbook workbook:excelList){
	                 //给每个文件名加序号
	                 eName=excelName+String.valueOf(i);
	                 //实例化一个压缩实体
	                 ZipEntry entry = new ZipEntry(eName+".xls");
	                 //将压缩实体放入压缩包
	                 zip.putNextEntry(entry);
	                 //将excel内容写进压缩实体
	                 workbook.write(zip);
	                 i++;
	             }
	             //将文件输出
	             zip.flush();
	             zip.close();
	             response.flushBuffer();  
	         } catch (Exception e) {
	        	 e.printStackTrace();
	         }
	    	
	    	
	    	
	    	
		
	}
		/**
	     * 生成Excel
	     * @param excelName   要导出的excel名称
	     * @param list       要导出的数据集合
	     * @param begin   数据集合的开始位置
	     * @param end      数据集合的结束位置
	     * @param fieldMap 中英文字段对应Map,即要导出的excel表头
	  
	     * @return
	     */ 
	    private static  HSSFWorkbook createExcel(String excelName,List> list,Integer begin,Integer end,LinkedHashMap fieldMap){

	        int sheetContent=2000;     //每个excel中sheet的容量

	        //计算sheet的数量
	        int sheetCount=0;
	        //如果总记录数  正好整除 以每个sheet的容量
	        if ((end-begin)%sheetContent==0){
	            //sheet的数量=总记录数 除以 每个sheet的容量
	            sheetCount=(end-begin)/sheetContent;
	        }else{
	            //sheet的数量=总记录数 除以 每个sheet的容量 加1
	            sheetCount=(end-begin)/sheetContent+1;
	        }

	        //创建一个WorkBook,对应一个Excel文件
	        HSSFWorkbook wb=new HSSFWorkbook();
	        //创建单元格,并设置值表头 设置表头居中
	        HSSFCellStyle style=wb.createCellStyle();
	        //创建一个居中格式
	        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

	        //定义sheet
	        HSSFSheet sheet=null;
	        //定义sheet的名称
	        String sheetName=excelName+"-";
	        //sheet中的数据开始位置
	        int beginSheet=0;
	        //sheet中的数据结束位置
	        int endSheet=0;

	        //循环创建sheet
	        for (int i=0;iend){
	                endSheet=end;
	            }

	            // 填充工作表
	            try {
	            	  fillSheet(sheet,list,beginSheet,endSheet,fieldMap,style);
	            } catch (Exception e) {
                 e.printStackTrace();
	            }
	        }
	        //返回excel
	        return wb;
	    }
/**
 * 
* @Title: fillSheet
* @Description: (向每一个sheet页中填充row)
* @param sheet 页对象
* @param list  数据集合
* @param beginSheet   这一页开始的数据
* @param endSheet  这一夜结束的数据
* @param fieldMap   表头中文字段和数据库字段  键为数据库字段 值为中文字段
* @param style   表头样式
* @return void
 */
	    private static void fillSheet(HSSFSheet sheet, List> list, int beginSheet, int endSheet,
				LinkedHashMap fieldMap, HSSFCellStyle style) {
	    	   // 定义存放英文字段名和中文字段名的数组
	    	    //英文为键中文为值
	        String[] enFields = new String[fieldMap.size()];
	        String[] cnFields = new String[fieldMap.size()];

	        // 将值分别填入两个数组
	        int count = 0;
	        for (Entry entry : fieldMap.entrySet()) {
	            enFields[count] = entry.getKey();
	            cnFields[count] = entry.getValue();
	            count++;
	        }
	        int   rowIndex=0;//行的数量
	        //在sheet中添加表头第0行
	        HSSFRow row=sheet.createRow(rowIndex++);

	        // 填充表头
	        for (int i = 0; i < cnFields.length; i++) {
	            HSSFCell cell=row.createCell(i);
	            cell.setCellValue(cnFields[i]);
	            cell.setCellStyle(style);
	            sheet.autoSizeColumn(20);
	        }

	        Map map=null;
      for(int i=beginSheet;i

你可能感兴趣的:(poi技术)