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

 


 

posted @ 2019-07-17 21:41  MonstersU  阅读(1217)  评论(0编辑  收藏  举报