Excel报表打印(POI)
1.需求说明
在企业级应用开发中,Excel报表是一种最常见的报表需求。Excel报表开发一般分为两种形式:
1、为了方便操作,基于Excel的报表批量上传数据
2、通过java代码生成Excel报表。
2.Excel报表概述
目前市面上的Excel分为两大版本Excel2003和Excel2007及以上两个版本,它们区别如下:
3.常见的Excel操作工具
Java中常见的用来操作Excl的方式一般有2种:JXL和POI。
JXL只能对Excel进行操作,属于比较老的框架,它只支持到Excel 95-2000的版本。现在已经停止更新和维护。
POI是apache的项目,可对微软的Word,Excel,Ppt进行操作,包括office2003和2007,Excl2003和2007。poi现在一
直有更新。所以现在主流使用POI。
4.POI是什么
Apache POI是Apache软件基金会的开源项目,由Java编写的免费开源的跨平台的 Java API,Apache POI提供API给
Java语言操作Microsoft Office的功能。
Apache POI是目前最流行的操作Microsoft Office的API组件,借助POI可以方便的完成诸如:数据报表生成,数据批
量上传,数据备份等工作
5.POI入门
搭建环境
引入坐标
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <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>
API说明
HSSF提供读写Microsoft Excel XLS格式档案的功能。 2003版本
XSSF提供读写Microsoft Excel OOXML XLSX格式档案的功能。2007版本
创建Excel
public class PoiTest01 { /** * 创建一个excel * 创建excel: * 1.创建工作簿 * 2.创建sheet * 3.创建行对象 * 4.创建单元格 * 5.对单元格赋值 * 6.设置样式 * 7.下载 */ @Test public void test() throws Exception { //1.创建一个工作簿 //Workbook wb = new HSSFWorkbook(); //处理excel2003版本 .xls Workbook wb = new XSSFWorkbook();//处理excel2007及以上版本 .xlsx //new SXSSFWorkbook();// 处理大数据量excel报表对象 //2.创建sheet Sheet sheet = wb.createSheet("abc"); //3.创建行对象 Row row = sheet.createRow(1);//接受参数 ,数组下标 //4.创建单元格 Cell cell = row.createCell(1);//数组下表 //5.设置单元格内容 cell.setCellValue("大幂幂"); //设置样式 /** * 1.创建样式对象 * 2.通过样式对象指定样式 * 3.配置单元个样式 */2.3、读取excel CellStyle cellStyle = wb.createCellStyle(); //通过样式对象指定样式 cellStyle.setBorderTop(BorderStyle.THIN); //细线 cellStyle.setBorderBottom(BorderStyle.THIN); //细线 cellStyle.setBorderLeft(BorderStyle.THIN); //细线 cellStyle.setBorderRight(BorderStyle.THIN); //细线 //字体 对象 Font font = wb.createFont(); font.setFontName("华文行楷"); font.setFontHeightInPoints((short)26);//字号 cellStyle.setFont(font); cell.setCellStyle(cellStyle); //指定行高和列宽 sheet.setColumnWidth(1,20*256); //列宽 row.setHeightInPoints(30); //6.将excel保存到本地磁盘中 FileOutputStream fos = new FileOutputStream("E:\\text.xlsx"); wb.write(fos); fos.close(); } }
读取Excel
读取如下报表
/** * 加载excel文件,并读取内容 */ public class PoiTest02 { @Test public void test() throws Exception { //1.根据excel文件加载工作簿 Workbook wb = new XSSFWorkbook("E:\\demo1.xlsx"); //2.读取第一个sheet Sheet sheet = wb.getSheetAt(0);//数组下标 //3.循环sheet中的每一行 //sheet.getLastRowNum 获取最后一行的数组下标 for(int i=0;i<sheet.getLastRowNum()+1;i++) { Row row = sheet.getRow(i); //row.getLastCellNum() 获取最大行数 //4.读取行中的每一个单元格 String str = ""; for(int j=0;j<row.getLastCellNum();j++) { Cell cell = row.getCell(j); //5.获取单元格中的数据 if(cell != null) { str += getCellValue(cell); } } System.out.println(str); } } public Object getCellValue(Cell cell) { /** * 获取单元格的类型 */ CellType type = cell.getCellType(); Object result = null; switch (type) { case STRING:{ result = cell.getStringCellValue();//获取string类型数据 break; } case NUMERIC:{ /** * 判断 */ if(DateUtil.isCellDateFormatted(cell)) { //日期格式 result = cell.getDateCellValue(); }else{ //double类型 result = cell.getNumericCellValue(); //数字类型 } break; } case BOOLEAN:{ result = cell.getBooleanCellValue();//获取boolean类型数据 break; } default:{ break; } } return result; } }
思考
Excel报表打印项目实际操作上遇到的问题
从数据库查询出来的Excel数据并不一定是来自于一张表,可能来自于多张表
解决:我们需要自定义一个javaBean实体,从数据库查询出来返回到实体中
当然sql语句还是很重要的:
我们运用多表联查,并且可能要一些表单创建时间查询,这里我们
用到了MySql的日期函数
场景
附一条sql语句
<!--查询报表数据-->
<select id="findByCreateTime" parameterType="map" resultType="cn.jia.domain.vo.ContractProductVo">
SELECT
c.custom_name customName,
c.contract_no contractNo,
cp.product_no productNo,
cp.cnumber cnumber,
cp.factory_name factoryName,
c.delivery_period deliveryPeriod,
c.ship_time shipTime,
c.trade_terms tradeTerms
FROM co_contract c,co_contract_product cp
WHERE c.id = cp.contract_id
and c.company_id = #{companyid}
AND DATE_FORMAT(create_time,'%Y-%m') = #{inputDate}
</select>
附Mysql日期函数
MySQL DATE_FORMAT() 函数
定义和用法
DATE_FORMAT() 函数用于以不同的格式显示日期/时间数据。
语法
DATE_FORMAT(date,format)
date 参数是合法的日期。format 规定日期/时间的输出格式。
可以使用的格式有:
格式 |
描述 |
%a |
缩写星期名 |
%b |
缩写月名 |
%c |
月,数值 |
%D |
带有英文前缀的月中的天 |
%d |
月的天,数值(00-31) |
%e |
月的天,数值(0-31) |
%f |
微秒 |
%H |
小时 (00-23) |
%h |
小时 (01-12) |
%I |
小时 (01-12) |
%i |
分钟,数值(00-59) |
%j |
年的天 (001-366) |
%k |
小时 (0-23) |
%l |
小时 (1-12) |
%M |
月名 |
%m |
月,数值(00-12) |
%p |
AM 或 PM |
%r |
时间,12-小时(hh:mm:ss AM 或 PM) |
%S |
秒(00-59) |
%s |
秒(00-59) |
%T |
时间, 24-小时 (hh:mm:ss) |
%U |
周 (00-53) 星期日是一周的第一天 |
%u |
周 (00-53) 星期一是一周的第一天 |
%V |
周 (01-53) 星期日是一周的第一天,与 %X 使用 |
%v |
周 (01-53) 星期一是一周的第一天,与 %x 使用 |
%W |
星期名 |
%w |
周的天 (0=星期日, 6=星期六) |
%X |
年,其中的星期日是周的第一天,4 位,与 %V 使用 |
%x |
年,其中的星期一是周的第一天,4 位,与 %v 使用 |
%Y |
年,4 位 |
%y |
年,2 位 |
实例
下面的脚本使用 DATE_FORMAT() 函数来显示不同的格式。我们使用 NOW() 来获得当前的日期/时间:
DATE_FORMAT(NOW(),'%b %d %Y %h:%i %p')
DATE_FORMAT(NOW(),'%m-%d-%Y')
DATE_FORMAT(NOW(),'%d %b %y')
DATE_FORMAT(NOW(),'%d %b %Y %T:%f')
结果类似:
Dec 29 2008 11:45 PM
12-29-2008
29 Dec 08
29 Dec 2008 16:25:46.635