POI简介:Jakarta POI 是一套用于访问微软格式文档的Java API。Jakarta POI有很多组件组成,其中有用于操作Excel格式文件的HSSF和用于操作Word的HWPF,在各种组件中目前只有用于操作Excel的HSSF相对成熟。
官方主页http://poi.apache.org/index.html,
API文档http://poi.apache.org/apidocs/index.html
现在用的比较多的都是用POI技术来导出或者导入Excel,用POI导出Excel我们首先要下载所需的jar包然后导入到我们的项目中,用maven的同学只需找到相关依赖加入到pom.xml里面即可。这里我用maven导包。
<!--POI处理EXCEL-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.6</version>
</dependency>
Jakarta POI HSSF API组件:
HSSF(用于操作Excel的组件)提供给用户使用的对象在rg.apache.poi.hssf.usermodel包中,主要部分包括Excel对象,样式和格式,有以下几种常用的对象:
常用组件:
HSSFWorkbook excel的文档对象
HSSFSheet excel的表单
HSSFRow excel的行
HSSFCell excel的格子单元
HSSFFont excel字体
样式:
HSSFCellStyle cell样式
基本操作步骤:
首先,我们应该要知道的是,一个Excel文件对应一个workbook,一个workbook中有多个sheet组成,一个sheet是由多个行(row)和列(cell)组成。那么我们用poi要导出一个Excel表格
的正确顺序应该是:
1、用HSSFWorkbook打开或者创建“Excel文件对象”
2、用HSSFWorkbook对象返回或者创建Sheet对象
3、用Sheet对象返回行对象,用行对象得到Cell对象
4、对Cell对象读写。
5、将生成的HSSFWorkbook放入HttpServletResponse中响应到前端页面
工具类代码:
package com.self.util;
import org.apache.poi.hssf.usermodel.*;
/**
* @ClassName ExcelUtil
* @Description Excel生成工具类
* @Author zxl
* @Date 2019/2/1 10:30
* @Version 1.0
*/
public class ExcelUtil {
/**
*@Author S12434
*@Description 导出Excel
*@Date 10:36 2019/2/1
*@Param [sheetName sheet名称, title 标题, values 内容, wb HHSWorkbook对象]
*@Return org.apache.poi.hssf.usermodel.HSSFWorkbook
*/
public static HSSFWorkbook getHHSWorkbook(String sheetName,String[] title,String[][] values,HSSFWorkbook wb ){
//第一步,创建一个HSSFWorkbook,对应一个Excel文件
if(wb==null){
wb=new HSSFWorkbook();
}
//第二步,在workbook中添加一个sheet,对应Excel文件中的sheet
HSSFSheet sheet=wb.createSheet(sheetName);
//第三步,在sheet中添加表头第0行,注意老版本poi对EXCEL的行数列数的限制
HSSFRow row=sheet.createRow(0);
//第四步,创建单元格,并设置值表头,设置表头居中
HSSFCellStyle style=wb.createCellStyle();
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//声明列对象
HSSFCell cell=null;
//创建标题
for(int i=0;i<title.length;i++){
cell=row.createCell(i);
cell.setCellValue(title[i]);
cell.setCellStyle(style);
}
//创建内容
for(int i=0;i<values.length;i++){
row = sheet.createRow(i + 1);
for(int j=0;j<values[i].length;j++){
row.createCell(j).setCellValue(values[i][j]);
}
}
return wb;
}
}
控制器代码:
package com.self.controller;
import com.self.common.Criteria;
import com.self.entity.OsInput;
import com.self.service.IOsInputService;
import com.self.util.ExcelUtil;
import com.self.util.QueryUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.*;
/**
* @ClassName ExcelReportController
* @Description Excel报表导出类
* @Author zxl
* @Date 2019/2/1 11:10
* @Version 1.0
*/
@Controller
@RequestMapping("/excel")
public class ExcelReportController {
@Autowired
IOsInputService iOsInputService;
@RequestMapping("/inputExport")
@ResponseBody
public Map<String,String> inputExport(HttpServletRequest request,HttpServletResponse response,String order,String sort) {
Map<String,String> map= new HashMap<>();
map.put("statusCode","200");
map.put("message","导出成功!");
Enumeration<?> e = request.getParameterNames();
TreeMap<String, Object> params = new TreeMap<String, Object>();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
Object value = request.getParameter(name);
if (value != null && !"".equals(value)) {
params.put(name, value);
}
}
String[] sortBy = null;//排序的字段
Sort s=null;
if (sort != null) {
sortBy = sort.split(",");
Sort.Direction direction = Sort.Direction.ASC;
if ("desc".equals(order)) {
direction = Sort.Direction.DESC;
}
s = new Sort(direction, sortBy);
}
Criteria<OsInput> c = new Criteria<OsInput>();
for (Map.Entry<String, Object> entry : params.entrySet()) {
// //Map里面有值表示有查询条件
switch (entry.getKey().toString()){
case "conditions":
QueryUtils.queryConditions(c, (String)entry.getValue());
break;
default:
break;
}
}
List<OsInput> list=iOsInputService.findAll(c,s);
//excel标题
String[] title = {"编号","用品名称","供应商","规格型号","类别","计量单位","库位","入库数量","单价","税后单价","税","金额","税后金额","入库时间","操作人工号","操作人姓名","备注"};
//excel文件名
String fileName = "办公用品出库记录"+System.currentTimeMillis()+".xls";
//sheet名
String sheetName = "办公用品出库记录表";
String [][] content=new String[list.size()][title.length];
for(int i=0;i<list.size();i++){
OsInput osInput=list.get(i);
content[i][0]=osInput.getOsiIndex().toString();//编号
content[i][1]=osInput.getOsiName();//用品名称
content[i][2]=osInput.getOsiSupName();//供应商
content[i][3]=osInput.getOsiModel();//规格型号
content[i][4]=osInput.getOsiTypeName();//类别
content[i][5]=osInput.getOsiUnitName();//计量单位
content[i][6]=osInput.getOsiStorehouse();//库位
content[i][7]=osInput.getOsiInputqty().toString();//入库数量
content[i][8]=osInput.getOsiPrice().toString();//单价
content[i][9]=osInput.getOsiPricetax().toString();//税后单价
content[i][10]=osInput.getOsiTaxname();//税
content[i][11]=osInput.getOsiCost().toString();//金额
content[i][12]=osInput.getOsiCosttax().toString();//税后金额
content[i][13]=osInput.getOsiInputdate().toString();//入库时间
content[i][14]=osInput.getOsiUsercode();//操作人工号
content[i][15]=osInput.getOsiUsername();//操作人姓名
content[i][16]=osInput.getOsiDesc();//备注
}
//创建HSSFWorkbook
HSSFWorkbook wb= ExcelUtil.getHHSWorkbook(sheetName,title,content,null);
try{
this.setResponseHeader(response,fileName);
OutputStream os=response.getOutputStream();
wb.write(os);
os.flush();
os.close();
return map;
}catch (Exception ec){
ec.printStackTrace();
map.put("statusCode","500");
map.put("message","导出失败:"+ec.getMessage()+"!");
return map;
}
}
/**
*@Author zxl
*@Description 发送响应流方法
*@Date 13:40 2019/2/11
*@Param [response, fileName]
*@Return void
*/
public void setResponseHeader(HttpServletResponse response, String fileName) {
try {
try {
fileName = new String(fileName.getBytes(),"ISO8859-1");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.setContentType("application/octet-stream;charset=ISO8859-1");
response.setHeader("Content-Disposition", "attachment;filename="+ fileName);
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
前端代码:
function excelExport(){
var osiIndex = $("#osiIndex").combobox("getValue");//办公用品
var osiSupid = $("#osiSupid").combobox("getValue");//供应商
var osiModel = $("#osiModel").textbox("getValue");//规格型号
var osiTypecode = $("#osiTypecode").combobox("getValue");//类别
var startTime = $("#startTime").datebox("getValue").split("-").join("").split(" ").join("").split(":").join("");//入库日期从
var endTime = $("#endTime").datebox("getValue").split("-").join("").split(" ").join("").split(":").join("");//至
var osiUsercode = $("#osiUsercode").combobox("getValue");//操作人
//结束时间不能比开始时间小
if ("" != startTime && "" == endTime) {
} else {
if (!compareDateTime(endTime, startTime)) {
$.messager.alert("警告", "结束时间大于开始时间", "warning");
return;
}
}
var conditions = [];
conditions.push("osiIndex_equal:" + osiIndex);//办公用品
conditions.push("osiSupid_equal:" + osiSupid);//供应商
conditions.push("osiModel_like:" + osiModel);//规格型号
conditions.push("osiTypecode_equal:" + osiTypecode);//类别
conditions.push("osiInputdate_startTimeHms:" + startTime);//入库日期从
conditions.push("osiInputdate_endTimeHms:" + endTime);//至
conditions.push("osiUsercode_equalTotal:" + osiUsercode);//操作人
// $.ajax({
// url:'../excel/inputExport?sort=osiInputdate&order=asc&conditions=' + conditions,
// dataType:'json',
// type:'post',
// traditional: true,
// success:function(data){
// alert(data.message);
//
// }
// });
window.location.href='../excel/inputExport?sort=osiInputdate&order=asc&conditions=' + conditions;
}
从前端代码可以看到,ajax访问后台的方式被注释了,那是因为$.ajax,$.post 不支持返回二进制文件流的类型,dataType只支持xml,json,script,html这几种格式,没有blob类型。所以若要采用异步导出EXCEL的方式,只能选择使用原生Ajax XMLReques对象进行处理。
原生ajax异步请求参考文档:
只需要修改前端代码即可。
var xhr ;
if(window.XMLHttpRequest){//code for IE7+,Firefox,Chrome,Opera,Safari
xhr = new XMLHttpRequest();
}else{//code for IE6,IE5
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var url = '../excel/inputExport?sort=osiInputdate&order=asc&conditions=' + conditions;
//设置响应类型为blob类型
xhr.responseType = "blob";
xhr.open("post", url, true);
xhr.onload = function () {
if (this.status == "200") {
//获取响应文件流
var blob = this.response;
var reader = new FileReader();
reader.readAsDataURL(blob); // 转换为base64,可以直接放入a表情href
reader.onload = function (e) {
// 转换完成,创建一个a标签用于下载
var a = document.createElement('a');
a.download = '办公用品.xls';
a.href = e.target.result;
$("body").append(a); // 修复firefox中无法触发click
a.click();
$(a).remove();
}
}
}
xhr.send();
}
另:需总结JAVA文件下载的几种方式