一.POI报表
在企业开发中,Excel报表是一种最常见的报表需求,Excel报表开发一般分为两种形式:
(1)为了方便操作,基于Excel的报表批量上传数据
(2)通过java代码,快速生成Excel报表
POI报表简介:
Apache POI是Apache软件基金会的开源项目,由Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java语言操作Microsoft Office的功能。
Excel分为两个大的版本Excel2003和Excel2007及以上两个版本:
区别 | Excel 2003 | Excel 2007及以上 |
---|---|---|
扩展名 | xls | xlsx |
数据结构 | 二进制格式 | xml格式 |
单sheet数据量 | 行:65535、列:256 | 行:1048576、列:16384 |
特点 | 存储容量有限 | 基于xml压缩,占用空间小,操作效率高 |
API对象介绍
-
工作簿(表): WorkBook (HssfWordBook:2003版本,XssfWorkBook:2007及以上)
-
页:Sheet
-
行:Row
-
单元格:Cell
二.快速入门
1.创建项目,环境搭建,导入pom.xml的坐标文件
<dependencies>
<!--2003版本-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<!--2007及以上版本-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<!--处理百万数据-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.0.1</version>
</dependency>
</dependencies>
2.通过java创建Excel
public class CreateDemo {
/*
通过java代码创建excel
*/
public static void main(String[] args)throws Exception {
// 1.创建工作表
/*
HSSFWorkbook:2003版本
XSSFWorkbook:2007及以上版本
SXSSFWorkbook:处理百万数据
*/
Workbook wb = new XSSFWorkbook();
// 2.创建第一页
Sheet sheet = wb.createSheet("poi入门");
// 指定第三列宽度 24
sheet.setColumnWidth(2, 24*256); // poi的设计者把我们设置的宽度 除以256
// 3.创建第三行
Row row = sheet.createRow(2);// 指定行索引行
// 4.创建第三个单元格
Cell cell = row.createCell(2);// 指定索引列
// 5.填充数据
cell.setCellValue("北京欢迎你");
// 6.保存到本地
FileOutputStream out = new FileOutputStream("d:/demo.xlsx");
wb.write(out);
}
}
3.通过java解析Excel
注意:excel单元格类型为:
-
string
-
number
-
boolean
-
date
public class ParseDemo {
/*
通过java代码解析excel
*/
public static void main(String[] args) throws IOException {
// 1.加载已有的excel工作表
Workbook wb = new XSSFWorkbook("C:\\Users\\wsl\\Desktop\\demo.xlsx");
// 2.获取第一页
Sheet sheet = wb.getSheetAt(0);
// 3.遍历行
// sheet.getLastRowNum(); 获取最后一个有数据行的索引号(索引是从0开始),返回值4
for (int i = 0; i < sheet.getLastRowNum() + 1; i++) {
Row row = sheet.getRow(i);
// 4.遍历单元格
// row.getLastCellNum(); 获取最后一个有数据列的编号(编号是从1开始),返回值6
for (int j = 2; j < row.getLastCellNum(); j++) {
Cell cell = row.getCell(j);
// 5.获取单元格的数据
// System.out.print(cell.getStringCellValue()+" ");
System.out.print(getCellValue(cell)+" ");
}
System.out.println(" ");// 换行
}
}
//解析每个单元格的数据
public static Object getCellValue(Cell cell) {
Object obj = null;
CellType cellType = cell.getCellType(); //获取单元格数据类型
switch (cellType) {
case STRING: {
obj = cell.getStringCellValue();//字符串
break;
}
//excel默认将日期也理解为数字
case NUMERIC: {
if (DateUtil.isCellDateFormatted(cell)) {
obj = cell.getDateCellValue();//日期
} else {
obj = cell.getNumericCellValue(); // 数字
}
break;
}
case BOOLEAN: {
obj = cell.getBooleanCellValue(); // 布尔
break;
}
default: {
break;
}
}
return obj;
}
}
三.案例:
按规定导出出货表,导出出货表的excel
自定义SQL语句:
-- 根据船期+企业id查询
SELECT
c.`custom_name` AS customName,
c.`contract_no` AS contractNo,
cp.`product_no` AS productNo,
cp.`cnumber`,
cp.`factory_name` AS factoryName,
c.`delivery_period` AS deliveryPeriod,
c.`ship_time` AS shipTime,
c.`trade_terms` AS tradeTerms
FROM `co_contract` c
INNER JOIN `co_contract_product` cp ON c.`id` = cp.`contract_id`
WHERE DATE_FORMAT(c.`ship_time`,'%Y-%m') = '2015-01' AND c.`company_id` = '1'
自定义VO对象
import java.io.Serializable;
import java.util.Date;
public class ContractProductVo implements Serializable {
private String customName; //客户名称
private String contractNo; //合同号,订单号
private String productNo; //货号
private Integer cnumber; //数量
private String factoryName; //厂家名称,冗余字段
private Date deliveryPeriod; //交货期限
private Date shipTime; //船期
private String tradeTerms; //贸易条款
public String getCustomName() {
return customName;
}
public void setCustomName(String customName) {
this.customName = customName;
}
public String getContractNo() {
return contractNo;
}
public void setContractNo(String contractNo) {
this.contractNo = contractNo;
}
public String getProductNo() {
return productNo;
}
public void setProductNo(String productNo) {
this.productNo = productNo;
}
public Integer getCnumber() {
return cnumber;
}
public void setCnumber(Integer cnumber) {
this.cnumber = cnumber;
}
public String getFactoryName() {
return factoryName;
}
public void setFactoryName(String factoryName) {
this.factoryName = factoryName;
}
public Date getDeliveryPeriod() {
return deliveryPeriod;
}
public void setDeliveryPeriod(Date deliveryPeriod) {
this.deliveryPeriod = deliveryPeriod;
}
public Date getShipTime() {
return shipTime;
}
public void setShipTime(Date shipTime) {
this.shipTime = shipTime;
}
public String getTradeTerms() {
return tradeTerms;
}
public void setTradeTerms(String tradeTerms) {
this.tradeTerms = tradeTerms;
}
@Override
public String toString() {
return "ContractProductVo{" +
"customName='" + customName + '\'' +
", contractNo='" + contractNo + '\'' +
", productNo='" + productNo + '\'' +
", cnumber=" + cnumber +
", factoryName='" + factoryName + '\'' +
", deliveryPeriod=" + deliveryPeriod +
", shipTime=" + shipTime +
", tradeTerms='" + tradeTerms + '\'' +
'}';
}
}
下载工具类:
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class DownloadUtils {
/**
* @param filePath 要下载的文件路径
* @param returnName 返回的文件名
* @param response HttpServletResponse
* @param delFlag 是否删除文件
*/
protected static void download(String filePath,String returnName,HttpServletResponse response,boolean delFlag){
prototypeDownload(new Fil