POI报表

1.POI主要功能

可以操作office文档的Java API

主要功能:操作excel文档

​ 虽然也可以操作word文档,但功能比较差。Java中并没有优秀的word解析技术。

​ 解析word建议使用.net技术。Java利用WebService技术获取解析结果。

​ 为何要用专业组件来解析Excel?

​ 因为Excel不是一个单纯的文本格式。

与其他excel解析技术的比较:

​ JXL:只能操作excel2003(现在也能操作2007-2016了)

​ POI:可以操作整个office(excel,doc,vb宏,ppt,visio)

2.POI支持的解析方式

  • HSSF解析(.xls Excel97-03版本)

  • XSSF解析(.xlsx Excel07-16版本)

    解析方式不同,是由于两类版本excel文件本身的实现有不同

3.应用场景

  • 导入excel数据

    ​ 将excel中的备份数据还原到数据库

  • 导出excel数据

    ​ 将数据库中的数据导出或备份

4. 快速入门:

Maven坐标

<!--操作97-03版本用-->
<dependency> 
    <groupId>org.apache.poi</groupId> 
    <artifactId>poi</artifactId> 
    <version>3.11</version> 
</dependency>
<!--操作07-16版本用-->
<dependency> 
    <groupId>org.apache.poi</groupId> 
    <artifactId>poi-ooxml</artifactId> 
    <version>3.11</version> 
</dependency>
<!--?-->
<dependency> 
    <groupId>org.apache.poi</groupId> 
    <artifactId>poi-ooxml-schemas</artifactId> 
    <version>3.11</version> 
</dependency>

实现步骤:

  1. 创建工作簿
  2. 创建sheet
  3. 创建行对象
  4. 创建单元格对象
  5. 设置内容
  6. 设置内容格式
    ​ 使用wb去创建内容格式,是由于创建出的字体是在工作簿内公共使用的。
    1. 设置字体
    2. 设置字体大小
    3. 创建cellStyle
    4. 将cellStyle赋给cell
  7. 将 工作簿写入输出流
  8. 下载

简单Demo:

package cn.itcast.jx.poi;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

public class POITest {

    @SuppressWarnings("resource")
    public static void main(String[] args) throws Exception {
        //1 创建工作薄:Workbook是一个接口,它有一个实现类HSSFWorkbook对象,这个对象专门操作excel97-03,excel的后缀名是xls
        Workbook wb = new HSSFWorkbook();
        //2 创建工作表sheet:工作表
        Sheet sheet = wb.createSheet();
        //3 创建行对象,java中从0开始计数
        Row row = sheet.createRow(3);
        //4 创建列对象
        Cell cell = row.createCell(3);
        //5 设置内容
        cell.setCellValue("itcast,一统江湖");
        //6 设置内容格式
        Font font = wb.createFont();
        font.setFontHeightInPoints((short)24);//以像素点的方式设置字体大小
        font.setFontName("华文彩云");//设置字体
        
        //System.out.println(Short.MIN_VALUE+"-"+Short.MAX_VALUE);
        //创建格式
        CellStyle cellStyle = wb.createCellStyle();
        cellStyle.setFont(font);
        
        //将cellStyle给cell
        cell.setCellStyle(cellStyle);
        //7 保存(javase项目采用保存)
        FileOutputStream stream = new FileOutputStream(new File("d://a.xls"));
        wb.write(stream);//将对象写进流
        
        stream.flush();
        stream.close();
        //8 下载(web项目 才有下载)
        System.out.println("运行结束");
    }
}

项目应用Demo:出货单打印:

package cn.itcast.jx.action.cargo;

import java.io.ByteArrayOutputStream;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.CellRangeAddress;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.struts2.ServletActionContext;
import org.hibernate.type.descriptor.sql.BitTypeDescriptor;

import cn.itcast.jx.action.BaseAction;
import cn.itcast.jx.domain.ContractProduct;
import cn.itcast.jx.service.ContractProductService;
import cn.itcast.jx.util.DownloadUtil;
import cn.itcast.jx.util.UtilFuns;
/**
 * 打印出货表:选择时间(船期)
 */
public class OutProductAction extends BaseAction {
    //获取页面提交的打印月份
    private String inputDate;
    
    public String getInputDate() {
        return inputDate;
    }
    public void setInputDate(String inputDate) {
        this.inputDate = inputDate;
    }
    //跳转到打印页面
    public String toedit() throws Exception {
        return "toedit";
    }
    //依赖注入
    private ContractProductService contractProductService;
    
    public void setContractProductService(
            ContractProductService contractProductService) {
        this.contractProductService = contractProductService;
    }
    //打印excel文档:
    @SuppressWarnings("resource")
    public String print() throws Exception {
        //创建工作表
        Workbook wb = new HSSFWorkbook();
        //创建工作表
        Sheet sheet = wb.createSheet();
        
        //设置列宽
        sheet.setColumnWidth(0, 6*256);
        sheet.setColumnWidth(1, 26*256);
        sheet.setColumnWidth(2, 12*256);
        sheet.setColumnWidth(3, 30*256);
        sheet.setColumnWidth(4, 12*256);
        sheet.setColumnWidth(5, 15*256);
        sheet.setColumnWidth(6, 10*256);
        sheet.setColumnWidth(7, 10*256);
        sheet.setColumnWidth(8, 10*256);
        
      //定义一些公共变量
        //行对象
        Row nRow = null;
        //单元格对象
        Cell nCell = null;  
        //行号和列号
        int rowNo = 0;
        int cellNo = 1;
        
        /************大标题的打印**************/
        nRow = sheet.createRow(rowNo);
        nCell = nRow.createCell(cellNo);
        //横向合并单元格
        sheet.addMergedRegion(new CellRangeAddress(0,0,1,8));
        
        //设置内容:
        //设置内容:
        /**
         * 2012-01:
         * 2012-10:
         * 
         * 方式一:inputDate.replace("-0","-").replace("-","年")
         * 方式二:inputDate.replace("-0","年").replace("-","年")
         * 
         */
        nCell.setCellValue(inputDate.replace("-0","-").replace("-","年")+"月出货表");
        
        //行高?样式?
        nRow.setHeightInPoints(36f);
        nCell.setCellStyle(bigTitle(wb));
        
        /************小标题的打印**************/
        //先换行
        rowNo++;
        //创建行对象
        nRow = sheet.createRow(rowNo);
        
        String[] titles = {"客户","订单号","货号","数量","工厂","工厂交期","船期","贸易条款"};
        //遍历标题,进行输出打印
        for(String title:titles){
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(title);
            nCell.setCellStyle(title(wb));
        }
        
        /************内容的打印**************/
        //准备数据
        //String hql = "from ContractProduct where contract.shipTime like '%"+inputDate+"%'";//mysql支持,oracle不支持
        //hql中有to_char函数吗?没有,这是oracle中的pl/sql函数
        //但是,hibernate强大的地方就在:你可以在HQL中使用数据库中的函数
        String hql = "from ContractProduct where to_char(contract.shipTime,'yyyy-mm') = '"+inputDate+"'";//oracle支持
        //查询:
        List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);
        
        //将数据放入sheet中
        for(ContractProduct cp:list){
            //行变化
            rowNo++;
            nRow = sheet.createRow(rowNo);
            //列
            cellNo = 1;//规1
            
            //"客户",
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getContract().getCustomName());
            nCell.setCellStyle(text(wb));
            
            //"订单号",
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getContract().getContractNo());
            nCell.setCellStyle(text(wb));
            //"货号",
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getProductNo());
            nCell.setCellStyle(text(wb));
            //"数量",
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getCnumber());
            nCell.setCellStyle(text(wb));
            //"工厂",
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getFactoryName());
            nCell.setCellStyle(text(wb));
            //"工厂交期",
            nCell = nRow.createCell(cellNo++);
            //用SimpleDateFormat也行
            nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));
            nCell.setCellStyle(text(wb));
            //"船期",
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));
            nCell.setCellStyle(text(wb));
            //"贸易条款"
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getContract().getTradeTerms());
            nCell.setCellStyle(text(wb));
            
        }
        
        
        /************下载**************/
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        //将内容写入流
        wb.write(byteArrayOutputStream);
        //使用流
        DownloadUtil downloadUtil = new DownloadUtil();
        
        HttpServletResponse response = ServletActionContext.getResponse();
        
        /**
         * 第一个:文件流
         * 第二个:response
         * 第三个:下载的文件的名字
         */
        downloadUtil.download(byteArrayOutputStream, response, "itcast.xls");
        
        return NONE;
    }
    //大标题的样式
    public CellStyle bigTitle(Workbook wb){
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("宋体");
        font.setFontHeightInPoints((short)16);
        font.setBoldweight(Font.BOLDWEIGHT_BOLD);                   //字体加粗
        
        style.setFont(font);
        
        style.setAlignment(CellStyle.ALIGN_CENTER);                 //横向居中
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);      //纵向居中
        
        return style;
    }
    //小标题的样式
    public CellStyle title(Workbook wb){
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("黑体");
        font.setFontHeightInPoints((short)12);
        
        style.setFont(font);
        
        style.setAlignment(CellStyle.ALIGN_CENTER);                 //横向居中
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);      //纵向居中
        
        style.setBorderTop(CellStyle.BORDER_THIN);                  //上细线
        style.setBorderBottom(CellStyle.BORDER_THIN);               //下细线
        style.setBorderLeft(CellStyle.BORDER_THIN);                 //左细线
        style.setBorderRight(CellStyle.BORDER_THIN);                //右细线
        
        return style;
    }
    
    //文字样式
    public CellStyle text(Workbook wb){
        CellStyle style = wb.createCellStyle();
        Font font = wb.createFont();
        font.setFontName("Times New Roman");
        font.setFontHeightInPoints((short)10);
        
        style.setFont(font);
        
        style.setAlignment(CellStyle.ALIGN_LEFT);                   //横向居左
        style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);      //纵向居中
        
        style.setBorderTop(CellStyle.BORDER_THIN);                  //上细线
        style.setBorderBottom(CellStyle.BORDER_THIN);               //下细线
        style.setBorderLeft(CellStyle.BORDER_THIN);                 //左细线
        style.setBorderRight(CellStyle.BORDER_THIN);                //右细线
        
        return style;
    }
}

5.使用模板的实现

​ 模板即是一个已经设置好部分样式的excel文档。
​ 标题行,列宽行高,字体颜色等可以在模板中先设置好。

步骤

  1. 制作模板文件

  2. 读取模板文件,获取工作簿

    //路径
    String path = ServletActionContext.getRequest().getRealPath("/");
    path += "/make/xlsprint/tOUTPRODUCT.xls";
    //输入流
    FileInputStream is = new FileInputStream(new File(path));    
    //借助模板创建工作簿
    Workbook wb = new HSSFWorkbook(is);
    
  3. 获取sheet

    Sheet sheet = wb.getSheetAt(0);
    
  4. 获取行

  5. 获取某单元格的格式

    CellStyle customerCellStyle = nRow.getCell(cellNo++).getCellStyle();
    
  6. 设置内容及格式

  7. 将工作簿写入输出流

  8. 下载

项目应用Demo:

    @SuppressWarnings("resource")
    public String print() throws Exception {
        //读取模板,路径
        String path = ServletActionContext.getRequest().getRealPath("/");
        path += "/make/xlsprint/tOUTPRODUCT.xls";//获取模板在服务器的路径
        
        FileInputStream is = new FileInputStream(new File(path));
        
        //1 借助模板创建工作簿
        Workbook wb = new HSSFWorkbook(is);
        //2 获取工作表
        Sheet sheet = wb.getSheetAt(0);
        
        //定义公共变量
        Row nRow = null;//行对象
        Cell nCell = null;//单元格对象
        
        int rowNo = 0;//第几行
        int cellNo = 1;//列对象
            
        /*******************设置大标题********************/
        //3 获取行对象
        nRow = sheet.getRow(rowNo);
        //4 获取单元格
        nCell = nRow.getCell(cellNo);   
        // 5 设置数据
        nCell.setCellValue(inputDate.replace("-0", "-").replace("-", "年")+"月份出货表");
        // 6 设置样式,获取原来的样式赋值,这步可以省略
        //nCell.setCellStyle(nCell.getCellStyle());

        /*******************设置小标题********************/
        rowNo++;//跳过小标题行,因为模板中已经设置好 
        
        /*******************设置出货数据********************/
        rowNo++;//进入数据第一行行
        //获取样式
        nRow = sheet.getRow(rowNo);
        
        //客户    
        CellStyle customerCellStyle = nRow.getCell(cellNo++).getCellStyle();
        //订单号   
        CellStyle contractNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
        //货号    
        CellStyle productNoCellStyle = nRow.getCell(cellNo++).getCellStyle();
        //数量    
        CellStyle cnumberCellStyle = nRow.getCell(cellNo++).getCellStyle();
        //工厂    
        CellStyle factoryCellStyle = nRow.getCell(cellNo++).getCellStyle();
        //工厂交期  
        CellStyle deliveryPeriodCellStyle = nRow.getCell(cellNo++).getCellStyle();
        //船期    
        CellStyle shipTimeCellStyle = nRow.getCell(cellNo++).getCellStyle();
        //贸易条款
        CellStyle tradeTermsCellStyle = nRow.getCell(cellNo++).getCellStyle();
        
        // 准备数据
        //mysql方式(oracle不支持):
        //String hql = "from ContractProduct where contract.shipTime like '%"+inputDate+"%'";
        //Oracle方式:to_char可以将Date转成varchar,oracle中的所有的PL/SQL函数都可以直接写在hql语句中
        String hql = "from ContractProduct where to_char(contract.shipTime,'yyyy-mm')='"+inputDate+"'";
        //从数据库查找要输出的货物的集合
        List<ContractProduct> list = contractProductService.find(hql, ContractProduct.class, null);
        for(ContractProduct cp:list){
            //单元格no归1
            cellNo = 1;         
            //一条数据创建一行
            nRow = sheet.createRow(rowNo);
            //创建每列的数据
            //客户    
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getContract().getCustomName());
            nCell.setCellStyle(customerCellStyle);          
            //订单号   
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getContract().getContractNo());
            nCell.setCellStyle(contractNoCellStyle);
            //货号    
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getProductNo());
            nCell.setCellStyle(productNoCellStyle);
            //数量    
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getCnumber());
            nCell.setCellStyle(cnumberCellStyle);
            //工厂    
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getFactoryName());
            nCell.setCellStyle(factoryCellStyle);
            //工厂交期  
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getDeliveryPeriod()));
            nCell.setCellStyle(deliveryPeriodCellStyle);
            
            //船期    
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(UtilFuns.dateTimeFormat(cp.getContract().getShipTime()));
            nCell.setCellStyle(shipTimeCellStyle);
            //贸易条款
            nCell = nRow.createCell(cellNo++);
            nCell.setCellValue(cp.getContract().getTradeTerms());
            nCell.setCellStyle(tradeTermsCellStyle);
            
            //切到下一行,准备下一行数据操作
            rowNo++;
        }
        
        
        /***************************************************/
        // 7.写入流
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();//字节数组缓冲流
        wb.write(byteArrayOutputStream);        
        // 8.下载
        DownloadUtil downloadUtil = new DownloadUtil();
        HttpServletResponse response = ServletActionContext.getResponse();
        /**
         * 第一个参数:流
         * 第二个参数:response
         * 第三个参数:下载的文件名
         */
        downloadUtil.download(byteArrayOutputStream, response, "出货表.xls");
                
        return NONE;
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • POI操作Excel Excel简介一个excel文件就是一个工作簿workbook,一个工作簿中可以创建多张工作...
    灰气球阅读 4,705评论 2 48
  • Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Ja...
    玩味Orz阅读 2,608评论 0 0
  • 使用首先需要了解他的工作原理 1.POI结构与常用类 (1)创建Workbook和Sheet (2)创建单元格 (...
    长城ol阅读 8,411评论 2 25
  • 转自链接 3.项目实践 3.1基于.xls模板生成Excel文件 3.2生成九九乘法表 3.3生成一张工资单 3....
    腿毛裤阅读 3,436评论 0 0
  • VBA订制工具栏 http://club.excelhome.net/thread-1047254-1-1.htm...
    大海一滴写字的地方阅读 2,242评论 0 0