POI對EXCEL的操作【重點:如何設置CELL格式爲文本格式】


轉載至:http://javacrazyer.iteye.com/blog/894758


實際開發過程中通常用到的就是從數據庫導出EXCEL表格了,JXL可以這樣做,其實POI也可以(關於JXL與POI的異同可訪問我之前總結的文章),之前寫過POI對七種文檔(當然也包括EXCEL)的內容讀取操作的文章,這次要寫的就非常重要了,就是開發中經常會用到的POI讀取數據庫導出EXCEL的操作,所謂導出EXCEL也就是生成帶數據內容的新的EXCEL文件

目前的POI版本是3.7

下載地址:http://poi.apache.org/download.html#POI-3.7

 必須包只有一個:poi-3.7-20101029.jar


 整理思路:1)數據庫中的字段對應EXCEL的最頂層一行各個CELL名稱[也就是上面圖片中序號版本...的]

                2)將每個數據一次插入到對應名稱CELL的對應記錄位置

                3)爲了方便操作,頂層的cell各個名稱可以抽取出來成爲一個單獨類

具體代碼

   第一部分:單獨的EXCEL表頭類

 public class Cachetable {

Java代碼  收藏代碼
  1. // Fields  
  2. private int recnum;  
  3. private String devIp;  
  4. private String srcaddr;  
  5. private String dstaddr;  
  6. private String nexthop;  
  7. private String input;  
  8. private String output;  
  9. private String dpkts;  
  10. private String doctets;  
  11. private String sstart;  
  12.   
  13. private String dstport;  
  14. private String prot;  
  15. private String tos;  
  16. private String srcas;  
  17. private String dstas;  
  18. private String pduversion;  
  19.   
  20.   
  21. /** default constructor */  
  22. public Cachetable() {  
  23. }  
  24.   
  25.   
  26. /** full constructor */  
  27. public Cachetable(int recnum, String devIp, String srcaddr, String dstaddr, String nexthop, String input, String output, String dpkts, String doctets, String sstart, String dstport, String prot, String tos, String srcas, String dstas,String pduversion) {  
  28.     this.recnum = recnum;  
  29.     this.devIp = devIp;  
  30.     this.srcaddr = srcaddr;  
  31.     this.dstaddr = dstaddr;  
  32.     this.nexthop = nexthop;  
  33.     this.input = input;  
  34.     this.output = output;  
  35.     this.dpkts = dpkts;  
  36.     this.doctets = doctets;  
  37.     this.sstart = sstart;  
  38.     this.dstport = dstport;  
  39.     this.prot = prot;  
  40.     this.tos = tos;  
  41.     this.srcas = srcas;  
  42.     this.dstas = dstas;  
  43.     this.pduversion = pduversion;  
  44.   
  45. }  
  46.   
  47.   
  48. public int getRecnum() {  
  49.     return this.recnum;  
  50. }  
  51.   
  52. public void setRecnum(int recnum) {  
  53.     this.recnum= recnum;  
  54. }  
  55.   
  56. public String getDevIp() {  
  57.     return this.devIp;  
  58. }  
  59.   
  60. public void setDevIp(String devIp) {  
  61.     this.devIp = devIp;  
  62. }  
  63.   
  64.   
  65. public String getSrcaddr() {  
  66.     return this.srcaddr;  
  67. }  
  68.   
  69. public void setSrcaddr(String srcaddr) {  
  70.     this.srcaddr = srcaddr;  
  71. }  
  72.   
  73.   
  74. public String getDstaddr() {  
  75.     return this.dstaddr;  
  76. }  
  77.   
  78. public void setDstaddr(String dstaddr) {  
  79.     this.dstaddr = dstaddr;  
  80. }  
  81.   
  82.   
  83. public String getNexthop() {  
  84.     return this.nexthop;  
  85. }  
  86.   
  87. public void setNexthop(String nexthop) {  
  88.     this.nexthop = nexthop;  
  89. }  
  90.   
  91.   
  92. public String getInput() {  
  93.     return this.input;  
  94. }  
  95.   
  96. public void setInput(String input) {  
  97.     this.input = input;  
  98. }  
  99.   
  100.   
  101. public String getOutput() {  
  102.     return this.output;  
  103. }  
  104.   
  105. public void setOutput(String output) {  
  106.     this.output = output;  
  107. }  
  108.   
  109. public String getDpkts() {  
  110.     return this.dpkts;  
  111. }  
  112.   
  113. public void setDpkts(String dpkts) {  
  114.     this.dpkts = dpkts;  
  115. }  
  116.   
  117.   
  118. public String getDoctets() {  
  119.     return this.doctets;  
  120. }  
  121.   
  122. public void setDoctets(String doctets) {  
  123.     this.doctets = doctets;  
  124. }  
  125.   
  126.   
  127. public String getSstart() {  
  128.     return this.sstart;  
  129. }  
  130.   
  131. public void setSstart(String sstart) {  
  132.     this.sstart = sstart;  
  133. }  
  134.   
  135. public String getDstport() {  
  136.     return this.dstport;  
  137. }  
  138.   
  139. public void setDstport(String dstport) {  
  140.     this.dstport = dstport;  
  141. }  
  142.   
  143. public String getProt() {  
  144.     return this.prot;  
  145. }  
  146.   
  147. public void setProt(String prot) {  
  148.     this.prot = prot;  
  149. }  
  150.   
  151.   
  152. public String getTos() {  
  153.     return this.tos;  
  154. }  
  155.   
  156. public void setTos(String tos) {  
  157.     this.tos = tos;  
  158. }  
  159.   
  160. public String getSrcas() {  
  161.     return this.srcas;  
  162. }  
  163.   
  164. public void setSrcas(String srcas) {  
  165.     this.srcas = srcas;  
  166. }  
  167.   
  168.   
  169. public String getDstas() {  
  170.     return this.dstas;  
  171. }  
  172.   
  173. public void setDstas(String dstas) {  
  174.     this.dstas = dstas;  
  175. }  
  176.   
  177. public String getPduversion() {  
  178.     return this.pduversion;  
  179. }  
  180.   
  181. public void setPduversion(String pduversion) {  
  182.     this.pduversion = pduversion;  
  183. }  

 

第二部分:具體的POI操作生成EXCEL類

【我這裏只是個示例,沒連數據庫,直接運行即可,如果想連,稍微變動一點即可】

 

Java代碼  收藏代碼
  1. package com.zkyy.flow.excel;  
  2.   
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.OutputStream;  
  6. import java.sql.SQLException;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9.   
  10. import javax.swing.JOptionPane;  
  11.   
  12. import org.apache.poi.hssf.usermodel.HSSFCell;  
  13. import org.apache.poi.hssf.usermodel.HSSFCellStyle;  
  14. import org.apache.poi.hssf.usermodel.HSSFDataFormat;  
  15. import org.apache.poi.hssf.usermodel.HSSFFooter;  
  16. import org.apache.poi.hssf.usermodel.HSSFHeader;  
  17. import org.apache.poi.hssf.usermodel.HSSFRow;  
  18. import org.apache.poi.hssf.usermodel.HSSFSheet;  
  19. import org.apache.poi.hssf.usermodel.HSSFWorkbook;  
  20.   
  21. import com.kk.flow.webapp.util.Cachetable;  
  22.     
  23. public class ExcelOut {     
  24.     
  25.     //表頭     
  26.     public static final String[] tableHeader = {"序號","版本","接收時刻","設備","入接口","出接口",     
  27.         "源IP","目的IP","下一跳","協議","端口","對端端口","TOS","源AS","目的AS","TCP_FLAG","pad1","pad2"};     
  28.     //創建工作本   TOS  
  29.     public static HSSFWorkbook demoWorkBook = new HSSFWorkbook();     
  30.     //創建表     
  31.     public static HSSFSheet demoSheet = demoWorkBook.createSheet("The World's 500 Enterprises");     
  32.     //表頭的單元格個數目     
  33.     public static final short cellNumber = (short)tableHeader.length;     
  34.     //數據庫表的列數     
  35.     public static final int columNumber = 1;     
  36.     /**   
  37.      * 創建表頭   
  38.      * @return   
  39.      */    
  40.     public static void createTableHeader()     
  41.     {     
  42.         HSSFHeader header = demoSheet.getHeader();     
  43.         header.setCenter("世界五百強企業名次表");     
  44.         HSSFRow headerRow = demoSheet.createRow((short0);     
  45.         for(int i = 0;i < cellNumber;i++)     
  46.         {     
  47.             HSSFCell headerCell = headerRow.createCell((short) i);    
  48.             headerCell.setCellType(HSSFCell.CELL_TYPE_STRING);  
  49.             headerCell.setCellValue(tableHeader[i]);     
  50.         }     
  51.     }     
  52.     /**   
  53.      * 創建行   
  54.      * @param cells   
  55.      * @param rowIndex   
  56.      */    
  57.     public static void createTableRow(List<String> cells,short rowIndex)     
  58.     {     
  59.         //創建第rowIndex行     
  60.         HSSFRow row = demoSheet.createRow((short) rowIndex);     
  61.         for(int i = 0;i < cells.size();i++)     
  62.         {     
  63.             //創建第i個單元格     
  64.             HSSFCell cell = row.createCell(i);   
  65.             if(cell.getCellType()!=1){  
  66.                 cell.setCellType(HSSFCell.CELL_TYPE_STRING);    
  67.             }  
  68.               
  69.             //新增的四句話,設置CELL格式爲文本格式  
  70.             HSSFCellStyle cellStyle2 = demoWorkBook.createCellStyle();  
  71.             HSSFDataFormat format = demoWorkBook.createDataFormat();  
  72.             cellStyle2.setDataFormat(format.getFormat("@"));  
  73.             cell.setCellStyle(cellStyle2);  
  74.           
  75.             cell.setCellValue(cells.get(i));   
  76.             cell.setCellType(HSSFCell.CELL_TYPE_STRING);  
  77.         }    
  78.     }     
  79.       
  80.     /** 
  81.      * USE:用於獲取Cachetable的數據。。。假數據。到時候:你連接數據庫的到List<Cachetable>的數據就行了。 共生成 
  82.      * 100條數據.相當於100行 
  83.      *  
  84.      * @return 
  85.      */  
  86.     public List<Cachetable> getDate() {  
  87.         List<Cachetable> cacheList = new ArrayList<Cachetable>();  
  88.         for (int j = 0; j < 300; j++) {  
  89.             Cachetable tb = new Cachetable();  
  90.             tb.setRecnum(j + 1);  
  91.             tb.setDevIp("JavaCrazyer");  
  92.             tb.setSrcaddr("北京");  
  93.             tb.setDstaddr("xxx");  
  94.             tb.setNexthop("yy");  
  95.             tb.setInput("123");  
  96.             tb.setOutput("127.0.0.1");  
  97.             tb.setDpkts("what are you doing?");  
  98.             tb.setDoctets("who are you?");  
  99.             tb.setSstart("Oh  sure!");  
  100.             tb.setProt("One");  
  101.             tb.setTos("two");  
  102.             tb.setSrcas("three");  
  103.             tb.setDstas("four");  
  104.             tb.setPduversion("不知道");  
  105.             cacheList.add(tb);  
  106.         }  
  107.         return cacheList;  
  108.     }  
  109.          
  110.     /**   
  111.      * 創建整個Excel表   
  112.      * @throws SQLException    
  113.      *   
  114.      */    
  115.     public  void createExcelSheet() throws SQLException{  
  116.         createTableHeader();     
  117.         int rowIndex=1;  
  118.           
  119.         List<Cachetable> list=getDate();  
  120.           
  121.         for(int j=0;j<list.size();j++){  
  122.             List<String> listRead=new ArrayList<String>();  
  123.         for(int i=1;i<=columNumber;i++){  
  124.           listRead.add(list.get(i).getDevIp());  
  125.           listRead.add(list.get(i).getSrcaddr());  
  126.           listRead.add(list.get(i).getDstaddr());  
  127.           listRead.add(list.get(i).getNexthop());  
  128.           listRead.add(list.get(i).getInput());  
  129.           listRead.add(list.get(i).getOutput());  
  130.           listRead.add(list.get(i).getDpkts());  
  131.           listRead.add(list.get(i).getDoctets());  
  132.           listRead.add(list.get(i).getSstart());  
  133.           listRead.add(list.get(i).getProt());  
  134.           listRead.add(list.get(i).getTos());  
  135.           listRead.add(list.get(i).getSrcas());  
  136.           listRead.add(list.get(i).getDstas());  
  137.           listRead.add(list.get(i).getPduversion());  
  138.           listRead.add(rowIndex+"");  
  139.         }  
  140.          createTableRow(listRead,(short)rowIndex);     
  141.          rowIndex++;     
  142.         }  
  143.     }  
  144.      
  145.     /**   
  146.      * 導出表格   
  147.      * @param sheet   
  148.      * @param os   
  149.      * @throws IOException   
  150.      */    
  151.     public void exportExcel(HSSFSheet sheet,OutputStream os) throws IOException     
  152.     {     
  153.         sheet.setGridsPrinted(true);     
  154.         HSSFFooter footer = sheet.getFooter();     
  155.         footer.setRight("Page " + HSSFFooter.page() + " of " +     
  156.         HSSFFooter.numPages());     
  157.         demoWorkBook.write(os);     
  158.     }     
  159.          
  160.     public static void main(String[] args) {     
  161.         String fileName = "f:\\世界五百強企業名次表.xls";     
  162.          FileOutputStream fos = null;     
  163.             try {  
  164.                 ExcelOut pd = new ExcelOut();  
  165.                 pd.createExcelSheet();  
  166.                 fos = new FileOutputStream(fileName);    
  167.                 pd.exportExcel(demoSheet,fos);  
  168.                 JOptionPane.showMessageDialog(null"表格已成功導出到 : "+fileName);  
  169.             } catch (Exception e) {  
  170.                 JOptionPane.showMessageDialog(null"表格導出出錯,錯誤信息 :"+e+"\n錯誤原因可能是表格已經打開。");  
  171.                 e.printStackTrace();  
  172.             } finally {  
  173.                 try {  
  174.                     fos.close();     
  175.                 } catch (Exception e) {     
  176.                     e.printStackTrace();     
  177.                 }     
  178.             }     
  179.     }     
  180. }    

 

 

說明:

   1)有關數據庫連接,如果操作到數據庫的話,在遍歷數據庫時用getDate這個方法遍歷就可以啦,那麼插入的數據就不是定值了,而是數據庫中的值哦,具體操作數據庫的步驟,我不用說,你懂得

   2)有關涉及更改EXCEL的CELL格式爲字符串,如圖一般情況下大家導出的EXCEL表格CELL格式通常是常規的



   這個問題,估計已經不止一兩個朋友在網上問過,我至今沒有看到一個滿意的答案,通常大家都是想到既然是設置CELL格式肯定是通過cell.setCellType(HSSFCell.CELL_TYPE_STRING)然後插入數據再導出,誠然這種想法是對的,實際上不能起到任何作用,因爲這個方法就是EXCEL默認的格式,寫不寫都一樣(好多同學都不知道吧),再寫出我的解決方案之前請大家參考下一段文字

 

第一段:Excel的單元格格式 
圖中的數據有數值、貨幣、時間、日期、文本等格式。這些數據格式在POI中的HSSFDataFormat類裏都有相應的定義。 
HSSFDataFormat是HSSF子項目裏面定義的一個類。類HSSFDataFormat允許用戶新建數據格式類型。HSSFDataFormat類包含靜態方法static java.lang.String getBuiltinFormat(short index),它可以根據編號返回內置數據類型。另外static short getBuiltinFormat(java.lang.String format)方法則可以根據數據類型返回其編號,static java.util.List getBuiltinFormats()可以返回整個內置的數據格式列表。 
在HSSFDataFormat裏一共定義了49種內置的數據格式,如下面所示。 

 HSSFDataFormat的數據格式 

內置數據類型 
編號 

"General" 


"0" 


"0.00" 


"#,##0" 


"#,##0.00" 


"($#,##0_);($#,##0)" 


"($#,##0_);[Red]($#,##0)" 


"($#,##0.00);($#,##0.00)" 


"($#,##0.00_);[Red]($#,##0.00)" 


"0%" 


"0.00%" 
0xa 

"0.00E+00" 
0xb 

"# ?/?" 
0xc 

"# ??/??" 
0xd 

"m/d/yy" 
0xe 

"d-mmm-yy" 
0xf 

"d-mmm" 
0x10 

"mmm-yy" 
0x11 

"h:mm AM/PM" 
0x12 

"h:mm:ss AM/PM" 
0x13 

"h:mm" 
0x14 

"h:mm:ss" 
0x15 

"m/d/yy h:mm" 
0x16 

保留爲過國際化用 
0x17 - 0x24 

"(#,##0_);(#,##0)" 
0x25 

"(#,##0_);[Red](#,##0)" 
0x26 

"(#,##0.00_);(#,##0.00)" 
0x27 

"(#,##0.00_);[Red](#,##0.00)" 
0x28 

"_($*#,##0_);_($*(#,##0);_($* \"-\"_);_(@_)" 
0x29 

"_(*#,##0.00_);_(*(#,##0.00);_(*\"-\"??_);_(@_)" 
0x2a 

"_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)" 
0x2b 

"_($*#,##0.00_);_($*(#,##0.00);_($*\"-\"??_);_(@_)" 
0x2c 

"mm:ss" 
0x2d 

"[h]:mm:ss" 
0x2e 

"mm:ss.0" 
0x2f 

"##0.0E+0" 
0x30 

"@" - This is text format 
0x31 

在上面表中,字符串類型所對應的是數據格式爲"@"(最後一行),也就是HSSFDataFormat中定義的值爲0x31(49)的那行。Date類型的值的範圍是0xe-0x11,本例子中的Date格式爲""m/d/yy"",在HSSFDataFormat定義的值爲0xe(14)。  

 

 

 

第二段:POI中Excel文件Cell的類型 
在讀取每一個Cell的值的時候,通過getCellType方法獲得當前Cell的類型,在Excel中Cell有6種類型,如下面所示。 

Cell的類型 

CellType 
說明 

CELL_TYPE_BLANK 
空值 

CELL_TYPE_BOOLEAN 
布爾型 

CELL_TYPE_ERROR 
錯誤 

CELL_TYPE_FORMULA 
公式型 

CELL_TYPE_STRING 
字符串型 

CELL_TYPE_NUMERIC 
數值型 

一般都採用CELL_TYPE_STRING和CELL_TYPE_NUMERIC類型,因爲在Excel文件中只有字符串和數字。如果Cell的Type爲CELL_TYPE_NUMERIC時,還需要進一步判斷該Cell的數據格式,因爲它有可能是Date類型,在Excel中的Date類型也是以Double類型的數字存儲的。Excel中的Date表示當前時間與1900年1月1日相隔的天數,所以需要調用HSSFDateUtil的isCellDateFormatted方法,判斷該Cell的數據格式是否是Excel Date類型。如果是,則調用getDateCellValue方法,返回一個Java類型的Date。

 

 

好了讀完上面兩段文字我想大家關於CELL類型和格式應該清楚了,更應該清楚的是到底怎麼才能將‘設置單元格格式’改成文本然後再導出

解決方案:就是上面代碼中的ExcelOut類裏面createTableRow方法中的一段代碼

 

            HSSFCellStyle cellStyle2 = demoWorkBook.createCellStyle();

            HSSFDataFormat format = demoWorkBook.createDataFormat();

            cellStyle2.setDataFormat(format.getFormat("@"));

            cell.setCellStyle(cellStyle2);

看最終導出效果圖吧,點擊任何一個CELL右鍵設置單元格格式


 

 

 3)  JOptionPane.showMessageDialog(null, "表格已成功導出到 : "+fileName);這句話有點意思



 看到沒這就是javax.swing.JOptionPane類的有關消息輸出的好處,很方便使用

 

 

PS:更多的關於POI設置EXCEL單元格格式爲數字、百分比、貨幣、日期等等格式的,請看我接下來要寫的文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章