Java操作Excel文件的兩種方案

微軟在桌面系統上的成功,令我們不得不大量使用它的辦公產品,如:Word,Excel。時至今日,它的源代碼仍然不公開已封鎖了我們的進一步應用和開發。在我們實際開發企業辦公系統的過程中,常常有客戶這樣子要求:你要把我們的報表直接用Excel打開。或者是:我們已經習慣用Excel打印。但是這種的客戶需求在j2ee環境的環境下怎麼實現?

一.Java用POI操作Excel文件

  Apache的Jakata項目的POI子項目的HSSF接口可以處理MS Excel(97-2002)對象。它不象我們僅僅是用csv生成的沒有格式的可以由Excel轉換的東西,而是真正的Excel對象,你可以控制一些屬性如sheet,cell等等。另外,無錫永中Office的實現方案也是純java的解決方案,不過那也是完全商業的產品,並不是公開代碼項目。其實,從開發歷史的角度講,在80年代中期starOffice的原作者在德國成立了StarOffice suite公司,然後到1999年夏天starOffice被sun收購,再到2000年6月starOffice5.2的發佈;並且從starOffice6.0開始,starOffice建立在OpenOffice的api的基礎上,這個公開代碼的office項目已經進行了很長的時間。雖然那是由C++寫的,但是POI的代碼部分也是由openOffice改過來的。

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 錯誤信息表

複製代碼
//利用Java 創建Excel文檔
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);
        //設置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樣式
        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("workbook.xls");
        wb.write(fileOut);
        fileOut.close();
    }
}
複製代碼

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

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

  因爲POI還不是一個足夠成熟的項目,所以有必要做進一步的開發和測試,確認生成的Excel是否能滿足用戶挑剔的需求。

二.Java用PageOffice操作Excel文件

  PageOffice是一個實踐了分佈式計算設計思想的組件,提供的方案並不是純服務器端的Excel解決方案,對文件的處理放到了客戶端來進行。用PageOffice開發需要的引入的文件只需一個pageoffice4.4.0.3.jar(以具體的jar版的版本號爲準)。畢竟是商業軟件,提供的編程接口簡潔高效。針對excel文件生成的類是:com.zhuozhengsoft.pageoffice.excelwriter

類摘要

Border

Border 類,代表Excel中定義的邊框對象。

Cell

Cell 類,代表Excel中定義的單元格對象,用來填充單元格數據及控制單元格格式。

DataField

DataField 類,代表PageOffice中定義的Excel表格對象裏的字段對象。

DataFieldCollection

DataField 字段集合,代表 com.zhuozhengsoft.pageoffice.excelwriter.Table 中當前記錄行。

Font

Font 類,代表Excel中定義的字體對象。

Sheet

Sheet 類,代表Excel中定義的工作表對象。

Table

Table 類,代表PageOffice中定義的Excel表格對象。

Workbook

Workbook 類代表一個Excel文檔,用來動態輸出數據到Excel文檔並且控制其表格格式及編輯功能。

 

  excelwriter類生成excel文件的效果可以在官方提供的Sample4包裏找到。以下是PageOffice官方示例代碼中提供的一個完全用程序生成預算表的demo的源代碼,演示了針對Excel文檔生成所提供的大部分接口。

  

複製代碼
    Workbook wb = new Workbook();
    // 設置背景
    Table backGroundTable = wb.openSheet("Sheet1").openTable("A1:P200");
    backGroundTable.getBorder().setLineColor(Color.white);

    // 設置標題
    wb.openSheet("Sheet1").openTable("A1:H2").merge();//合併單元格
    //打開表格並設置表格的行高
    wb.openSheet("Sheet1").openTable("A1:H2").setRowHeight(30);
    Cell A1 = wb.openSheet("Sheet1").openCell("A1");
    //設置單元格的水平對齊方式
    A1.setHorizontalAlignment(XlHAlign.xlHAlignCenter);
    //設置單元格的垂直對齊方式
    A1.setVerticalAlignment(XlVAlign.xlVAlignCenter);
    //設置單元格的前景色
    A1.setForeColor(new Color(0, 128, 128));
    //給單元格賦值
    A1.setValue("出差開支預算");
    
    //設置字體:加粗、大小
    wb.openSheet("Sheet1").openTable("A1:A1").getFont().setBold(true);
    wb.openSheet("Sheet1").openTable("A1:A1").getFont().setSize(25);
    
    // 畫表頭    
    Border C4Border = wb.openSheet("Sheet1").openTable("C4:C4").getBorder();
    //設置表格邊框的寬度、顏色
    C4Border.setWeight(XlBorderWeight.xlThick);
    C4Border.setLineColor(Color.yellow);
    
    Table titleTable = wb.openSheet("Sheet1").openTable("B4:H5");
    //設置表格邊框的樣式、寬度、顏色
    titleTable.getBorder().setBorderType(XlBorderType.xlAllEdges);
    titleTable.getBorder().setWeight(XlBorderWeight.xlThick);
    titleTable.getBorder().setLineColor(new Color(0, 128, 128));
    
    // 畫表體
    Table bodyTable = wb.openSheet("Sheet1").openTable("B6:H15");
    bodyTable.getBorder().setLineColor(Color.gray);
    bodyTable.getBorder().setWeight(XlBorderWeight.xlHairline);

    Border B7Border = wb.openSheet("Sheet1").openTable("B7:B7").getBorder();
    B7Border.setLineColor(Color.white);

    Border B9Border = wb.openSheet("Sheet1").openTable("B9:B9").getBorder();
    B9Border.setBorderType(XlBorderType.xlBottomEdge);
    B9Border.setLineColor(Color.white);

    Border C6C15BorderLeft = wb.openSheet("Sheet1").openTable("C6:C15").getBorder();
    C6C15BorderLeft.setLineColor(Color.white);
    C6C15BorderLeft.setBorderType(XlBorderType.xlLeftEdge);
    
    Border C6C15BorderRight = wb.openSheet("Sheet1").openTable("C6:C15").getBorder();
    C6C15BorderRight.setLineColor(Color.yellow);
    C6C15BorderRight.setLineStyle(XlBorderLineStyle.xlDot);
    C6C15BorderRight.setBorderType(XlBorderType.xlRightEdge);

    Border E6E15Border = wb.openSheet("Sheet1").openTable("E6:E15").getBorder();
    E6E15Border.setLineStyle(XlBorderLineStyle.xlDot);
    E6E15Border.setBorderType(XlBorderType.xlAllEdges);
    E6E15Border.setLineColor(Color.yellow);

    Border G6G15BorderRight = wb.openSheet("Sheet1").openTable("G6:G15").getBorder();
    G6G15BorderRight.setBorderType(XlBorderType.xlRightEdge);
    G6G15BorderRight.setLineColor(Color.white);

    Border G6G15BorderLeft = wb.openSheet("Sheet1").openTable("G6:G15").getBorder();
    G6G15BorderLeft.setLineStyle(XlBorderLineStyle.xlDot);
    G6G15BorderLeft.setBorderType(XlBorderType.xlLeftEdge);
    G6G15BorderLeft.setLineColor(Color.yellow);

    Table bodyTable2 = wb.openSheet("Sheet1").openTable("B6:H15");
    bodyTable2.getBorder().setWeight(XlBorderWeight.xlThick);
    bodyTable2.getBorder().setLineColor(new Color(0, 128, 128));
    bodyTable2.getBorder().setBorderType(XlBorderType.xlAllEdges);

    // 畫表尾
    Border H16H17Border = wb.openSheet("Sheet1").openTable("H16:H17").getBorder();
    H16H17Border.setLineColor(new Color(204, 255, 204));

    Border E16G17Border = wb.openSheet("Sheet1").openTable("E16:G17").getBorder();
    E16G17Border.setLineColor(new Color(0, 128, 128));

    Table footTable = wb.openSheet("Sheet1").openTable("B16:H17");
    footTable.getBorder().setWeight(XlBorderWeight.xlThick);
    footTable.getBorder().setLineColor(new Color(0, 128, 128));
    footTable.getBorder().setBorderType(XlBorderType.xlAllEdges);

    // 設置行高列寬
    wb.openSheet("Sheet1").openTable("A1:A1").setColumnWidth(1);
    wb.openSheet("Sheet1").openTable("B1:B1").setColumnWidth(20);
    wb.openSheet("Sheet1").openTable("C1:C1").setColumnWidth(15);
    wb.openSheet("Sheet1").openTable("D1:D1").setColumnWidth(10);
    wb.openSheet("Sheet1").openTable("E1:E1").setColumnWidth(8);
    wb.openSheet("Sheet1").openTable("F1:F1").setColumnWidth(3);
    wb.openSheet("Sheet1").openTable("G1:G1").setColumnWidth(12);
    wb.openSheet("Sheet1").openTable("H1:H1").setColumnWidth(20);

    wb.openSheet("Sheet1").openTable("A16:A16").setRowHeight(20);
    wb.openSheet("Sheet1").openTable("A17:A17").setRowHeight(20);

    // 設置表格中字體大小爲10
    for (int i = 0; i < 12; i++) {//excel表格行號
        for (int j = 0; j < 7; j++) {//excel表格列號
            wb.openSheet("Sheet1").openCellRC(4 + i, 2 + j).getFont().setSize(10);
        }
    }

    // 填充單元格背景顏色
    for (int i = 0; i < 10; i++) {
        wb.openSheet("Sheet1").openCell("H" + (6 + i)).setBackColor(new Color(255, 255, 153));
    }

    wb.openSheet("Sheet1").openCell("E16").setBackColor(new Color(0, 128, 128));
    wb.openSheet("Sheet1").openCell("F16").setBackColor(new Color(0, 128, 128));
    wb.openSheet("Sheet1").openCell("G16").setBackColor(new Color(0, 128, 128));
    wb.openSheet("Sheet1").openCell("E17").setBackColor(new Color(0, 128, 128));
    wb.openSheet("Sheet1").openCell("F17").setBackColor(new Color(0, 128, 128));
    wb.openSheet("Sheet1").openCell("G17").setBackColor(new Color(0, 128, 128));
    wb.openSheet("Sheet1").openCell("H16").setBackColor(new Color(204, 255, 204));
    wb.openSheet("Sheet1").openCell("H17").setBackColor(new Color(204, 255, 204));

    //填充單元格文本和公式
    Cell B4 = wb.openSheet("Sheet1").openCell("B4");
    B4.getFont().setBold(true);
    B4.setValue("出差開支預算");
    Cell H5 = wb.openSheet("Sheet1").openCell("H5");
    H5.getFont().setBold(true);
    H5.setValue("總計");
    H5.setHorizontalAlignment(XlHAlign.xlHAlignCenter);
    Cell B6 = wb.openSheet("Sheet1").openCell("B6");
    B6.getFont().setBold(true);
    B6.setValue("飛機票價");
    Cell B9 = wb.openSheet("Sheet1").openCell("B9");
    B9.getFont().setBold(true);
    B9.setValue("酒店");
    Cell B11 = wb.openSheet("Sheet1").openCell("B11");
    B11.getFont().setBold(true);
    B11.setValue("餐飲");
    Cell B12 = wb.openSheet("Sheet1").openCell("B12");
    B12.getFont().setBold(true);
    B12.setValue("交通費用");
    Cell B13 = wb.openSheet("Sheet1").openCell("B13");
    B13.getFont().setBold(true);
    B13.setValue("休閒娛樂");
    Cell B14 = wb.openSheet("Sheet1").openCell("B14");
    B14.getFont().setBold(true);
    B14.setValue("禮品");
    Cell B15 = wb.openSheet("Sheet1").openCell("B15");
    B15.getFont().setBold(true);
    B15.getFont().setSize(10);
    B15.setValue("其他費用");

    wb.openSheet("Sheet1").openCell("C6").setValue("機票單價(往)");
    wb.openSheet("Sheet1").openCell("C7").setValue("機票單價(返)");
    wb.openSheet("Sheet1").openCell("C8").setValue("其他");
    wb.openSheet("Sheet1").openCell("C9").setValue("每晚費用");
    wb.openSheet("Sheet1").openCell("C10").setValue("其他");
    wb.openSheet("Sheet1").openCell("C11").setValue("每天費用");
    wb.openSheet("Sheet1").openCell("C12").setValue("每天費用");
    wb.openSheet("Sheet1").openCell("C13").setValue("總計");
    wb.openSheet("Sheet1").openCell("C14").setValue("總計");
    wb.openSheet("Sheet1").openCell("C15").setValue("總計");

    wb.openSheet("Sheet1").openCell("G6").setValue("  張");
    wb.openSheet("Sheet1").openCell("G7").setValue("  張");
    wb.openSheet("Sheet1").openCell("G9").setValue("  晚");
    wb.openSheet("Sheet1").openCell("G10").setValue("  晚");
    wb.openSheet("Sheet1").openCell("G11").setValue("  天");
    wb.openSheet("Sheet1").openCell("G12").setValue("  天");

    //設置單元格包含的公式
    wb.openSheet("Sheet1").openCell("H6").setFormula("=D6*F6");
    wb.openSheet("Sheet1").openCell("H7").setFormula("=D7*F7");
    wb.openSheet("Sheet1").openCell("H8").setFormula("=D8*F8");
    wb.openSheet("Sheet1").openCell("H9").setFormula("=D9*F9");
    wb.openSheet("Sheet1").openCell("H10").setFormula("=D10*F10");
    wb.openSheet("Sheet1").openCell("H11").setFormula("=D11*F11");
    wb.openSheet("Sheet1").openCell("H12").setFormula("=D12*F12");
    wb.openSheet("Sheet1").openCell("H13").setFormula("=D13*F13");
    wb.openSheet("Sheet1").openCell("H14").setFormula("=D14*F14");
    wb.openSheet("Sheet1").openCell("H15").setFormula("=D15*F15");

    for (int i = 0; i < 10; i++) {
        //設置數據以貨幣形式顯示
        wb.openSheet("Sheet1").openCell("D" + (6 + i)).setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
        wb.openSheet("Sheet1").openCell("H" + (6 + i)).setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    }

    Cell E16 = wb.openSheet("Sheet1").openCell("E16");
    E16.getFont().setBold(true);
    E16.getFont().setSize(11);
    E16.setForeColor(Color.white);
    E16.setValue("出差開支總費用");
    E16.setVerticalAlignment(XlVAlign.xlVAlignCenter);
    Cell E17 = wb.openSheet("Sheet1").openCell("E17");
    E17.getFont().setBold(true);
    E17.getFont().setSize(11);
    E17.setForeColor(Color.white);
    E17.setFormula("=IF(C4>H16,\"低於預算\",\"超出預算\")");
    E17.setVerticalAlignment(XlVAlign.xlVAlignCenter);
    Cell H16 = wb.openSheet("Sheet1").openCell("H16");
    H16.setVerticalAlignment(XlVAlign.xlVAlignCenter);
    H16.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    H16.getFont().setName("Arial");
    H16.getFont().setSize(11);
    H16.getFont().setBold(true);
    H16.setFormula("=SUM(H6:H15)");
    Cell H17 = wb.openSheet("Sheet1").openCell("H17");
    H17.setVerticalAlignment(XlVAlign.xlVAlignCenter);
    H17.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    H17.getFont().setName("Arial");
    H17.getFont().setSize(11);
    H17.getFont().setBold(true);
    H17.setFormula("=(C4-H16)");

    // 填充數據
    Cell C4 = wb.openSheet("Sheet1").openCell("C4");
    C4.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    C4.setValue("2500");
    Cell D6 = wb.openSheet("Sheet1").openCell("D6");
    D6.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    D6.setValue("1200");
    wb.openSheet("Sheet1").openCell("F6").getFont().setSize(10);
    wb.openSheet("Sheet1").openCell("F6").setValue("1");
    Cell D7 = wb.openSheet("Sheet1").openCell("D7");
    D7.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    D7.setValue("875");
    wb.openSheet("Sheet1").openCell("F7").setValue("1");

    //打開文件
    PageOfficeCtrl poCtrl1 = new PageOfficeCtrl(request);
    poCtrl1.setWriter(wb);
    poCtrl1.setServerPage("poserver.do");
    poCtrl1.webOpen("doc/test.xls", OpenModeType.xlsNormalEdit, "");
複製代碼

 

  可能有人會說上面的代碼有點多,編程工作量大,但是當你對比一下方案一中POI生成的那個表格和這個demo中生成的表格用多大的差別,就不會有這種感覺。上面的代碼生成的文件效果如下圖所示:

  

  

  就生成這個預算表來說,換用其他的任何組件來實現(包括開源和非開源的,當然也包括POI)都很難想象要寫多少行代碼。作爲任何一個系統的開發人員工作的重點都應該放在具體的業務邏輯上,把大量的精力和編碼工作放在用程序實現表格的繪製其實是很不明智,這個demo也只是展示了一下PageOffice是可以這樣做的,但還有更好的、任何開源組件都沒有或處理不好的方法,那就是使用現有的Excel文件模板。從上面的例子可以看出PageOffice 給excel單元格賦值,也可以賦值公式,所以最好的辦法就是對用戶現有的excel模板編程,直接對單元格賦值數據和公式,代碼量會急速的減少,同樣是生成上面的一個預算表,如果模板是下面這樣的:

  

  那麼編寫的代碼就只剩下填充數據的代碼了:

  

複製代碼
    Workbook wb = new Workbook();
    //填充單元格文本和公式
    B6.setValue("飛機票價");
    Cell B9 = wb.openSheet("Sheet1").openCell("B9");
    B9.getFont().setBold(true);
    B9.setValue("酒店");
    Cell B11 = wb.openSheet("Sheet1").openCell("B11");
    B11.getFont().setBold(true);
    B11.setValue("餐飲");
    Cell B12 = wb.openSheet("Sheet1").openCell("B12");
    B12.getFont().setBold(true);
    B12.setValue("交通費用");
    Cell B13 = wb.openSheet("Sheet1").openCell("B13");
    B13.getFont().setBold(true);
    B13.setValue("休閒娛樂");
    Cell B14 = wb.openSheet("Sheet1").openCell("B14");
    B14.getFont().setBold(true);
    B14.setValue("禮品");
    Cell B15 = wb.openSheet("Sheet1").openCell("B15");
    B15.getFont().setBold(true);
    B15.getFont().setSize(10);
    B15.setValue("其他費用");

    wb.openSheet("Sheet1").openCell("C6").setValue("機票單價(往)");
    wb.openSheet("Sheet1").openCell("C7").setValue("機票單價(返)");
    wb.openSheet("Sheet1").openCell("C8").setValue("其他");
    wb.openSheet("Sheet1").openCell("C9").setValue("每晚費用");
    wb.openSheet("Sheet1").openCell("C10").setValue("其他");
    wb.openSheet("Sheet1").openCell("C11").setValue("每天費用");
    wb.openSheet("Sheet1").openCell("C12").setValue("每天費用");
    wb.openSheet("Sheet1").openCell("C13").setValue("總計");
    wb.openSheet("Sheet1").openCell("C14").setValue("總計");
    wb.openSheet("Sheet1").openCell("C15").setValue("總計");

    wb.openSheet("Sheet1").openCell("G6").setValue("  張");
    wb.openSheet("Sheet1").openCell("G7").setValue("  張");
    wb.openSheet("Sheet1").openCell("G9").setValue("  晚");
    wb.openSheet("Sheet1").openCell("G10").setValue("  晚");
    wb.openSheet("Sheet1").openCell("G11").setValue("  天");
    wb.openSheet("Sheet1").openCell("G12").setValue("  天");
// 填充數據
    Cell C4 = wb.openSheet("Sheet1").openCell("C4");
    C4.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    C4.setValue("2500");
    Cell D6 = wb.openSheet("Sheet1").openCell("D6");
    D6.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    D6.setValue("1200");
    wb.openSheet("Sheet1").openCell("F6").getFont().setSize(10);
    wb.openSheet("Sheet1").openCell("F6").setValue("1");
    Cell D7 = wb.openSheet("Sheet1").openCell("D7");
    D7.setNumberFormatLocal("¥#,##0.00;¥-#,##0.00");
    D7.setValue("875");
    wb.openSheet("Sheet1").openCell("F7").setValue("1");
複製代碼

  

  這就變成了一個簡單的工作量的問題,不需要絞盡腦汁去計算怎麼繪製表格才更合理,才能實現效果。

  就視覺效果來說,PageOffice處理生成的表格,不管是表格邊框的處理,還是單元格背景色,或者字體和對齊方式等等都處理的非常好,尤其對Excel公式的支持更是可圈可點,就這個功能,一般用戶想要的結構比較複雜的報表都可以實現。

       從性能上看,文件生成的速度飛快,幾乎是瞬間完成,還同時實現了文件在線打開、是否只讀和打印的控制。

  兩種方案的選擇:對於客戶端數量小的系統,如果也不需要文件的在線的打開查看或編輯打印(PageOffice生成文件時可以有界面,也可以沒有界面,不要被我上面說的那個例子誤導),那麼可以使用POI。當可能會出現大量客戶端併發訪問或同時處理多個大文件時, POI需要大量佔用服務器內存,由於Word文檔固有的複雜度,POI會大量佔用CPU時間,寫入時長時間佔用磁盤文件,會導致網頁反應速度下降、阻塞現象的發生,還是選擇使用PageOffice。畢竟PageOffice是商業軟件是收費的,根據具體的項目需求選擇不同的方案更實際。

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