国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
用POI HSSF處理EXCEL表格

筆者據(jù)使用經(jīng)驗以為:Apache的開源項目。當然POI HSSF也有缺點:不能直接支持EXCEL圖表,API文檔粗糙簡略,有些類和方法需要引用Apache項目中的其它一些包,包與包之間依賴關系比較復雜等等。

本文內(nèi)容不在于提供一個POI HSSF 的完整使用指南(上面那個Apache主頁上的Quick Guide已經(jīng)非常詳細),而是列出一些筆者在項目開發(fā)過程中找到的一些技巧、經(jīng)驗。

下圖是定義的模板PoiTest.xls:

 

通過POI生成的最終結(jié)果:

(單元格中的數(shù)據(jù)發(fā)生變化時,圖表中的柱狀、折線也會跟著變化)

 

處理圖表

目前POI版本為2.5.1,org.apache.poi.hssf.usermodel包里有一個HSSFChart類,里面只有一個空方法createBarChart(),表明POI還不直接支持EXCEL圖表。

替代方法還是有的:因為EXCEL圖表的源數(shù)據(jù)引用自EXCEL單元格。我們可以先新建一個EXCEL工作薄,作為模板,在里面創(chuàng)建圖表,指定它引用工作表中的一些特定單元格。然后我們用POI來讀取這個工作薄,把數(shù)據(jù)寫入到那些特定單元格。

首先要在模板里創(chuàng)建可以動態(tài)引用單元格的“名稱”,利用“名稱”來創(chuàng)建圖表中的“系列”。

一、打開模板PoiTest.xls,點擊[插入]>[名稱]>[定義],創(chuàng)建四個“名稱”sx,s1y,s2y,s3y:

sx=OFFSET(Sheet1!$A$17,0,2,1,COUNTA(Sheet1!$17:$17)-4)

s1y=OFFSET(Sheet1!$A$18,0,2,1,COUNTA(Sheet1!$18:$18)-4)

s2y=OFFSET(Sheet1!$A$19,0,2,1,COUNTA(Sheet1!$19:$19)-3)

s3y=OFFSET(Sheet1!$A$20,0,2,1,COUNTA(Sheet1!$20:$20)-3)

 

這里用到了兩個EXCEL函數(shù),OFFSET()和COUNTA()函數(shù)。

其中COUNTA()可以返回一行或一列的單元格總數(shù):

比如COUNTA(Sheet1!$A:$A),計算工作表Sheet1的A列的單元格數(shù)目。

又比如COUNTA(Sheet1!$17:$17),計算的是Sheet1的第17行的單元格數(shù)目。

當我們沒有在單元格里鍵入數(shù)據(jù)時,該單元格是不會被COUNTA()計算的。

OFFSET()函數(shù)用來引用一系列連續(xù)的單元格,它共有五個參數(shù):

參數(shù)一,作為位置參照的單元格。

參數(shù)二,行的起始偏移量(以參數(shù)一為參照)。

參數(shù)三,列的起始偏移量(以參數(shù)一為參照)。

參數(shù)四,跨行數(shù)。

參數(shù)五,跨列數(shù)。

比如:

OFFSET(Sheet1!$A:$1,1,2,3,4),表示引用范圍為:C2:F4。

二、在模板中創(chuàng)建圖表,在圖表上點右鍵,選擇[源數(shù)據(jù)]>[系列],如圖建立三個系列:

 

點[添加]創(chuàng)建新的系列:

[名稱]表示系列名,可以直接輸入字串,也可以引用EXCEL單元格。

在[值]中輸入我們在上一步中創(chuàng)建的“名稱”,格式為:模板名.xls!名稱。

在[分類(X)軸標志(T)]中輸入我們在上一步中創(chuàng)建的“名稱”sx,格式為:模板名.xls!名稱。它表示圖表區(qū)域的X軸將要顯示的內(nèi)容。

三、用POI把數(shù)據(jù)寫入到相應的單元格中,圖表將會自動顯示對應的信息。

注意:

上面這種方法適用數(shù)據(jù)集合行數(shù)固定而列數(shù)動態(tài)變化的情況。

對于行數(shù)也動態(tài)變化的情況,只能先在模板里預設盡可能多的“名稱”和“系列”。

對于行數(shù)和列數(shù)都固定的情形,沒必要這么復雜,只要在圖表的[源數(shù)據(jù)]里設置[數(shù)據(jù)區(qū)域],使之引用EXCEL模板中的一定范圍,如下圖:

 

設置單元格樣式

 

HSSFCellStyle類代表一種單元格樣式??梢酝ㄟ^這個類來設置單元格的邊框樣式、背景顏色、字體、水平和垂直對齊方式等等。

HSSFCellStyle titleStyle = workbook.createCellStyle();
  titleStyle.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);
  titleStyle.setBorderLeft((short)1);
  titleStyle.setBorderRight((short)1);
  titleStyle.setBorderTop(HSSFCellStyle.BORDER_DOUBLE);
  titleStyle.setFillForegroundColor(HSSFColor.LIGHT_ORANGE.index);
  titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);


注意:如果我們定義了一種樣式,把它賦給一些單元格。然后基于新的需要,更改該樣式中的某個屬性,再賦給另一些單元格。那么之前單元格樣式的該屬性也會被同時更改。

比如我們定義了樣式,設置單元格背景色為紅色:

HSSFCellStyle cellStyle = workbook.createCellStyle();

cellStyle.setFillForegroundColor(HSSFColor.RED.index);
cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
 


然后把它賦給一個單元格:

HSSFCell cell1 = row.createCell((short)1);

cell1.setCellStyle(cellStyle);
 


然后更改樣式中的背景色屬性為藍色:

cellStyle.setFillForegroundColor(HSSFColor.BLUE.index);


然后賦給另一個單元格:

HSSFCell cell2 = row.createCell((short)2);

cell2.setCellStyle(cellStyle);
 


想當然,我們預計在最終結(jié)果中cell1的背景色為紅色,cell2的背景色為藍色。但是結(jié)果是:兩個單元格的背景色都變成了藍色。

遇到這種情況,要預先定義兩種不同的單元格樣式。

當一個EXCEL文件同時需要很多大同小異的單元格樣式時,這樣一一定義很麻煩。POI HSSF提供了一個HSSFCellUtil類(在org.apache.poi.hssf.usermodel.contrib包),里面有幾個方法可以繞過HSSFCellStyle直接設定單元格的樣式,但這幾個方法會拋出NestableException異常,要處理這個異常,需要引用Apache的幾個Common包:

commons-beanutils.jar

commons-beanutils-bean-collections.jar

commons-beanutils-core.jar

commons-lang.jar

commons-logging-api.jar

合并單元格

HSSFSheet.addMergedRegion(new Region())方法可以合并單元格,Region()中的一個構(gòu)造函數(shù)含有四個參數(shù),分別代表起始行、起始列、結(jié)束行、結(jié)束列:

sheet.addMergedRegion(new Region(initRow, (short)(initCol-2), initRow + lists.size() - 1, (short)(initCol-2)));


處理公式

 

HSSFCell.setCellFormula()方法用來在EXCEL單元格中寫入公式。

   cell = row.createCell((short)(dataFlag));
   cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
   cell.setCellFormula("SUM(" + getColLetter(initCol) + (listFlag+1) +
     ":" + getColLetter(dataFlag-1) + (listFlag+1) + ")");
   cell.setCellStyle(nameStyle);


處理鏈接

 

在POI中往單元格中寫鏈接,是用HYPERLINK函數(shù)搞定的。

HYPERLINK函數(shù)包含兩個參數(shù),第一個參數(shù)是指向的URL地址,第二個參數(shù)是顯示字串。

   cell = row.createCell((short)(dataFlag));
   cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
   cell.setCellFormula("HYPERLINK(\"   cell.setCellStyle(linkStyle);


為了使鏈接效果更好,我們可以給鏈接所在單元格定義一種樣式,使鏈接顯示為有下劃線的藍色字串:

  HSSFCellStyle linkStyle = workbook.createCellStyle();
  linkStyle.setBorderBottom((short)1);
  linkStyle.setBorderLeft((short)1);
  linkStyle.setBorderRight((short)1);
  linkStyle.setBorderTop((short)1);
  linkStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
  linkStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  HSSFFont font = workbook.createFont();
  font.setFontName(HSSFFont.FONT_ARIAL);
  font.setUnderline((byte)1);
  font.setColor(HSSFColor.BLUE.index);
  linkStyle.setFont(font);


中文處理:

要在通過POI生成的EXCEL中正常顯示中文,需要為單元格設置編碼:

cell.setEncoding(HSSFCell.ENCODING_UTF_16);
  cell.setCellValue("部門");


完整的PoiServlet類:

package org.eleaf.poi.servlets;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.hssf.util.Region;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;

public class PoiServlet extends HttpServlet {


 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=PoiTest.xls");
        ServletOutputStream sos = response.getOutputStream();
        HSSFWorkbook workbook = new HSSFWorkbook(getServletContext().getResourceAsStream("/PoiTest.xls"));
        HashMap map = getDatas();
        workbook = writeDatas(workbook, map);
        workbook.write(sos);
        sos.close();
 }
 /**
  * 將數(shù)據(jù)寫入到EXCEL中。
  * @param workbook
  * @param map 數(shù)據(jù)集合
  * @return
  */
 private HSSFWorkbook writeDatas(HSSFWorkbook workbook, HashMap map)
 {
  HSSFCellStyle titleStyle = workbook.createCellStyle();
  titleStyle.setBorderBottom(HSSFCellStyle.BORDER_DOUBLE);
  titleStyle.setBorderLeft((short)1);
  titleStyle.setBorderRight((short)1);
  titleStyle.setBorderTop(HSSFCellStyle.BORDER_DOUBLE);
  titleStyle.setFillForegroundColor(HSSFColor.LIGHT_ORANGE.index);
  titleStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  HSSFCellStyle dataStyle = workbook.createCellStyle();
  dataStyle.setBorderBottom((short)1);
  dataStyle.setBorderLeft((short)1);
  dataStyle.setBorderRight((short)1);
  dataStyle.setBorderTop((short)1);
  dataStyle.setFillForegroundColor(HSSFColor.LIGHT_GREEN.index);
  dataStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  dataStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  HSSFCellStyle nameStyle = workbook.createCellStyle();
  nameStyle.setBorderBottom((short)1);
  nameStyle.setBorderLeft((short)1);
  nameStyle.setBorderRight((short)1);
  nameStyle.setBorderTop((short)1);
  nameStyle.setFillForegroundColor(HSSFColor.LIGHT_CORNFLOWER_BLUE.index);
  nameStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  HSSFCellStyle linkStyle = workbook.createCellStyle();
  linkStyle.setBorderBottom((short)1);
  linkStyle.setBorderLeft((short)1);
  linkStyle.setBorderRight((short)1);
  linkStyle.setBorderTop((short)1);
  linkStyle.setFillForegroundColor(HSSFColor.SKY_BLUE.index);
  linkStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
  HSSFFont font = workbook.createFont();
  font.setFontName(HSSFFont.FONT_ARIAL);
  font.setUnderline((byte)1);
  font.setColor(HSSFColor.BLUE.index);
  linkStyle.setFont(font);
 
  HSSFSheet sheet = workbook.getSheetAt(0);
  final int initRow = 17;
  final int initCol = 2;
  HSSFRow rTitle = sheet.createRow(initRow - 1);
  List lists = (List) map.get("list");
  List titles = (List)map.get("title");
  int titleFlag = initCol;
  for (Iterator it = titles.iterator(); it.hasNext();)
  {
   String title = (String)it.next();
   HSSFCell cell = rTitle.createCell((short)titleFlag);
   cell.setCellStyle(titleStyle);
   cell.setEncoding(HSSFCell.ENCODING_UTF_16);
   cell.setCellType(HSSFCell.CELL_TYPE_STRING);
   cell.setCellValue(title);
   titleFlag++;
  }
 
  HSSFCell cell = rTitle.createCell((short)(titleFlag));
  cell.setCellStyle(titleStyle);
  cell.setCellType(HSSFCell.CELL_TYPE_STRING);
  cell.setEncoding(HSSFCell.ENCODING_UTF_16);
  cell.setCellValue("總計");
  titleFlag++;
 
  cell = rTitle.createCell((short)(titleFlag));
  cell.setCellStyle(titleStyle);
  cell.setCellType(HSSFCell.CELL_TYPE_STRING);
  cell.setEncoding(HSSFCell.ENCODING_UTF_16);
  cell.setCellValue("鏈接");
 
  cell = rTitle.createCell((short)(initCol-1));
  cell.setCellStyle(titleStyle);
  cell.setCellType(HSSFCell.CELL_TYPE_STRING);
  cell.setEncoding(HSSFCell.ENCODING_UTF_16);
  cell.setCellValue("職員");
 
  cell = rTitle.createCell((short)(initCol-2));
  cell.setCellStyle(titleStyle);
  cell.setCellType(HSSFCell.CELL_TYPE_STRING);
  cell.setEncoding(HSSFCell.ENCODING_UTF_16);
  cell.setCellValue("部門");
  int listFlag = initRow;
  for (Iterator it = lists.iterator(); it.hasNext();)
  {
   String name = (String)it.next();
   List datas = (List)map.get(name);
   HSSFRow row = sheet.createRow(listFlag);
  
   cell = row.createCell((short)(initCol-1));
   cell.setCellStyle(nameStyle);
   cell.setEncoding(HSSFCell.ENCODING_UTF_16);
   cell.setCellValue(name);
  
   cell = row.createCell((short)(initCol-2));
   cell.setEncoding(HSSFCell.ENCODING_UTF_16);
   cell.setCellStyle(dataStyle);
   int dataFlag = initCol;
   System.out.println("datas=" + datas);
   for (Iterator ite = datas.iterator(); ite.hasNext();)
   {
    int data = ((Integer)ite.next()).intValue();
    cell = row.createCell((short)dataFlag);
    cell.setCellStyle(dataStyle);
    cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
    cell.setCellValue(data);
    dataFlag++;
   }
   cell = row.createCell((short)(dataFlag));
   cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
   cell.setCellFormula("SUM(" + getColLetter(initCol) + (listFlag+1) +
     ":" + getColLetter(dataFlag-1) + (listFlag+1) + ")");
   cell.setCellStyle(nameStyle);
   dataFlag++;
  
   cell = row.createCell((short)(dataFlag));
   cell.setCellType(HSSFCell.CELL_TYPE_FORMULA);
   cell.setCellFormula("HYPERLINK(\"
   cell.setCellStyle(linkStyle);
   listFlag++;
  }
  sheet.getRow(initRow).getCell((short)(initCol-2)).setCellValue("武裝部");
 
  sheet.addMergedRegion(new Region(initRow, (short)(initCol-2), initRow + lists.size() - 1, (short)(initCol-2)));
  return workbook;
 }
 /**
  * 將列的索引換算成ABCD字母,這個方法要在插入公式時用到。
  * @param colIndex 列索引。
  * @return ABCD字母。
  */
 private String getColLetter(int colIndex)
 {
  String ch = "";
     if (colIndex  < 26)
         ch = "" + (char)((colIndex) + 65);
     else
        ch = "" + (char)((colIndex) / 26 + 65 - 1) + (char)((colIndex) % 26 + 65);
     return ch;
 }
 /**
  * 獲得數(shù)據(jù),組織為HashMap. 這里為了演示方便,簡單生成了一些數(shù)據(jù)。在實際應用中,是從
  * 數(shù)據(jù)庫中獲取數(shù)據(jù)的。
  * @return 組織后的數(shù)據(jù)
  */
 private HashMap getDatas()
 {
  HashMap map = new HashMap();
  List lists = new ArrayList();
  List title = new ArrayList();
  List a = new ArrayList();
  List b = new ArrayList();
  List c = new ArrayList();
  for (int i = 1; i <= 8; i++)
  {
   title.add(i + "月");
   a.add(new Integer((int)(Math.random() * 10)));
   b.add(new Integer((int)(Math.random() * 10)));
   c.add(new Integer((int)(Math.random() * 10)));
  }
  map.put("荊軻", a);lists.add("荊軻");
  map.put("專諸", b); lists.add("專諸");
  map.put("聶政", c); lists.add("聶政");
  map.put("list", lists);
  map.put("title", title);
  System.out.println("map=" + map);
  return map;
 }
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
  doGet(request, response);
 }
 
 

}

打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Java程序員從笨鳥到菜鳥之(一百零四)java操作office和pdf文件(二)利用POI實現(xiàn)數(shù)據(jù)導出excel報表
POI操作Excel常用方法總結(jié)
POI單元格顔色設定 | 程序人生
使用POI,結(jié)合JDBC編程技術(shù),我們就可以方便地將數(shù)據(jù)庫中的數(shù)據(jù)導出生成Excel報表
java操作Excel的神奇之路
Jakarta的POI項目操作Excel文件的方便的途徑
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服