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閱讀 227,488評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內容

  • POI操作Excel Excel簡介一個excel文件就是一個工作簿workbook,一個工作簿中可以創建多張工作...
    灰氣球閱讀 4,730評論 2 48
  • Apache POI 是用Java編寫的免費開源的跨平臺的 Java API,Apache POI提供API給Ja...
    玩味Orz閱讀 2,630評論 0 0
  • 使用首先需要了解他的工作原理 1.POI結構與常用類 (1)創建Workbook和Sheet (2)創建單元格 (...
    長城ol閱讀 8,470評論 2 25
  • 轉自鏈接 3.項目實踐 3.1基于.xls模板生成Excel文件 3.2生成九九乘法表 3.3生成一張工資單 3....
    腿毛褲閱讀 3,470評論 0 0
  • VBA訂制工具欄 http://club.excelhome.net/thread-1047254-1-1.htm...
    大海一滴寫字的地方閱讀 2,261評論 0 0