java用org.apache.poi包操做excel

一.POI簡介html

Jakarta POI 是apache的子項目,目標是處理ole2對象。它提供了一組操縱Windows文檔的Java APIjava

目前比較成熟的是HSSF接口,處理MS Excel(97-2002)對象。它不象咱們僅僅是用csv生成的沒有格式的能夠由Excel轉換的東西,而是真正的Excel對象,你能夠控制一些屬性如sheet,cell等等。apache

二.HSSF概況數組

HSSF 是Horrible SpreadSheet Format的縮寫,也即「討厭的電子表格格式」。也許HSSF的名字有點滑稽,就本質而言它是一個很是嚴肅、正規的API。經過HSSF,你能夠用純Java代碼來讀取、寫入、修改Excel文件。安全

HSSF 爲讀取操做提供了兩類API:usermodel和eventusermodel,即「用戶模型」和「事件-用戶模型」。前者很好理解,後者比較抽象,但操做效率要高得多。ide

三.開始編碼函數

1 . 準備工做工具

要求:JDK 1.4+POI開發包測試

能夠到 http://www.apache.org/dyn/closer.cgi/jakarta/poi/ 最新的POI工具包字體

2 . EXCEL 結構

HSSFWorkbook excell 文檔對象介紹 HSSFSheet excell的表單 HSSFRow excell的行 HSSFCell excell的格子單元 HSSFFont excell字體 HSSFName 名稱 HSSFDataFormat 日期格式 在poi1.7中才有如下2項: HSSFHeader sheet頭 HSSFFooter sheet尾 和這個樣式 HSSFCellStyle cell樣式 輔助操做包括 HSSFDateUtil 日期 HSSFPrintSetup 打印 HSSFErrorConstants 錯誤信息表

3 .具體用法實例 (採用 usermodel )

如何讀Excel

讀取Excel文件時,首先生成一個POIFSFileSystem對象,由POIFSFileSystem對象構造一個HSSFWorkbook,該HSSFWorkbook對象就表明了Excel文檔。下面代碼讀取上面生成的Excel文件寫入的消息字串: try{ POIFSFileSystem fs=new POIFSFileSystem(new FileInputStream("d:/workbook.xls")); HSSFWorkbook wb = new HSSFWorkbook(fs); HSSFSheet sheet = wb.getSheetAt(0); HSSFRow row = sheet.getRow(0); HSSFCell cell = row.getCell((short) 0); String msg = cell.getStringCellValue(); System.out.println(msg); }catch(Exception e){ e.printStackTrace(); }

如何寫excel,

將excel的第一個表單第一行的第一個單元格的值寫成「a test」。

POIFSFileSystem fs =new POIFSFileSystem(new FileInputStream("workbook.xls"));

HSSFWorkbook wb = new HSSFWorkbook(fs);

HSSFSheet sheet = wb.getSheetAt(0);

HSSFRow row = sheet.getRow(0);

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

cell.setCellValue("a test");

// Write the output to a file

FileOutputStream fileOut = new FileOutputStream("workbook.xls");

wb.write(fileOut);

fileOut.close();

4 . 可參考文檔

POI 主頁: http://jakarta.apache.org/poi/

初學者如何快速上手使用POI HSSF

http://jakarta.apache.org/poi/hssf/quick-guide.html

裏面有不少例子代碼,能夠很方便上手。

四.使用心得

POI HSSF 的usermodel包把Excel文件映射成咱們熟悉的結構,諸如Workbook、Sheet、Row、Cell等,它把整個結構以一組對象的形式保存在內存之中,便於理解,操做方便,基本上可以知足咱們的要求,因此說這個一個不錯的選擇。

------------------------------- 前面已經講過利用POI讀寫Excel,下面是一個用POI向Excel中插入圖片的例子。

官方文檔: Images are part of the drawing support. To add an image just call createPicture() on the drawing patriarch. At the time of writing the following types are supported: PNG JPG DIB It is not currently possible to read existing images and it should be noted that any existing drawings may be erased once you add a image to a sheet.

// Create the drawing patriarch. This is the top level container for // all shapes. This will clear out any existing shapes for that sheet.

經過HSSFPatriarch類createPicture方法的在指定的wb中的sheet建立圖片,它接受二個參數,第一個是HSSFClientAnchor,設定圖片的大小。

package com.poi.hssf.test;

import java.io.FileOutputStream; import java.io.File; import java.io.ByteArrayOutputStream; import java.io.IOException;

import java.awt.image.BufferedImage; import javax.imageio.*;

import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFPatriarch; import org.apache.poi.hssf.usermodel.HSSFClientAnchor;;

public class TestPOI {

public static void main(String[] args) { 
        FileOutputStream fileOut = null; 
        BufferedImage bufferImg =null; 
        BufferedImage bufferImg1 = null; 
        try{ 
           
      //先把讀進來的圖片放到一個ByteArrayOutputStream中,以便產生ByteArray 
      ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); 
      ByteArrayOutputStream byteArrayOut1 = new ByteArrayOutputStream(); 
      bufferImg = ImageIO.read(new File("d:/PieChart.jpg")); 
      bufferImg1 = ImageIO.read(new File("d:/fruitBarChart.jpg")); 
      ImageIO.write(bufferImg,"jpg",byteArrayOut); 
      ImageIO.write(bufferImg1,"jpg",byteArrayOut1); 
     
    //建立一個工做薄 
   HSSFWorkbook wb = new HSSFWorkbook(); 
   HSSFSheet sheet1 = wb.createSheet("new sheet"); 
   //HSSFRow row = sheet1.createRow(2); 
   HSSFPatriarch patriarch = sheet1.createDrawingPatriarch(); 
   HSSFClientAnchor anchor = new HSSFClientAnchor(0,0,512,255,(short) 1,1,(short)10,20);
   HSSFClientAnchor anchor1 = new HSSFClientAnchor(0,0,512,255,(short) 2,30,(short)10,60); 
   anchor1.setAnchorType(2);
   //插入圖片
   patriarch.createPicture(anchor , wb.addPicture(byteArrayOut.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG)); 
   patriarch.createPicture(anchor1 , wb.addPicture(byteArrayOut1.toByteArray(),HSSFWorkbook.PICTURE_TYPE_JPEG)); 
   
       fileOut = new FileOutputStream("d:/workbook.xls"); 
       //寫入excel文件
       wb.write(fileOut); 
       fileOut.close(); 
   
        }catch(IOException io){ 
                io.printStackTrace(); 
                System.out.println("io erorr : "+ io.getMessage()); 
        } finally 
        { 
           if (fileOut != null) 
           {
                      
               try { 
                          fileOut.close(); 
                     } 
               catch (IOException e)
               { 
                        // TODO Auto-generated catch block 
                        e.printStackTrace(); 
                 } 
           } 
        }
}

} Java 生成 EXCEL POI文檔說明 POI版本:3.0.2-FINAL 下載地址: http://poi.apache.org/index.html 通常在項目中真正要實現這樣一個表格的時候,例如項目須要製做報表等等,一般的作法都是事先把格式一切的東西都手動製做好(這個作好了的文件在實際的項目裏咱們稱之爲「數據模板」,簡稱「模板」),而後在Java應用中適當的時機把這個文件讀進來修改,最後再另存到指定的位置或者傳遞給下一個處理者(例如以流的方式送給Servlet等等),這樣其實POI具體作的事情就是向模板裏寫業務的數據,仍是很方便快捷的。 一POI 讀取Excel 基本工做

  1. // 指定要讀取的文件,本例使用上面生成的helloworld.xls FileInputStream readFile = new FileInputStream("c:/ceshi.xls"); // 建立一個WorkBook,從指定的文件流中建立,即上面指定了的文件流 HSSFWorkbook wb = new HSSFWorkbook(readFile); // 獲取名稱爲「測試頁」的sheet // 注意,若是不能肯定具體的名稱,能夠用getSheetAt(int)方法取得Sheet //HSSFSheet st = wb.getSheet("測試頁"); HSSFSheet st = wb.getSheetAt(0); //建立樣式表,樣式表能夠設置單元格的一些屬性 好比背景色,鎖定狀態,行列寬高等 HSSFCellStyle normalStyle = wb.createCellStyle(); //如下列方式存儲當前單元格樣式 單元格對象.setCellStyle(normalStyle); 二設置模板與創建行和列
  2. 若是預先的模板有內容的話,在操做的時候則只須要讀去當前單元格的內容以及樣式,或者能夠從新定義。(若是沒有內容,又想以讀去的方式來獲取Excel的話,須要手動初始化模板,如給模板中須要用到的單元格設置邊框或者背景色等) 例如 HSSFRow row = st.getRow(0); //讀取第一行 HSSFCell cell = row.getCell((short)0); //讀取第一行第一個字段
  3. 若是模板中無內容的話,則須要在代碼中建立初始化行和列來達到目的 例如 HSSFRow row = st.createRow(0); //建立第一行 HSSFCell cell = row.createCell((short)0); //以第一行爲基礎建立第一列 三模板的只讀單元格功能與POI關係 在Excel中能夠設置某些單元格爲鎖定狀態(即:只讀狀態),設置好後還不能生效,由於要經過點擊 工具—保護—保護工做表,輸入密碼達到效果,在選擇保護工做表項目中能夠控制只讀的屬性(具體看需求):如不能修改樣式名稱,能夠修改行列大小或者刪除行列,還有個選項是選定鎖定單元格,若是把這個鉤選取消了,則只讀時點擊不到被設置只讀保護的單元格,也不會出現不能修改屬性的提示框。 若是咱們須要這些只讀的單元格的功能的話,則須要在模板中設置,經過POI來讀取後再生成的EXCEL 也會保留此功能,還能夠經過POI在讀取模板後設置哪些字段爲鎖定狀態: 例 HSSFCellStyle alterableStyle = wb.createCellStyle(); //獲取當前單元格的樣式對象 alterableStyle.setLocked(true); //設定此單元格爲鎖定狀態 若是在選擇模板EXCEL不須要設置只讀的屬性時候(即:默認屬性)則能夠不用在模板中選擇保護工做表 ,一樣能夠在POI中實現 例 st.protectSheet(new String("333")); //當前工做表爲保護狀態 密碼爲333 (需知:設置只讀屬性的容許刪除行和列的選項時,若是當前行或者列 有已經被設定爲鎖定的單元格時,則此列或者行不能被刪除) 四 安全問題 因爲模板須要受到保護,建議在創建模板的時候 設置保護工做表 另外最好能夠找到工做以鎖定模板的VBA工程窗口,這樣POI讀取模板後 生成的EXCELVBA工程窗口也自動被鎖定, 以防止破解 模板的工做表密碼

public void test() { try{

HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(-#34;new sheet-#34;);

// Create a row and put some cells in it. Rows are 0 based. HSSFRow row = sheet.createRow((short)0); // Create a cell and put a value in it. HSSFCell cell = row.createCell((short)0); cell.setCellValue(1);

// Or do it on one line. row.createCell((short)1).setCellValue(1.2); row.createCell((short)2).setCellValue(-#34;This is a string-#34;); row.createCell((short)3).setCellValue(true); row.createCell((short)3).setCellValue(-#34;這是中文字符-#34;);

// Write the output to a file FileOutputStream fileOut = new FileOutputStream(-#34;c:/workbook.xls-#34;); wb.write(fileOut); fileOut.close(); }catch(Exception ex){

}

}

我寫的一列row.createCell((short)3).setCellValue(-#34;這是中文字符-#34;); 這樣就出亂碼了,請指教

//先設置編碼 cell.setEncoding(HSSFCell.ENCODING_UTF_16);

//設置值 統一爲String cell.setCellValue(dataValue);

謝謝,我如今的操做系統是XP 英文版的。

用樓上的方法仍是亂碼,我是用Eclipse編譯的。

我也有這個問題,我是2000   用// cell.setCellValue(-#34;中文-#34;);能夠 但用 row.createCell((short)3).setCellValue(-#34;這是中文字符-#34;); 就是亂碼

jxl寫excel import jxl.Workbook; import jxl.read.biff.BiffException; import jxl.Sheet; import jxl.write.Label; import jxl.Cell; import jxl.write.WritableWorkbook; import jxl.write.WritableSheet; import jxl.write.WriteException;

public void exportExcelFile(String outputFile, List dataList) throws Exception {

//建立工做表與sheet的引用 WritableWorkbook wb = null; WritableSheet ws = null; //直接根據輸出的文件建立工做表對象 try { wb = Workbook.createWorkbook(new File(outputFile)); //建立第一頁的sheet ws = wb.createSheet(-#34;sheet1-#34;, 0); //循環導出數據 for (int rowId = 0; rowId -#60; dataList.size(); rowId++) { //獲得對應行的數據列表 List valueList = (List) dataList.get(rowId); //循環每個單元格 for (int column = 0; column -#60; valueList.size(); column++) { //獲得對應單元格的值 String value = (String) valueList.get(column); //設置值 Label label = new Label(column, rowId, value); //加到sheet上 ws.addCell(label); } } //輸出到文件 wb.write(); //關閉文件 wb.close(); } catch(Exception e) {

} } poi 寫excel import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDateUtil; 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; import org.apache.poi.poifs.filesystem.POIFSFileSystem;

public List parseExcelFile( InputStream inputStream ) throws PMSBusinessException { //設置通用對象列表 List dataList = new ArrayList(); List valueList = null; //以文件流構造workbook HSSFWorkbook workbook = null; workbook = new HSSFWorkbook(inputStream); int sheetNum = workbook.getNumberOfSheets(); //獲得第一個sheet對象 HSSFSheet templateSheet = workbook.getSheetAt(1); HSSFRow templateRow = templateSheet.getRow(0); //獲得總行數 int rowNum = templateSheet.getPhysicalNumberOfRows(); //獲得總列數 int columnNum = templateSheet.getRow(0).getPhysicalNumberOfCells(); //循環每一行 for (int rowId = 0; rowId -#60; rowNum; rowId++) { //獲得第rowId行對象 HSSFRow hsrow = templateSheet.getRow(rowId); //建立一個值列表對象 分別存放每個字段對應的值 valueList = new ArrayList(); //循環每一列 for (int columnId = 0; columnId -#60; columnNum; columnId++) { String value = null; //獲得一個單元格 if(hsrow == null) return dataList;

HSSFCell cell = hsrow.getCell((short) columnId); //取模板第一個單元格 HSSFCell templateCell = templateRow.getCell((short) columnId); //取得列名稱 String columnName = templateCell.getStringCellValue().trim(); //只有單元格中有值時才作類型判斷 if (cell != null) { //獲得類型 int cellType = cell.getCellType(); switch (cellType) { //若是是空串 case HSSFCell.CELL_TYPE_BLANK : value = -#34;-#34;; break; //若是是布爾型 case HSSFCell.CELL_TYPE_BOOLEAN : value = cell.getBooleanCellValue() ? -#34;TRUE-#34; : -#34;FALSE-#34;; break; //若是是錯誤型 case HSSFCell.CELL_TYPE_ERROR : value = -#34;#ERR-#34; + cell.getErrorCellValue(); break; //若是是公式型 case HSSFCell.CELL_TYPE_FORMULA : value = cell.getCellFormula(); break; //若是是數字型 case HSSFCell.CELL_TYPE_NUMERIC : //判斷一下是不是日期類型 if (HSSFDateUtil.isCellDateFormatted(cell)) { //轉爲yyyy-MM-dd格式 DateFormat sdf = new SimpleDateFormat(-#34;yyyy-MM-dd-#34;); value = sdf.format(cell.getDateCellValue()); } //不然是數字 else {

if ( -#34;編號-#34;.equals( columnName ) || -#34;時限-#34;.equals( columnName ) ) { //轉爲整數的字符串 value =-#34;-#34;+(long)cell.getNumericCellValue(); } //其餘所有轉爲小數型字符串 else { value = cell.getNumericCellValue() + -#34;-#34;; } } break; //字符串型 case HSSFCell.CELL_TYPE_STRING : value = cell.getStringCellValue(); break; //其它 default : value = -#34;Unknown Cell Type: -#34; + cell.getCellType(); } } //把轉化後的值放入List 這裏list中可能放入null 表明沒有值 valueList.add(value); } } //返回通用列表所有爲String 類型 或 Null return dataList; }

導出有模板文件的excel public void exportStyleFile(String inputFile, String outputFile, List dataList) throws PMSBusinessException { POIFSFileSystem fs = null; HSSFWorkbook templatewb = null; //用模板文件構造poi try { fs = new POIFSFileSystem(new FileInputStream(inputFile)); //建立模板工做表 templatewb = new HSSFWorkbook(fs); } catch (FileNotFoundException e) { e.printStackTrace(System.out); } catch (IOException e) { e.printStackTrace(System.out); }

//直接取模板第一個sheet對象 HSSFSheet templateSheet = templatewb.getSheetAt(1); //獲得模板的第一個sheet的第一行對象 爲了獲得模板樣式 HSSFRow templateRow = templateSheet.getRow(0); //取得Excel文件的總列數 int columns = templateSheet.getRow((short) 0).getPhysicalNumberOfCells(); //建立樣式數組 HSSFCellStyle styleArray[] = new HSSFCellStyle[columns]; //一次性建立全部列的樣式放在數組裏 for (int s = 0; s -#60; columns; s++) { //獲得數組實例 styleArray[s] = templatewb.createCellStyle(); } //循環對每個單元格進行賦值 這裏要求模板的列序與list中的值要一一對應 //定位行 for (int rowId = 1; rowId -#60;= dataList.size(); rowId++) { //依次取第rowId行數據 每個數據是valueList List valueList = (List) dataList.get(rowId - 1); //定位列 for (int columnId = 0; columnId -#60; valueList.size(); columnId++) { //依次取出對應與colunmId列的值 //每個單元格的值 String dataValue = (String) valueList.get(columnId); //取出colunmId列的的style //模板每一列的樣式 HSSFCellStyle style = styleArray[columnId]; //取模板第colunmId列的單元格對象 //模板單元格對象 HSSFCell templateCell = templateRow.getCell((short) columnId); //建立一個新的rowId行 行對象 //新建的行對象 HSSFRow hssfRow = templateSheet.createRow(rowId); //建立新的rowId行 columnId列 單元格對象 //新建的單元格對象 HSSFCell cell = hssfRow.createCell((short) columnId); //若是對應的模板單元格 樣式爲非鎖定 HSSFFont font = templatewb.createFont(); String columnName = templateCell.getStringCellValue().trim(); //若是是不許修改的列則紅色顯示字體 if(columnId==0 || columnId==1 ||columnId== 2 || columnId==3 || columnId == 5 || columnId == 7 || columnId== 13|| columnId==15) { //設置此列style爲非鎖定 //style.setLocked(false); font.setColor(HSSFFont.COLOR_RED); style.setFont(font); //設置到新的單元格上 cell.setCellStyle(style); } //不然樣式爲鎖定 普通顏色 else { //設置此列style爲鎖定 //style.setLocked(true); font.setColor(HSSFFont.COLOR_NORMAL); style.setFont(font); //設置到新單元格上 cell.setCellStyle(style); } //設置編碼 cell.setEncoding(HSSFCell.ENCODING_UTF_16); //設置值 統一爲String cell.setCellValue(dataValue); } } //設置輸入流 FileOutputStream fOut = null;; try { fOut = new FileOutputStream(outputFile); //將模板的內容寫到輸出文件上 templatewb.write(fOut); fOut.flush(); //操做結束,關閉文件 fOut.close(); } catch (FileNotFoundException e1) { e1.printStackTrace(System.out);

} }

no格式 public void exportExcelFile(String outputFile, List dataList) //建立工做表 HSSFWorkbook workbook = new HSSFWorkbook(); //建立sheet HSSFSheet sheet = workbook.createSheet(); //循環導出 for (int rowId = 0; rowId -#60; dataList.size(); rowId++) { //取出對應行的數據列表對象 List valueList = (List) dataList.get(rowId); //從第0行開始建立 HSSFRow hsrow = sheet.createRow(rowId); //依次寫入每個單元格 for (int columnId = 0; columnId -#60; valueList.size(); columnId++) { //獲得對應單元格的值 String dataValue = (String) valueList.get(columnId); //建立該行的單元格 HSSFCell cell = hsrow.createCell((short) columnId); //設置編碼 cell.setEncoding(HSSFCell.ENCODING_UTF_16); //設置值 cell.setCellValue(dataValue); } } //寫出到文件 FileOutputStream os; try { os = new FileOutputStream(outputFile); workbook.write(os); os.flush(); //關閉文件流 os.close(); } catch (FileNotFoundException e) { e.printStackTrace(System.out); } } 如何使用Java POI生成Excel表文件 2008-02-29 17:04 // 使用Java POI // 把要兩個JAR文件放到lib/ext下 // code run against the jakarta-poi-1.5.0-FINAL-20020506.jar. // and commons-logging-1.0.jar 例子程序: import org.apache.poi.hssf.usermodel.*; import java.io.FileOutputStream;

// code run against the jakarta-poi-1.5.0-FINAL-20020506.jar. // and commons-logging-1.0.jar public class PoiTest {

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

FileOutputStream fos = new FileOutputStream("d://foo.xls"); HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet s = wb.createSheet(); wb.setSheetName(0, "Matrix"); for(short i=0; i<50; i++) { HSSFRow row = s.createRow(i); for(short j=0; j<50; j++) { HSSFCell cell = row.createCell(j); cell.setCellValue(""+i+","+j); } } wb.write(fos); fos.close(); } }

二、

import org.apache.poi.hssf.model.Workbook; import org.apache.poi.hssf.usermodel.*; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date;

public class ExcelCreate { public static void main(String[] args)throws IOException {

HSSFWorkbook wb = new HSSFWorkbook();//創建新HSSFWorkbook對象 HSSFSheet sheet = wb.createSheet("new sheet");//創建新的sheet對象

// Create a row and put some cells in it. Rows are 0 based. HSSFRow row = sheet.createRow((short)0);//創建新行

// Create a cell and put a value in it. HSSFCell cell = row.createCell((short)0);//創建新cell cell.setCellValue(1);//設置cell的整數類型的值

// Or do it on one line. row.createCell((short)1).setCellValue(1.2);//設置cell浮點類型的值 row.createCell((short)2).setCellValue("test");//設置cell字符類型的值 row.createCell((short)3).setCellValue(true);//設置cell布爾類型的值 HSSFCellStyle cellStyle = wb.createCellStyle();//創建新的cell樣式 Workbook workBook = new Workbook(); HSSFDataFormat hSSFDataFormat = new HSSFDataFormat(workBook); cellStyle.setDataFormat(hSSFDataFormat.getFormat("m/d/yy h:mm"));//設置cell樣式爲定製的日期格式 HSSFCell dCell =row.createCell((short)4); dCell.setCellValue(new Date());//設置cell爲日期類型的值 dCell.setCellStyle(cellStyle); //設置該cell日期的顯示格式 HSSFCell csCell =row.createCell((short)5); csCell.setEncoding(HSSFCell.ENCODING_UTF_16);//設置cell編碼解決中文高位字節截斷 csCell.setCellValue("中文測試_Chinese Words Test");//設置中西文結合字符串 row.createCell((short)6).setCellType(HSSFCell.CELL_TYPE_ERROR);//創建錯誤cell

// Write the output to a file FileOutputStream fileOut = new FileOutputStream("c:/workbook.xls"); wb.write(fileOut); fileOut.close();

} }

POI設置Excel的格式 字體樣式 美化 2008年08月11日 星期一 14:09

import java.io.FileOutputStream; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRichTextString; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor;

/** *

  • @author hadeslee */ public class Test2{

    /** Creates a new instance of Test2 */ public Test2() { } public static void main(String[] args)throws Exception { //聲明一個工做薄 HSSFWorkbook wb=new HSSFWorkbook(); //生成一個表格 HSSFSheet sheet=wb.createSheet("表格1"); //生成一個列 HSSFRow row=sheet.createRow(0); //生成一個樣式 HSSFCellStyle style=wb.createCellStyle(); //設置這些樣式 style.setFillForegroundColor(HSSFColor.SKY_BLUE.index); style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND); style.setBorderBottom(HSSFCellStyle.BORDER_THIN); style.setBorderLeft(HSSFCellStyle.BORDER_THIN); style.setBorderRight(HSSFCellStyle.BORDER_THIN); style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); //生成一個字體 HSSFFont font=wb.createFont(); font.setColor(HSSFColor.VIOLET.index); font.setFontHeightInPoints((short)16); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //把字體應用到當前的樣式 style.setFont(font); //填充單元格 for(short i=0;i<5;i++){ //聲明一個單元格 HSSFCell cell=row.createCell(i); //設置單元格的字符值 cell.setCellValue(new HSSFRichTextString("第"+i+"列")); //設置單元格的樣式 cell.setCellStyle(style); } FileOutputStream fout=new FileOutputStream("個人第一個EXCEL.xls"); //輸出到文件 wb.write(fout); fout.close(); } }

public static void main(String[] args) { try { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet(); HSSFRow row = sheet.createRow(0); row.setHeight((short) 25);//目的是想把行高設置成25px FileOutputStream fileOut = new FileOutputStream("c://a.xls"); wb.write(fileOut); fileOut.close(); } catch (Exception e) { e.printStackTrace(); } }

打開a.xls發現結果不是我想要的,第一行的高度都沒有,沒有報錯說明代碼有問題,爲何回沒有高度呢?是否是單位不同呢?我把row.setHeight((short) 25);改爲了row.setHeight((short) 250);結果發現第一行出來了,可是這是怎麼一個換算關係呢?我查看了一下導出的Excel第一行高是16像素,換算一下得出row.setHeight((short) 15.625);表示行高爲一個像素,那麼想設成幾個像素就好作了。好比 row.setHeight((short) (15.625*n));//n爲行高的像素數。 其實在API中還有一個HSSFRow 對象還有一個設置行高的函數setHeightInPoints(float height);這個函數中參數就是行高的像素數,比setHeight函數要方便多了。 行高設置完成了,接下來設置列寬

public static void main(String[] args) {
    try {
         HSSFWorkbook wb = new HSSFWorkbook();
         HSSFSheet sheet = wb.createSheet();
         HSSFRow row = sheet.createRow(0);
         row.setHeight((short) 250);
         sheet.setColumnWidth((short) 0, (short) 250);
         FileOutputStream fileOut = new FileOutputStream("c://a.xls");
         wb.write(fileOut);
         fileOut.close();
     }
    catch (Exception e) {
         e.printStackTrace();
     }
 }

接下來講說sheet.setColumnWidth((short) 0, (short) 250); 第一個參數表示要爲第幾列設置,第二個參數表示列的寬度,看看上面的代碼按說第一行第一列的單元格形狀應該是個正方形,由於寬和高都是250,可是打開導出後的Excel發現寬度沒有高度大,是個長方形,查看該列的寬度僅爲7個像素,看來行高和列寬的單位是不同的,一樣換一算sheet.setColumnWidth((short) 0, (short) (35.7));表示高度爲一個像素,一樣設置列寬的像素爲sheet.setColumnWidth((short) 0, (short) (35.7*n));//n爲列高的像素數。

public class MergedCells { public static void main(String[] args) throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("new sheet");

HSSFRow row = sheet.createRow((short) 1);
     HSSFCell cell = row.createCell((short) 1);
     cell.setCellValue("This is a test of merging");

     sheet.addMergedRegion(new Region(1, (short) 1, 1, (short) 2));

     // Write the output to a file
     FileOutputStream fileOut = new FileOutputStream("workbook.xls");
     wb.write(fileOut);
     fileOut.close();

 }

}

public class WorkingWithFonts { public static void main(String[] args) throws IOException { HSSFWorkbook wb = new HSSFWorkbook(); HSSFSheet sheet = wb.createSheet("new sheet");

// Create a row and put some cells in it. Rows are 0 based.
     HSSFRow row = sheet.createRow((short) 1);

     // Create a new font and alter it.
     HSSFFont font = wb.createFont();
     font.setFontHeightInPoints((short) 24);
     font.setFontName("Courier New");
     font.setItalic(true);
     font.setStrikeout(true);

     // Fonts are set into a style so create a new one to use.
     HSSFCellStyle style = wb.createCellStyle();
     style.setFont(font);

     // Create a cell and put a value in it.
     HSSFCell cell = row.createCell((short) 1);
     cell.setCellValue("This is a test of fonts");
     cell.setCellStyle(style);

     // Write the output to a file
     FileOutputStream fileOut = new FileOutputStream("workbook.xls");
     wb.write(fileOut);
     fileOut.close();

 }

}

HSSFRow row = sheet2.createRow(2); row.setHeightInPoints(240); sheet2.setColumnWidth((short) 2, (short) 9000);

單元格的合併、數據行的分組以及Excel窗口的凍結 原本想把這三個東西分開來實現的,後來發現分開後內容都不多,因而就合在一塊兒說吧。那總不能乾巴巴的列幾個例子就完了吧,那就拿比較初級但又會常常遇到的表格類數據的統計的設計來作個小例子。(源碼下載)

結果發現——還真夠辛苦的。

此次先看效果圖吧,其中的豎排並非真正意義上Excel那種設置的豎排,而是稍微轉變了一下輸出的方式實現的,由於老外的英文單詞沒有這種豎排的可能(頂可能是旋轉,可是那樣字體就變了)。除此以外想到的另一種豎排文字的實現方式就是樣式旋轉+字體旋轉,沒測試,不知道是否可用,誰有功夫實現一下,而後記得告訴我結果啊。

poi_chap3.JPG

老樣子,把核心的代碼和簡要的說明列出來你們看一下吧。

// 這裏首先建立一個單元格樣式對象,設置了四周的邊框以及字體能夠換行 // 其中的字體換行是用來豎向顯示其中的一個單元格的 // 更好的一點兒作法是再作一個單獨的單元格樣式對象 // 要否則在處理自動列寬的時候可能會有點兒小問題 HSSFCellStyle normalStyle = wb.createCellStyle(); normalStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN); normalStyle.setBorderTop(HSSFCellStyle.BORDER_THIN); normalStyle.setBorderRight(HSSFCellStyle.BORDER_THIN); normalStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN); normalStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER); normalStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); normalStyle.setWrapText(true);

// 合併單元格A1-C1,填入內容的時候添到第一個格子裏就能夠 // 可是注意一點:單元格合併後設置邊框只在原第一個上有效, // 若是想應用的合併後的總體,則須要一個個的Create出單元格並應用樣式 // 這個明顯是一個不太方便的操做,期待POI下一版的改進了 st.addMergedRegion(new Region(0, (short) 0, 0, (short) 2)); HSSFRow row = st.createRow(0); HSSFCell cell = row.createCell((short) 0); cell.setCellValue(new HSSFRichTextString("業務一覽表")); cell.setCellStyle(normalStyle); row.createCell((short) 1).setCellStyle(normalStyle); row.createCell((short) 2).setCellStyle(normalStyle);

// 設置列頭,固然也能夠一個一個格子的寫,用循環感受有些取巧而已 // 一樣,須要單獨給每一個單元格應用樣式對象 String[] seasonName = { "第一季度", "第二季度", "第三季度", "第四季度" }; for (short i = 3; i < 7; i++) { cell = row.createCell(i); cell.setCellValue(new HSSFRichTextString(seasonName[i - 3])); cell.setCellStyle(normalStyle); }

// 這個是豎排文字的實現 // 目前POI沒找到(或許沒提供,或許我無知)讓文字豎排的方法, // HSSFCellStyle.setRotation()方法是設置旋轉角度的,和豎排不太同樣, // 後來想了一下,由於只有中文等全角字符纔有豎排的可能, // 一個英文單詞要是豎排看起來恐怕會很是怪異,不過不排除搞藝術的…… st.addMergedRegion(new Region(1, (short) 0, 6, (short) 0)); row = st.createRow(1); cell = row.createCell((short) 0); cell.setCellValue(new HSSFRichTextString("地/n區/n代/n理/nA")); cell.setCellStyle(normalStyle); for (int i = 2; i < 7; i++) st.createRow(i).createCell((short) 0).setCellStyle(normalStyle);

// 屬於地區的二級分類,豎向合併相鄰的兩個單元格,其餘同上 String[] shopName = { "連鎖店A", "連鎖店B", "連鎖店C" }; for (int i = 1; i < 6; i = i + 2) { row = st.createRow(i); cell = row.createCell((short) 1); cell.setCellValue(new HSSFRichTextString(shopName[(i - 1) / 2])); cell.setCellStyle(normalStyle); st.createRow(i + 1).createCell((short) 1).setCellStyle(normalStyle); st.addMergedRegion(new Region(i, (short) 1, i + 1, (short) 1)); }

// 屬於連鎖店的下一級,基本也是建立出來而後賦值+應用樣式 for (int i = 1; i < 7; i = i + 2) { cell = st.getRow(i).createCell((short) 2); cell.setCellValue(new HSSFRichTextString("收入")); cell.setCellStyle(normalStyle); cell = st.getRow(i + 1).createCell((short) 2); cell.setCellValue(new HSSFRichTextString("支出")); cell.setCellStyle(normalStyle); }

// 數據部分,直接Create而後應用樣式,有數據的話這個地方就打數據好了 for (int i = 1; i < 7; i++) for (short j = 3; j < 7; j++) st.createRow(i).createCell(j).setCellStyle(normalStyle);

// 凍結Excel的窗口,邊界爲數據部分的邊界 st.createFreezePane(3, 1);

// 按照連鎖店級別分組(固然實際狀況這樣分組沒啥意義) for (int i = 1; i < 7; i = i + 2) st.groupRow(i, i);

// 按照地區分組 st.groupRow(1, 5);

其實這樣實現起來是否是很麻煩呢?答案是:是。

其實這只是舉個例子,熟悉一下POI的各類API而已,真正要實現這樣一個表格的時候,例如項目須要製做報表等等,一般的作法都是事先把格式一切的東西都手動製做好(這個作好了的文件在實際的項目裏咱們稱之爲「數據模板」,簡稱「模板」),而後在Java應用中適當的時機把這個文件讀進來修改,最後再另存到指定的位置或者傳遞給下一個處理者(例如以流的方式送給Servlet等等),這樣其實POI具體作的事情就是向模板裏寫業務的數據,仍是很方便快捷的。

相關文章
相關標籤/搜索