POI動態生成Excel

實習第二周 No.2

項目功能里要求能夠將展示的報表導出excel,因為報表的數據都是動態從list傳進來的,所以使用了POI技術來動態構建excel文件。
百科里說POI是介個樣子的
“ApachePOI是Apache軟件基金會的開放源碼函式庫,POI提供API給Java程序對MicrosoftOffice格式檔案讀和寫的功能”
簡單來說就是通過它的API可以進行創建/讀取文檔,sheet,行列單元格等操作,也可以設置文檔的各個樣式。
剛接觸這個任務的時候查了很多資料,最后主要是參考了這篇文章,程序復制粘貼就跑得通,對POI的整個理解可以得到很好地提升。
詳解JAVA POI導出EXCEL報表的操作(包括各種格式及樣式的實現)
然后參考著就實現了項目里要求的樣子啦

    private static HSSFWorkbook wb = new HSSFWorkbook(); 
    private static HSSFSheet sheet = wb.createSheet(); 
    public boolean exportTrstatistics(List<Map<String,Object>>headList,List<Map<String,Object>>headerList,List<Map<String,Object>>dicList) throws Exception {
   //ExportExcel 即上文作者編寫的工具類。
        ExportExcel exportExcel = new ExportExcel(wb, sheet); 
            // 計算該報表的列數 
            int number=headList.size();
            int t=0;
            for(int i=0;i<headList.size();i++)
            {
                BigInteger te=(BigInteger) headList.get(i).get("chilNum");
                t=te.intValue();
                if(t!=0)
//因為第一行表頭有可能包含第二行表頭,而如果有第二列表頭的時候以第二行表頭的個數為準,這里多算了一個第一行表頭,所以需要-1
                    number=number+t-1;
            }        
            System.out.println(number);     
            // 給工作表列定義列寬(實際應用自己更改列數) 
            for (int i = 0; i < number; i++) { 
            sheet.setColumnWidth(i, 3000); 

            } 
//因為項目對單元格樣式的要求不高,所以這里直接拿來主義了
            // 創建單元格樣式 
            HSSFCellStyle cellStyle = wb.createCellStyle(); 
            // 指定單元格居中對齊 
            cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); 
            // 指定單元格垂直居中對齊 
            cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); 
            // 指定當單元格內容顯示不下時自動換行 
            cellStyle.setWrapText(true); 
            // 設置單元格字體 
            HSSFFont font = wb.createFont(); 
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); 
            font.setFontName("宋體"); 
            font.setFontHeight((short) 200); 
            cellStyle.setFont(font); 
            // 創建報表頭部 
            createNormalHead("各單位各類培訓持證人數匯總報表", number); 
            // 設置列頭 
            HSSFRow row2 = sheet.createRow(2); 
// 設置行高 
            row2.setHeight((short) 500); 
            HSSFCell cell0 = row2.createCell(0); 
            cell0.setCellStyle(cellStyle); 
            cell0.setCellValue(new HSSFRichTextString("公司/單位名稱")); 
            HSSFRow row3 = sheet.createRow(3); 
            // 設置行高 
            row3.setHeight((short) 500); 
            HSSFCell row3Cell = null; 
            int childnum=0;
            int childstartnum=0;
            int count2=1;   //記錄單元格應放置位置的指針
            List<Integer>mergeList=new ArrayList<Integer>();
            for(int i=0;i<headList.size();i++)
            {
                BigInteger childnum1=(BigInteger) headList.get(i).get("chilNum");
                childnum=childnum1.intValue();
                if(childnum!=0){
//第一行表頭包含第二行表頭的情況,因為第一行表頭和它內部的第二行表頭的第一個值是上下行同列的關系,所以這里couunt2沒有++;
                    HSSFCell cell1 = row2.createCell(count2); 
                    cell1.setCellStyle(cellStyle); 
                    cell1.setCellValue(new HSSFRichTextString((String) headList.get(i).get("dicInfoName"))); 
                    int counttemp=count2;
                    for(int j=0;j<childnum;j++)
                    {
//每次給第二行表頭添加信息以及沒有子項的第一行表頭添加信息的時候指針要向后移
                        row3Cell = row3.createCell(count2++); 
                        row3Cell.setCellStyle(cellStyle); 
                        row3Cell.setCellValue(new HSSFRichTextString((String) headerList.get(childstartnum++).get("dicInfoName"))); 
                    }
//記錄帶子項的第一行表頭的起始位置和結束位置,以便之后合并單元格
                    mergeList.add(counttemp);
                    mergeList.add(count2-1);

                }else{
                    
                    HSSFCell cell1 = row2.createCell(count2++); 
                    cell1.setCellStyle(cellStyle); 
                    cell1.setCellValue(new HSSFRichTextString((String) headList.get(i).get("dicInfoName"))); 
                }
            }
            // 合并單元格 
            // 合并第三行到第四行的第一列 
                sheet.addMergedRegion(new Region(2, (short) 0, 3, (short) 0)); 
            // 合并第三行到第四行的第二列,三列
            sheet.addMergedRegion(new Region(2, (short) 1, 3, (short) 1)); 

            sheet.addMergedRegion(new Region(2, (short) 2, 3, (short) 2)); 
            
            for(int i=0;i<mergeList.size();i++)
            {
                System.out.println(mergeList.get(i).intValue());
            }
//給第一行表頭設置合并單元格
        for(int i=0;i<mergeList.size();i=i+2)
{

  sheet.addMergedRegion(new Region(2, (short)( mergeList.get(i).intValue()), 2, (short)(mergeList.get(i+1).intValue()))); 

}

//之后的代碼就是用同樣的方式拼裝ExcelUtils的標簽
              HSSFRow row4 = sheet.createRow(4); 
              HSSFRow row5 = sheet.createRow(5); 
              HSSFRow row6 = sheet.createRow(6); 
              HSSFRow row7 = sheet.createRow(7); 
              HSSFCell cell4 = row4.createCell(0); 
              cell4.setCellStyle(cellStyle); 
              cell4.setCellValue(new HSSFRichTextString("合計")); 
             // for(int i=0;i<dicList.size();i++)
             // {
                 // HSSFCell cellsum = row4.createCell(i+1); 
    
             // }
              HSSFCell cell41 = row5.createCell(0); 
              cell41.setCellStyle(cellStyle); 
              cell41.setCellValue(new HSSFRichTextString("#foreach obj in ${list}"));
                  
              HSSFCell cell51 = row6.createCell(0); 
              cell51.setCellStyle(cellStyle); 
              cell51.setCellValue(new HSSFRichTextString("${obj.orgName}"));
                for(int i=0;i<dicList.size();i++)
                {
                    cell51 = row6.createCell(i+1); 
                    cell51.setCellStyle(cellStyle); 
                    cell51.setCellValue(new HSSFRichTextString("${obj."+(String) dicList.get(i).get("dicInfoCode")+"}"));
                    System.out.println((String) dicList.get(i).get("dicInfoCode"));
                }
                //求和
                  HSSFCell cellsum = row4.createCell(1); 
                  cellsum.setCellStyle(cellStyle);  
                  String letter = String.valueOf((char) (1+ 65));
                  cellsum.setCellValue("#formula SUMPRODUCT(--" + letter + "${objStartRowNo}:" + letter + "${objEndRowNo})");
               HSSFCell cell61 = row7.createCell(0); 
                cell61.setCellStyle(cellStyle); 
                cell61.setCellValue(new HSSFRichTextString("#end")); 
                
                exportExcel.outputExcel(ServletActionContext.getServletContext().getRealPath("template")+"\\trstatisticsNum.xls"); 
                System.out.println(ServletActionContext.getServletContext().getRealPath("template")+"\\trstatisticsNum.xls");
                return true;
    }

=======================================================
百科中的示例附上作為下次使用的備忘。
創建Excel 文檔

示例1將演示如何利用Jakarta POI API 創建Excel 文檔。

示例1程序如下:

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFCell;

import java .io.FileOutputStream;

public class CreateXL {

/** Excel 文件要存放的位置,假定在D盤下*/

public static String outputFile="D:\test.xls";

public static void main(String argv[]){

try{

// 創建新的Excel 工作簿

HSSFWorkbook workbook = new HSSFWorkbook();

// 在Excel工作簿中建一工作表,其名為缺省值

// 如要新建一名為"效益指標"的工作表,其語句為:

// HSSFSheet sheet = workbook.createSheet("效益指標");

HSSFSheet sheet = workbook.createSheet();

// 在索引0的位置創建行(最頂端的行)

HSSFRow row = sheet.createRow((short)0);

//在索引0的位置創建單元格(左上端)

HSSFCell cell = row.createCell((short) 0);

// 定義單元格為字符串類型

cell.setCellType(HSSFCell.CELL_TYPE_STRING);

// 在單元格中輸入一些內容

cell.setCellValue("增加值");

// 新建一輸出文件流

FileOutputStream fOut = new FileOutputStream(outputFile);

// 把相應的Excel 工作簿存盤

workbook.write(fOut);

fOut.flush();

// 操作結束,關閉文件

fOut.close();

System.out.println("文件生成...");

}catch(Exception e) {

System.out.println("已運行 xlCreate() : " + e );

}

}

}

讀取Excel文檔中的數據

示例2將演示如何讀取Excel文檔中的數據。假定在D盤JTest目錄下有一個文件名為test1.xls的Excel文件。

示例2程序如下:

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFCell;

import java .io.FileInputStream;

public class ReadXL {

/** Excel文件的存放位置。注意是正斜線*/

public static String fileToBeRead="D:\test1.xls";

public static void main(String argv[]){

try{

// 創建對Excel工作簿文件的引用

HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileToBeRead));

// 創建對工作表的引用。

// 本例是按名引用(讓我們假定那張表有著缺省名"Sheet1")

HSSFSheet sheet = workbook.getSheet("Sheet1");

// 也可用getSheetAt(int index)按索引引用,

// 在Excel文檔中,第一張工作表的缺省索引是0,

// 其語句為:HSSFSheet sheet = workbook.getSheetAt(0);

// 讀取左上端單元

HSSFRow row = sheet.getRow(0);

HSSFCell cell = row.getCell((short)0);

// 輸出單元內容,cell.getStringCellValue()就是取所在單元的值

System.out.println("左上端單元是: " + cell.getStringCellValue());

}catch(Exception e) {

System.out.println("已運行xlRead() : " + e );

}

}

}

設置單元格格式

在這里,我們將只介紹一些和格式設置有關的語句,我們假定workbook就是對一個工作簿的引用。在Java中,第一步要做的就是創建和設置 字體和單元格的格式,然后再應用這些格式:

1、創建字體,設置其為紅色、粗體:

HSSFFont font = workbook.createFont();

font.setColor(HSSFFont.COLOR_RED);

font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

2、創建格式

HSSFCellStyle cellStyle= workbook.createCellStyle();

cellStyle.setFont(font);

3、應用格式

HSSFCell cell = row.createCell((short) 0);

cell.setCellStyle(cellStyle);

cell.setCellType(HSSFCell.CELL_TYPE_STRING);

cell.setCellValue("標題 ");

處理WORD文檔

import java .io.*;

import org.apache.poi.hwpf.extractor.WordExtractor;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;

import org.apache.poi.hssf.usermodel.HSSFSheet;

import org.apache.poi.hssf.usermodel.HSSFRow;

import org.apache.poi.hssf.usermodel.HSSFCell;

public class TestPoi {

public TestPoi() {

}

public static void main(String args[]) throws Exception

{

FileInputStream in = new FileInputStream ("D:\a.doc");

WordExtractor extractor = new WordExtractor();

String str = extractor.extractText(in);

//System.out.println("the result length is"+str.length());

System.out.println(str);

}

}

搜集鏈接 方便以后查閱
POI操作Excel常用方法總結

自己封裝的poi操作excel工具類

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容