<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 154  文章 - 60  trackbacks - 0
    <2007年11月>
    28293031123
    45678910
    11121314151617
    18192021222324
    2526272829301
    2345678

    聲明:

    該blog是為了收集資料,認識朋友,學(xué)習(xí)、提高技術(shù),所以本blog的內(nèi)容除非聲明,否則一律為轉(zhuǎn)載!!

    感謝那些公開自己技術(shù)成果的高人們!!!

    支持開源,尊重他人的勞動!!

    常用鏈接

    留言簿(3)

    隨筆分類(148)

    隨筆檔案(143)

    收藏夾(2)

    其他

    學(xué)習(xí)(技術(shù))

    觀察思考(非技術(shù))

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    今天又用到了excel操作但由于相隔久遠只好重新復(fù)習(xí),順便整理一下,之前整理了JavaExcelAPI(簡稱JXL)的,由于POI用的不是很多就把4篇整理到一個blog中!!

    akata Poi HSSF:純java的Excel解決方案
    2002-10-23 上午 08:52:34

    微軟在桌面系統(tǒng)上的成功,令我們不得不大量使用它的辦公產(chǎn)品,如:Word,Excel。時至今日,它的源代碼仍然不公開已封鎖了我們的進一步應(yīng)用和開發(fā)。然而在要求更高的服務(wù)器領(lǐng)域,微軟本身的產(chǎn)品移植性不好,
    性能不佳。在我們實際的開發(fā)中,表現(xiàn)層的解決方案雖然有多樣,但是Ie瀏覽器已成為最多人使用的瀏覽器,因為大家都用Windows。在企業(yè)辦公系統(tǒng)中,常常有客戶這樣子要求:你要把我們的報表直接用Excel打開。或者是:我們已經(jīng)習(xí)慣用Excel打印。這樣子如果用.net開發(fā)是沒有問題的,但是有j2ee這個比.net更有前途的開放式的開發(fā)環(huán)境,難道我為了解決打印的要求去另寫客戶端的控件?或者在服務(wù)器端使用本地代碼?第一種方案的問題是關(guān)鍵數(shù)據(jù)的處理有時候不能在客戶端做,第2種方案的問題是犧牲了代碼的可移植性和穩(wěn)定性。如果讓客戶端只負責(zé)處理生成好的報表,那將是一種誘人的選擇。

    Apache的Jakata項目的POI子項目,目標是處理ole2對象。目前比較成熟的是HSSF接口,處理MS Excel(97-2002)對象。它不象我們僅僅是用csv生成的沒有格式的可以由Excel轉(zhuǎn)換的東西,而是真正的Excel對象,你可以控制一些屬性如sheet,cell等等。這是一個年輕的項目,所以象HDF這樣直接支持Word對象的好東西仍然在設(shè)計中。其它支持word格式的純java方案還有itext,不過也是仍在奮斗中。但是HSSF已經(jīng)成熟到能夠和足夠我們使用了。另外,無錫永中Office的實現(xiàn)方案也是純java的解決方案,不過那也是完全商業(yè)的產(chǎn)品,并不是公開代碼項目。其實,從開發(fā)歷史的角度講,在80年代中期starOffice的原作者在德國成立了StarOffice suite公司,然后到1999年夏天starOffice被sun收購,再到2000年6月starOffice5.2的發(fā)布;并且從starOffice6.0開始,starOffice建立在OpenOffice的api的基礎(chǔ)上,這個公開代碼的office項目已經(jīng)進行了很長的時間。雖然那是由C++寫的,但是POI的代碼部分也是由openOffice改過來的。所以,應(yīng)該對POI充滿足夠的信心。國內(nèi)已經(jīng)有部分公司在他們的辦公自動化等Web項目中使用poi了,如日恒的ioffice,海泰的HTOffice等。

    java當(dāng)初把核心處理設(shè)成Unicode,帶來的好處是另代碼適應(yīng)了多語言環(huán)境。然而由于老外的英語只有26個字母,有些情況下,一些程序員用8位的byte處理,一不小心就去掉了CJK的高位。或者是由于習(xí)慣在程序中采用硬編碼,還有多種原因,使得許多java應(yīng)用在CJK的處理上很煩惱。還好在POI HSSF中考慮到這個問題,可以設(shè)置encoding為雙字節(jié)。

    POI可以到www.apache.org下載到。編譯好的jar主要有這樣4個:poi包,poi Browser包,poi hdf包,poi hssf例程包。實際運行時,需要有poi包就可以了。如果用Jakarta ant編譯和運行,下載apache Jakarta POI的release中的src包,它里面已經(jīng)為你生成好了build文件了。只要運行ant就可以了(ant 的安裝和使用在此不說了)。如果是用Jbuilder 運行,請在新建的項目中加入poi包。以Jbuilder6為例,選擇Tools菜單項的config libraries...選項,新建一個lib。在彈出的菜單中選擇poi包,如這個jakarta-poi-1.5.1-final-20020820.jar,把poi添加到j(luò)builder中。然后,右鍵點擊你的項目,在project的properties菜單中path的required Libraries中,點add,添加剛才加入到j(luò)builder中的poi到你現(xiàn)在的項目中。如果你僅僅是為了熟悉POI hssf的使用,可以直接看POI的samples包中的源代碼,并且運行它。hssf的各種對象都有例程的介紹。hssf提供的例程在org.apache.poi.hssf.usermodel.examples包中,共有14個,生成的目標xls都是workbook.xls。如果你想看更多的例程,可以參考hssf的Junit test cases,在poi的包的源代碼中有。hssf都有測試代碼。

    這里只對部分例程的實現(xiàn)做介紹。

    HSSF提供給用戶使用的對象在org.apache.poi.hssf.usermodel包中,主要部分包括Excell對象,樣式和格式,還有輔助操作。有以下幾種對象:

    HSSFWorkbook excell的文檔對象

    HSSFSheet excell的表單

    HSSFRow excell的行

    HSSFCell excell的格子單元

    HSSFFont excell字體

    HSSFName 名稱

    HSSFDataFormat 日期格式

    在poi1.7中才有以下2項:

    HSSFHeader sheet頭

    HSSFFooter sheet尾

    和這個樣式

    HSSFCellStyle cell樣式

    輔助操作包括

    HSSFDateUtil 日期

    HSSFPrintSetup 打印

    HSSFErrorConstants 錯誤信息表

    仔細看org.apache.poi.hssf包的結(jié)構(gòu),不難發(fā)現(xiàn)HSSF的內(nèi)部實現(xiàn)遵循的是MVC模型。

    這里我用Rose把org.apache.poi.hssf.usermodel包中的對象反向?qū)氩⒏鶕?jù)相互關(guān)系作了整理,詳見下面兩圖:

    圖1 基本對象

    從中不難可以發(fā)現(xiàn)每一個基本對象都關(guān)聯(lián)了一個Record對象。Record對象是一個參考Office格式的相關(guān)記錄。

    圖2 HSSFWorkbook

    HSSFWorkbook即是一個Excell對象。這幅類圖體現(xiàn)的是HSSFWorkbook和基本對象的相互關(guān)系。可見,許多對象中也建立了Workbook的引用。還需要注意的是在HSSFWorkbook和HSSFSheet中建立了log機制POILogger,而且POILogger也是使用apache Log4J實現(xiàn)的。

    先看poi的examples包中提供的最簡單的例子,建立一個空xls文件。

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

    import java.io.FileOutputStream;

    import java.io.IOException;

    public class NewWorkbook

    {

    public static void main(String[] args)

    throws IOException

    {

    HSSFWorkbook wb = new HSSFWorkbook();//建立新HSSFWorkbook對象

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

    wb.write(fileOut);//把Workbook對象輸出到文件workbook.xls中

    fileOut.close();

    }

    }

    通過這個例子,我們建立的是一個空白的xls文件(不是空文件)。在此基礎(chǔ)上,我們可以進一步看其它的例子。

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

    import java.io.FileOutputStream;

    import java.io.IOException;

    public class CreateCells

    {

    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);//設(shè)置cell的整數(shù)類型的值

    // Or do it on one line.

    row.createCell((short)1).setCellValue(1.2);//設(shè)置cell浮點類型的值

    row.createCell((short)2).setCellValue("test");//設(shè)置cell字符類型的值

    row.createCell((short)3).setCellValue(true);//設(shè)置cell布爾類型的值

    HSSFCellStyle cellStyle = wb.createCellStyle();//建立新的cell樣式

    cellStyle.setDataFormat(HSSFDataFormat.getFormat("m/d/yy h:mm"));//設(shè)置cell樣式為定制的日期格式

    HSSFCell dCell =row.createCell((short)4);

    dCell.setCellValue(new Date());//設(shè)置cell為日期類型的值

    dCell.setCellStyle(cellStyle); //設(shè)置該cell日期的顯示格式

    HSSFCell csCell =row.createCell((short)5);

    csCell.setEncoding(HSSFCell.ENCODING_UTF_16);//設(shè)置cell編碼解決中文高位字節(jié)截斷

    csCell.setCellValue("中文測試_Chinese Words Test");//設(shè)置中西文結(jié)合字符串

    row.createCell((short)6).setCellType(HSSFCell.CELL_TYPE_ERROR);//建立錯誤cell

    // Write the output to a file

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

    wb.write(fileOut);

    fileOut.close();

    }

    }

    我稍微修改了原來的examples包中的CreateCells類寫了上面的功能測試類。通過這個例子,我們可以清楚的看到xls文件從大到小包括了HSSFWorkbook HSSFSheet HSSFRow HSSFCell這樣幾個對象。我們可以在cell中設(shè)置各種類型的值。尤其要注意的是如果你想正確的顯示非歐美的字符時,尤其象中日韓這樣的語言,必須設(shè)置編碼為16位的即是HSSFCell.ENCODING_UTF_16,才能保證字符的高8位不被截斷而引起編碼失真形成亂碼。

    其他測試可以通過參考examples包中的測試例子掌握poi的詳細用法,包括字體的設(shè)置,cell大小和低紋的設(shè)置等。需要注意的是POI是一個仍然在完善中的公開代碼的項目,所以有些功能正在不斷的擴充。如HSSFSheet的getFooter() getHeader()和setFooter(HSSFFooter hsf) setHeader(HSSFHeader hsh)是在POI1.7中才有的,而POI1.5中就沒有。運行測試熟悉代碼或者使用它做項目時請注意POI的版本。

    另外需要注意的是HSSF也有它的對xls基于事件的解析。可以參考例程中的EventExample.java。它通過實現(xiàn)HSSFListener完成從普通流認知Xls中包含的內(nèi)容,在apache Cocoon中的org.apache.cocoon.serialization.HSSFSerializer中用到了這個解析。因為Cocoon2是基于事件的,所以POI為了提供快速的解析也提供了相應(yīng)的事件。當(dāng)然我們自己也可以實現(xiàn)這個事件接口。

    因為POI還不是一個足夠成熟的項目,所以有必要做進一步的開發(fā)和測試。但是它已經(jīng)為我們用純java操作ole2對象提供了可能,而且克服了ole對象調(diào)用的缺陷,提供了服務(wù)器端的Excel解決方案。
    ======================================================

    利用Java 創(chuàng)建和讀取Excel文檔 

    --------------------------------------------------------------------------------
    源作者:Rubber                   人氣:26748 
       為了保證示例程序的運行,必須安裝Java 2 sdk1.4.0 和Jakarta POI,Jakarta POI的Web站點是: http://jakarta.apache.org/poi/

     

    示例1將演示如何利用Jakarta POI API 創(chuàng)建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盤JTest目錄下*/
     public static String outputFile="D:/JTest/ gongye.xls";
     public static void main(String argv[])
      {
     try
      {
      // 創(chuàng)建新的Excel 工作簿
      HSSFWorkbook workbook = new HSSFWorkbook();
      // 在Excel工作簿中建一工作表,其名為缺省值
      // 如要新建一名為"效益指標"的工作表,其語句為:
      // HSSFSheet sheet = workbook.createSheet("效益指標");
      HSSFSheet sheet = workbook.createSheet();
      // 在索引0的位置創(chuàng)建行(最頂端的行)
      HSSFRow row = sheet.createRow((short)0);
      //在索引0的位置創(chuàng)建單元格(左上端)
      HSSFCell cell = row.createCell((short) 0);
      // 定義單元格為字符串類型
      cell.setCellType(HSSFCell.CELL_TYPE_STRING);
      // 在單元格中輸入一些內(nèi)容
      cell.setCellValue("增加值");
      // 新建一輸出文件流
      FileOutputStream fOut = new FileOutputStream(outputFile);
      // 把相應(yīng)的Excel 工作簿存盤
      workbook.write(fOut);
      fOut.flush();
      // 操作結(jié)束,關(guān)閉文件
      fOut.close();
      System.out.println("文件生成...");

     

     }catch(Exception e) {
      System.out.println("已運行 xlCreate() : " + e );
     }
    }
    }

     

    讀取Excel文檔中的數(shù)據(jù)
      示例2將演示如何讀取Excel文檔中的數(shù)據(jù)。假定在D盤JTest目錄下有一個文件名為gongye.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:/JTest/ gongye.xls";
     public static void main(String argv[]){
     try{
      // 創(chuàng)建對Excel工作簿文件的引用
      HSSFWorkbook workbook = new HSSFWorkbook(new FileInputStream(fileToBeRead));
      // 創(chuàng)建對工作表的引用。
      // 本例是按名引用(讓我們假定那張表有著缺省名"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);
      // 輸出單元內(nèi)容,cell.getStringCellValue()就是取所在單元的值
      System.out.println("左上端單元是: " + cell.getStringCellValue());
     }catch(Exception e) {
      System.out.println("已運行xlRead() : " + e );
     }
    }
    }

     
      設(shè)置單元格格式
      在這里,我們將只介紹一些和格式設(shè)置有關(guān)的語句,我們假定workbook就是對一個工作簿的引用。在Java

     中,第一步要做的就是創(chuàng)建和設(shè)置字體和單元格的格式,然后再應(yīng)用這些格式: 

      1、創(chuàng)建字體,設(shè)置其為紅色、粗體:
    HSSFFont font = workbook.createFont();
    font.setColor(HSSFFont.COLOR_RED);
    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
      2、創(chuàng)建格式
    HSSFCellStyle cellStyle= workbook.createCellStyle();
    cellStyle.setFont(font);
      3、應(yīng)用格式
    HSSFCell cell = row.createCell((short) 0);
    cell.setCellStyle(cellStyle);
    cell.setCellType(HSSFCell.CELL_TYPE_STRING);
    cell.setCellValue("標題 "); 

      總之,如本篇文章所演示的一樣,Java程序員不必擔(dān)心Excel工作表中的數(shù)據(jù)了,利用Jakarta POI API, 

    我們就可以輕易的在程序中存取Excel文檔。

     ==============================================

    首先說說現(xiàn)在我所知道的Java編輯Excel文件的兩大開源工具:

    jakarta POI和JavaExcelAPI(簡稱JXL),這兩套工具我都試用了一這段時間,感覺各有優(yōu)劣吧。POI在某些細節(jié)有些小Bug并且不支持寫入圖片,其他方面都挺不錯的;

    JXL就慘了,除了支持寫入圖片外,我暫時看不到它比POI好的地方,我碰到的主要的問題就是對公式支持不是很好,很多帶有公式的Excel文件用JXL打開后,公式就丟失了(比如now(),today()),在網(wǎng)上看到其他大蝦評論說JXL寫入公式也有問題,另外,JXL操作Excel文件的效率比POI低一點。經(jīng)過比較后,我選擇了POI開發(fā)我的項目。

    現(xiàn)在我要做的東西基本完成啦,我把這段時間使用POI的一些心得總結(jié)出來,希望能對和我遇到相同問題的朋友有所幫助,至于POI基本的使用方法,自己去看文檔吧。

    1、設(shè)置分頁符的bug

    POI里的HSSFSheet類提供了setRowBreak方法可以設(shè)置Sheet的分頁符。

    Bug:如果你要設(shè)置分頁符的Sheet是本來就有的,并且你沒有在里面插入過分頁符,那么調(diào)用setRowBreak時POI會拋出空指針的異常。

    解決方法:在Excel里給這個sheet插入一個分頁符,用POI打開后再把它刪掉,然后你就可以隨意插入分頁符了。

    如果sheet是由POI生成的則沒有這個問題。我跟蹤了setRowBreak的源代碼,發(fā)現(xiàn)是Sheet.Java下的PageBreakRecord rowBreaks這個變量在搞鬼,如果Sheet里原來沒有分頁符,開發(fā)這個模塊的那位兄臺忘了為這個對象new實例,所以只能我們先手工給Excel插入一個分頁符來觸發(fā)POI為rowBreaks創(chuàng)建實例。

    2、如何拷貝行

    我在gmane.org的POI用戶論壇翻遍了每個相關(guān)的帖子,找遍了api,也沒看到一個拷貝行的方法,沒辦法,只能自己寫:

     

    //注:this.fWorkbook是一個HSSHWorkbook,請自行在外部new
        public void copyRows
        (String pSourceSheetName,
        String pTargetSheetName,
        int pStartRow, int pEndRow,
        int pPosition)
        {
        HSSFRow sourceRow = null;
        HSSFRow targetRow = null;
        HSSFCell sourceCell = null;
        HSSFCell targetCell = null;
        HSSFSheet sourceSheet = null;
        HSSFSheet targetSheet = null;
        Region region = null;
        int cType;
        int i;
        short j;
        int targetRowFrom;
        int targetRowTo;
       
        if ((pStartRow == -1) || (pEndRow == -1))
        {
          return;
        }
        sourceSheet = this.fWorkbook.getSheet(pSourceSheetName);
        targetSheet = this.fWorkbook.getSheet(pTargetSheetName);
        //拷貝合并的單元格
        for (i = 0; i < sourceSheet.getNumMergedRegions(); i++)
        {
        region = sourceSheet.getMergedRegionAt(i);
        if ((region.getRowFrom() >= pStartRow) && (region.getRowTo() <= pEndRow))
        {
        targetRowFrom = region.getRowFrom() - pStartRow + pPosition;
        targetRowTo = region.getRowTo() - pStartRow + pPosition;
        region.setRowFrom(targetRowFrom);
        region.setRowTo(targetRowTo);
        targetSheet.addMergedRegion(region);
        }
        }
        //設(shè)置列寬
        for (i = pStartRow; i <= pEndRow; i++)
        {
        sourceRow = sourceSheet.getRow(i);
        if (sourceRow != null)
        {
        for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++)
        {
        targetSheet.setColumnWidth(j, sourceSheet.getColumnWidth(j));
        }
        break;
        }
        }
        //拷貝行并填充數(shù)據(jù)
        for (;i <= pEndRow; i++)
        {
        sourceRow = sourceSheet.getRow(i);
        if (sourceRow == null)
        {
        continue;
        }
        targetRow = targetSheet.createRow(i - pStartRow + pPosition);
        targetRow.setHeight(sourceRow.getHeight());
        for (j = sourceRow.getFirstCellNum(); j < sourceRow.getLastCellNum(); j++)
        {
        sourceCell = sourceRow.getCell(j);
        if (sourceCell == null)
        {
        continue;
        }
        targetCell = targetRow.createCell(j);
        targetCell.setEncoding(sourceCell.getEncoding());
        targetCell.setCellStyle(sourceCell.getCellStyle());
        cType = sourceCell.getCellType();
        targetCell.setCellType(cType);
        switch (cType)
        {
        case HSSFCell.CELL_TYPE_BOOLEAN:
        targetCell.setCellValue(sourceCell.getBooleanCellValue());
        break;
        case HSSFCell.CELL_TYPE_ERROR:
        targetCell.setCellErrorValue(sourceCell.getErrorCellValue());
        break;           
        case HSSFCell.CELL_TYPE_FORMULA:
        //parseFormula這個函數(shù)的用途在后面說明
        targetCell.setCellFormula(parseFormula(sourceCell.getCellFormula()));
        break;
        case HSSFCell.CELL_TYPE_NUMERIC:
        targetCell.setCellValue(sourceCell.getNumericCellValue());
        break;
        case HSSFCell.CELL_TYPE_STRING:
        targetCell.setCellValue(sourceCell.getStringCellValue());
        break;
        }
        }
        }
        }
     
    這個函數(shù)有兩個問題暫時無法解決:

    a、只能在同一個Workbook里面使用,跨Workbook總是拷不過去,不知道為什么?

    b、由于在拷貝行時也把行高也拷過去了,如果往這些單元格里寫入的數(shù)據(jù)長度超過單元格長度,那么他們不會自動調(diào)整行高!

    3、公式的問題

    POI對Excel公式的支持是相當(dāng)好的,但是我發(fā)現(xiàn)一個問題,如果公式里面的函數(shù)不帶參數(shù),比如now()或today(),那么你通過getCellFormula()取出來的值就是now(ATTR(semiVolatile))和today(ATTR(semiVolatile)),這樣的值寫入Excel是會出錯的,這也是我上面copyRow的函數(shù)在寫入公式前要調(diào)用parseFormula的原因,parseFormula這個函數(shù)的功能很簡單,就是把ATTR(semiVolatile)刪掉,我把它的代碼貼出來:

     

    private String parseFormula(String pPOIFormula)
        {
        final String cstReplaceString = "ATTR(semiVolatile)"; //$NON-NLS-1$
        StringBuffer result = null;
        int index;
       
        result = new StringBuffer();
        index = pPOIFormula.indexOf(cstReplaceString);
        if (index >= 0)
        {
        result.append(pPOIFormula.substring(0, index));
        result.append(pPOIFormula.substring(index + cstReplaceString.length()));
        }
        else
        {
        result.append(pPOIFormula);
        }
       
        return result.toString();
        }
     

    至于為什么會出現(xiàn)ATTR(semiVolatile),還需要大家的探索精神!

    4、向Excel寫入圖片的問題。

    我上POI論壇查相關(guān)帖子,得到兩種結(jié)論:

    1、不支持寫入圖片;

    2、支持寫入圖片,通過EscherGraphics2d這個Class實現(xiàn)。于是我就去查EscherGraphics2d這個Class,發(fā)現(xiàn)這個Class提供了N個drawImage方法,喜出望外的我開始寫代碼,結(jié)果調(diào)了一天,一直看不到效果,黔驢技窮的我在萬般無奈下只好跟蹤進drawImage這個函數(shù)內(nèi)部,經(jīng)過N個函數(shù)調(diào)用后在最底層函數(shù)發(fā)現(xiàn)了最終答案:


    public boolean drawImage(Image image, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1,
       int sx2, int sy2, Color bgColor, ImageObserver imageobserver)
       {
       if (logger.check( POILogger.WARN ))
       logger.log(POILogger.WARN,"drawImage() not supported");
       return true;
       }
     

    所以我強烈建議大家,以后使用第三方開發(fā)包一定盡量下載它的源代碼,這樣你在碰到問題時,看看它的的內(nèi)部是怎么實現(xiàn)的,很多時候就可以不必重蹈我的覆轍了。既然POI不能寫入圖片,那我們只能把目光投向JXL,我用JXL寫入圖片功能是實現(xiàn)了,付出的代價是now()和today()這些函數(shù)丟失掉了,魚與熊掌不能兼得吧。

     ==========================jsp操作===============================

    <%@ page contentType="application/msexcel;charset=gb2312" %>
    response.setHeader("Content-disposition","inline; filename=test1.xls");
       //以上這行設(shè)定傳送到前端瀏覽器時的檔名為test1.xls
       //就是靠這一行,讓前端瀏覽器以為接收到一個excel檔
    下面正常顯示要轉(zhuǎn)化的表

    --------------------------------------------------------------------------

    介紹:
    Jakarta_POI 使用Java讀寫Excel(97-2002)文件,可以滿足大部分的需要。
    因為剛好有一個項目使用到了這個工具,花了點時間順便翻譯了一下POI本身
    帶的一個Guide.有一些節(jié)減和修改,希望給使用這個項目的人一些入門幫助。
    POI 下面有幾個自項目:HSSF用來實現(xiàn)Excel 的讀寫.以下是HSSF的主頁
    http://jakarta.apache.org/poi/hssf/index.html
    下面的介紹是基于以下地址的翻譯:
    http://jakarta.apache.org/poi/hssf/quick-guide.html
    目前的版本為1.51應(yīng)該是很長時間之內(nèi)的一個穩(wěn)定版,但HSSF提供的Sample不是基于
    1.51所寫,所以使用的時候需要適當(dāng)?shù)淖⒁?
    其實POI下面的幾個子項目側(cè)重不同讀寫 Word 的HDF正在開發(fā)當(dāng)中.
    XML下的FOP(http://xml.apache.org/fop/index.html)
    可以輸出pdf文件,也是比較好的一個工具
    目錄:
    創(chuàng)建一個workbook
    創(chuàng)建一個sheet
    創(chuàng)建cells
    創(chuàng)建日期cells
    設(shè)定單元格格式

    說明:
    以下可能需要使用到如下的類
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFDataFormat;
    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.hssf.util.HSSFColor;

    創(chuàng)建workbook

    HSSFWorkbook wb = new HSSFWorkbook();
    //使用默認的構(gòu)造方法創(chuàng)建workbook
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");
    //指定文件名
    wb.write(fileOut);
    //輸出到文件
    fileOut.close();

    創(chuàng)建一個sheet

    HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet1 = wb.createSheet("new sheet");
    //workbook創(chuàng)建sheet
    HSSFSheet sheet2 = wb.createSheet("second sheet");
    //workbook創(chuàng)建另外的sheet
    FileOutputStream fileOut = new FileOutputStream("workbook.xls");
    wb.write(fileOut);
    fileOut.close();

    創(chuàng)建cells
    HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet("new sheet");
    //注意以下的代碼很多方法的參數(shù)是short 而不是int 所以需要做一次類型轉(zhuǎn)換
    HSSFRow row = sheet.createRow((short)0);
    //sheet 創(chuàng)建一行
    HSSFCell cell = row.createCell((short)0);
    //行創(chuàng)建一個單元格
    cell.setCellValue(1);
    //設(shè)定單元格的值
    //值的類型參數(shù)有多中double ,String ,boolean,
    row.createCell((short)1).setCellValue(1.2);
    row.createCell((short)2).setCellValue("This is a string");
    row.createCell((short)3).setCellValue(true);

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

    創(chuàng)建日期cells
    HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet("new sheet");

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

    HSSFCell cell = row.createCell((short)0);
    //設(shè)定值為日期
    cell.setCellValue(new Date());

    HSSFCellStyle cellStyle = wb.createCellStyle();
    //指定日期顯示格式
    cellStyle.setDataFormat(HSSFDataFormat.getFormat("m/d/yy h:mm"));
    cell = row.createCell((short)1);
    cell.setCellValue(new Date());
    //設(shè)定單元格日期顯示格式
    cell.setCellStyle(cellStyle);

    FileOutputStream fileOut = new FileOutputStream("workbook.xls");
    wb.write(fileOut);
    fileOut.close();


    設(shè)定單元格格式
    單元格格式的設(shè)定有很多形式包括單元格的對齊方式,內(nèi)容的字體設(shè)置,
    單元格的背景色等,因為形式比較多,只舉一些例子.以下的例子在
    POI1.5中可能會有所改變具體查看API.
    ..........
    // Aqua background
    HSSFCellStyle style = wb.createCellStyle();
    //創(chuàng)建一個樣式
    style.setFillBackgroundColor(HSSFCellStyle.AQUA);
    //設(shè)定此樣式的的背景顏色填充
    style.setFillPattern(HSSFCellStyle.BIG_SPOTS);

    //樣式的填充類型。
    //有多種式樣如:
    //HSSFCellStyle.BIG_SPOTS
    //HSSFCellStyle.FINE_DOTS
    //HSSFCellStyle.SPARSE_DOTS等
    style.setAlignment(HSSFCellStyle.ALIGN_CENTER );
    //居中對齊
    style.setFillBackgroundColor(HSSFColor.GREEN.index);
    //設(shè)定單元個背景顏色
    style.setFillForegroundColor(HSSFColor.RED.index);
    //設(shè)置單元格顯示顏色
    HSSFCell cell = row.createCell((short) 1);
    cell.setCellValue("X");
    cell.setCellStyle(style);

    -----------------------------------------------------------------
    加上response.setContentType("Application/msexcel");
         response.setHeader("Content-disposition","attachment; filename=book.xls" );
    然后提交給它的時候會時候會提示下載,
    下載的就是生成的EXCEL文件。

    -----------------------------------------------------------


    有趣的是,對一個html文件(數(shù)據(jù)在表格中),當(dāng)把后綴改為xls后,打開文件即是。

    ------------------------------------------

    >>加上response.setContentType("Application/msexcel");
    >>     response.setHeader("Content-disposition","attachment; >>filename=book.xls" );
    >>然后提交給它的時候會時候會提示下載,
    >>下載的就是生成的EXCEL文件。

    book.xls的存放路徑應(yīng)該是哪里?

    ----------------------------------------------------------------


    使用poi的hssf生成一個excel文件以后
    有一個主類Workbook(相當(dāng)于一個excel文件)的方法
    Workbook.write(OutputStream)可以寫到response.getOutputStream()里面
    如果事先設(shè)置response的contentType為excel和下載的附件名稱就可下載excel
        HSSFWorkbook book = _proxy.expertExcel(_formBean,_login);

        if(book!=null)
        {
            response.setContentType ( "application/ms-excel" ) ;
            response.setHeader ( "Content-Disposition" ,
                                 "attachment;filename="+new String("導(dǎo)出Excel.xls".getBytes(),"iso-8859-1"))

    ;
            book.write(response.getOutputStream());
    }
    其中expertExcel無非是從數(shù)據(jù)庫或者其他地方獲取數(shù)據(jù)創(chuàng)建excel即可.

     


    ---------------------------------------------------------------
    response.setHeader("Content-disposition","attachment; filename=book.xls" );
    原來加上attachment瀏覽器就會提示保存或者打開,是我想要的。Thanks all.


    -------------------------------------------------------------------------

    1.用poi生成Excel文件,和WORD文檔都可以,是個不錯的方法,參見poi網(wǎng)站,樓上的朋友描述的很清楚了,此方法適用于生

    成,讀取,解析xls文件
    2.另外一種更簡單的方法:只適用于顯示用的EXCEL文件格式,生成常規(guī)的html文件格式,后綴命名方式為.xls即可.
    3.espreadsheet適用于網(wǎng)上即時的excel文件交互操作,生成,解析,保存修改,但需要購買

    -------------------------------------------------------------------------

    生成一個rtf文件,然后擴展名寫".doc",OK

    -----------------------------------------------------------

    用這個組件向excel寫數(shù)據(jù)時,總是出現(xiàn)中文亂碼情況,請問怎樣解決?

    源代碼:

      HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet("new sheet");
            HSSFHeader header = sheet.getHeader();
            header.setCenter("Center Header");
            HSSFRow row = sheet.createRow((short)0);                    
            HSSFCell cell = row.createCell((short)0);                 
            cell.setCellValue(1);                                        
            row.createCell((short)1).setCellValue(1.2123654);
            row.createCell((short)2).setCellValue("This is a string");
            row.createCell((short)3).setCellValue(true);
            row = sheet.createRow((short)1);
            cell = row.createCell((short)0);                        
            cell.setCellValue(new Date());                    
            row.createCell((short)1).setCellValue(str);
            row.createCell((short)2).setCellValue("This我是一個好人string");
            FileOutputStream fileOut = new FileOutputStream("d:/filename.xls");
            wb.write(fileOut);
            fileOut.close();

    當(dāng)我打開這個"d:/filename.xls"文件時,其中寫入的中文全都是亂碼!!!
    如何解決???

    ----------------------------------------------------------------------

    源代碼:
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet("new sheet");
            HSSFHeader header = sheet.getHeader();
            header.setCenter("Center Header");
            HSSFRow row = sheet.createRow((short)0);
            HSSFCell cell = row.createCell((short)0);
            cell.setCellValue(1);
            row.createCell((short)1).setCellValue(1.2123654);
            row.createCell((short)2).setCellValue("This is a string");
            row.createCell((short)3).setCellValue(true);
            row = sheet.createRow((short)1);
            cell = row.createCell((short)0);  
            cell.setCellValue(new Date());                    
            String str = new String("我是一個好人!!!");
            row.createCell((short)1).setCellValue(str);
            row.createCell((short)2).setCellValue("This我是一個好人string");
           
            FileOutputStream fileOut = new FileOutputStream("d:/filename.xls");
            wb.write(fileOut);
            fileOut.close();
    當(dāng)我打開“d:/filename.xls”文件察看時,里面的中文字符全部是亂碼!
    請問如何解決?

    ---------------------------------------------------------------------

    <%@ page contentType="application/msexcel;charset=gb2312" %>
    response.setHeader("Content-disposition","inline; filename=***.xls");就可以了,要是想要word 就
    <%@ page contentType="application/msword;charset=gb2312" %>
    response.setHeader("Content-disposition","inline; filename=test1.xls");


    -------------------------------------------------------------------

    引用 pengruihua 說:

            有趣的是,對一個html文件(數(shù)據(jù)在表格中),當(dāng)把后綴改為xls后,打開文件即是。

    這個只能說明excel強,這樣寫得xls,在JXL或者POI中都是不認的。

    加一句,用POI寫Excel有點問題,當(dāng)反復(fù)讀寫一個excel文件的時候,讀的速度會越來越慢。
    我的一個生成excel的就是,到了幾千條記錄的時候慢得就不能接受了,最后只好先生成cvs的文本,再將文本導(dǎo)成xls

    文件


    ---------------------------------------------------------------------------
    引用 java_century 說:

            源代碼:
            HSSFWorkbook wb = new HSSFWorkbook();
            HSSFSheet sheet = wb.createSheet("new sheet");
            HSSFHeader header = sheet.getHeader();
            header.setCenter("Center Header");
            HSSFRow row = sheet.createRow((short)0);
            HSSFCell cell = row.createCell((short)0);
            cell.setCellValue(1);
            row.createCell((short)1).setCellValue(1.2123654);
            row.createCell((short)2).setCellValue("This is a string");
            row.createCell((short)3).setCellValue(true);
            row = sheet.createRow((short)1);
            cell = row.createCell((short)0);  
            cell.setCellValue(new Date());                    
            String str = new String("我是一個好人!!!");
            row.createCell((short)1).setCellValue(str);
            row.createCell((short)2).setCellValue("This我是一個好人string");
           
            FileOutputStream fileOut = new FileOutputStream("d:/filename.xls");
            wb.write(fileOut);
            fileOut.close();
    當(dāng)我打開“d:/filename.xls”文件察看時,里面的中文字符全部是亂碼!
    請問如何解決?


    使用POI這樣處理中文
    HSSFCell cell = row.createCell((short)1);
    cell.setEncoding(HSSFCell.ENCODING_UTF_16);
    cell.setCellValue("中文");

    posted on 2007-10-26 09:37 lk 閱讀(10504) 評論(8)  編輯  收藏 所屬分類: j2se

    FeedBack:
    # re: java操作Excel(Jakarta_POI) 2007-11-16 15:59 撒旦飛
    怎么把單元格設(shè)為金錢的形式啊!如¥100
    設(shè)置100,在excel中自動賦上¥100啊?  回復(fù)  更多評論
      
    # re: java操作Excel(Jakarta_POI) 2007-11-19 09:39 lk
    朋友! 不要要求太多,jxl沒提供這么全面的方法,它只提供了數(shù)字(number)、標簽(label)、日期(date)、布爾(boolean)幾種簡單的類型。

    你可以在程序里自己寫一下嘛!

    excel還是蠻強大的我已經(jīng)試過了,在excel里,你不設(shè)置單元格格式,只要你輸入了貨幣符號excel就會自動將該單元格設(shè)置成貨幣格式,在你需要的單元個里輸入值時用程序先加一個¥后面加錢數(shù)就OK了。

      回復(fù)  更多評論
      
    # re: java操作Excel(Jakarta_POI) 2007-11-22 21:13 victim
    是好東西``我也一直在用,不過有一個問題一直沒解決,不知道怎么設(shè)置打開時默認顯示指定工作表```  回復(fù)  更多評論
      
    # re: java操作Excel(Jakarta_POI) 2007-11-22 21:16 victim
    啊```不好意思``以解決`

    hwb.setSelectedTab((short)hwb.getSheetIndex(sheetName));  回復(fù)  更多評論
      
    # re: java操作Excel(Jakarta_POI) 2007-11-27 15:23 
    我使用的時候有個問題,我導(dǎo)出來在excel數(shù)字是顯示文本,但我只要雙擊那一格,里面的文本數(shù)字就變?yōu)閿?shù)值類型。例如文本的“350702198116117551”
    雙擊后就變?yōu)?.50702E+17,焦點離開后還是顯示3.50702E+17,而不是起先的350702198116117551 怎么在程序里設(shè)置完,雙擊不會變?yōu)閿?shù)值類型啊。
      回復(fù)  更多評論
      
    # re: java操作Excel(Jakarta_POI) 2007-12-01 15:35 tobe
    最近想做個讀取excel內(nèi)容存入數(shù)據(jù)庫的程序,用poi文本格式的已經(jīng)實現(xiàn),但是那個excel里的圖片不知道怎樣才能讀出來 ,請指教!  回復(fù)  更多評論
      
    # re: java操作Excel(Jakarta_POI) 2008-10-21 15:56 ufo
    我的excel中需要有幾個下拉框供用戶來選擇項目,為什么保存時若焦點在下拉框上時,上傳后就解析不出來呢,提示:
    org.apache.poi.hssf.record.RecordFormatException: Unable to construct record instance, the following exception occured: null
    at org.apache.poi.hssf.record.RecordFactory.createRecord(RecordFactory.java:90)
    at org.apache.poi.hssf.record.RecordFactory.createRecords(RecordFactory.java:45)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:50)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:81)
    at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:75)。
      回復(fù)  更多評論
      
    # re: java操作Excel(Jakarta_POI) 2012-10-16 12:36 
    我也遇到了這個問題,該怎么解決呢@ufo
      回復(fù)  更多評論
      
    主站蜘蛛池模板: 亚洲国产成人精品无码区在线网站| 久久国产亚洲精品麻豆| 亚洲精品无码久久毛片 | 国产精成人品日日拍夜夜免费| 一级毛片免费毛片一级毛片免费| 久久免费看黄a级毛片| 免费的一级片网站| 亚洲一区二区三区在线播放| 国产成人无码综合亚洲日韩| 亚洲成年人电影网站| 亚洲AV色无码乱码在线观看| 精品免费久久久久国产一区 | 国产一级在线免费观看| 7x7x7x免费在线观看| 永久免费视频v片www| 亚洲永久无码3D动漫一区| 亚洲神级电影国语版| 18禁亚洲深夜福利人口| 国产色无码精品视频免费| 国产成人免费网站| 亚洲午夜AV无码专区在线播放| 久久精品亚洲综合一品| 一区二区亚洲精品精华液| 亚欧洲精品在线视频免费观看| 67194国产精品免费观看| 日韩一级免费视频| 亚洲av永久无码精品表情包| 亚洲成a人不卡在线观看| 人人鲁免费播放视频人人香蕉| 97视频免费观看2区| 免费中文字幕一级毛片| 亚洲视频在线观看网址| 特级aa**毛片免费观看| 久视频精品免费观看99| 国产成人亚洲影院在线观看| 亚洲校园春色另类激情| 中文在线免费不卡视频| 免费无码黄网站在线观看| 亚洲国产一区二区三区青草影视 | 一级毛片无遮挡免费全部| 丁香花免费完整高清观看|