POI报表

作者: Ivon_Ma | 来源:发表于2017-08-02 20:07 被阅读156次

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;
    }

相关文章

网友评论

      本文标题:POI报表

      本文链接:https://www.haomeiwen.com/subject/mjbylxtx.html