2010-03-23 33 views
17

Tôi đang sử dụng POI trong ứng dụng web J2EE của mình để tạo sổ làm việc. Tuy nhiên, tôi thấy rằng POI mất khoảng 3 phút để tạo ra một bảng tính với 25K hàng (với khoảng 15 cột mỗi). Đây có phải là vấn đề về hiệu suất POI hay không? Có các API khác được biết đến để có hiệu suất tốt hơn không?Hiệu suất POI

+0

@Gugusse, chấp nhận câu trả lời là một chỉ báo cho những người đọc câu hỏi gì _asker_ coi là câu trả lời đúng đến/vấn đề thực tế của mình. Đó là một phần thông tin rất quan trọng. Điều đó nói rằng, bất kỳ lý do bạn không bình luận sự cần thiết cho người hỏi để cung cấp một đoạn mã tối thiểu cho thấy hành vi được mô tả? –

+0

@Gugussee, anh ta chỉ đoán thôi. Lý do thực tế có thể là bất cứ điều gì, mà mẫu mã sẽ hiển thị ngay lập tức. Nó sẽ là hợp lý để đề nghị bạn cải thiện siêu cảnh sát của bạn? –

+0

@ Thorbjørn Ravn Andersen: Nó có hợp lý để đề nghị bạn cải thiện meta-meta-policing của bạn? ;) – Gugussee

Trả lời

12

Tôi sẽ rất ngạc nhiên khi thấy POI mất nhiều thời gian để tạo một tệp như vậy. Tôi vừa tạo một trang tính với 30000 hàng x 10 ô trong khoảng 18 giây (không định dạng, công bằng). Nguyên nhân có thể là một trong những cách sau:

  • POI khai thác gỗ có thể được bật lên, như mô tả here
  • bạn đang chạy từ bộ nhớ swap
  • đống sẵn VM của bạn có thể rất thấp
+0

Sẽ có các ký tự quốc tế làm cho việc xử lý chậm hơn? Và một câu hỏi khác, làm thế nào để tăng bộ nhớ VM cải thiện hiệu năng? –

+0

Tôi không tin rằng các ký tự quốc tế sẽ làm cho loại xử lý này chậm hơn: phần lớn là về lượng dữ liệu. Đối với máy ảo có sẵn, vì số lượng bộ nhớ cần thiết đến gần đống có sẵn, bộ thu gom rác phải khởi động thường xuyên hơn: trong trường hợp cực đoan, phần lớn thời gian CPU được dùng để thu gom rác. Đây là một tình huống cụ thể: nó không có khả năng bạn bị ảnh hưởng đáng kể bởi nó. –

+3

trong kinh nghiệm của tôi POI là kinda chậm và nếu POI cần một tải *** của bộ nhớ hoặc cần đăng nhập để được tắt, sau đó nó chắc chắn ** là ** một vấn đề POI. Chúng tôi tạo ra các báo cáo bằng cách sử dụng POI và ngay khi chúng tôi tạo ra nhiều hơn một vài bảng tính, nó trở nên rất chậm. Ngoài ra, 30000 hàng x 10 tế bào thực sự là một lượng nhỏ dữ liệu nhỏ cho một CPU thực hiện hàng tỷ chu kỳ mỗi giây. Vì vậy, yup, POI là một API khá chậm. – Gugussee

1

Chúng tôi cũng sử dụng POI trong ứng dụng web của chúng tôi và không có bất kỳ vấn đề hiệu suất nào với nó - mặc dù tài liệu được tạo của chúng tôi nhỏ hơn nhiều so với tài liệu của bạn. Trước tiên tôi sẽ kiểm tra xem POI có phải là vấn đề thực sự ở đây hay không. Cố gắng tạo ra các tài liệu đó mà không có J2EE-overhead (Unit-Test) và đo hiệu suất. Bạn cũng có thể theo dõi tải và sử dụng bộ nhớ trên máy chủ J2EE của bạn để xem liệu các vấn đề đến từ một số cài đặt hệ thống tối ưu.

3

Nếu không có câu trả lời nào khác hiệu quả, hãy xem JExcel của Andy Khan có tốt hơn không. Tôi đã tìm thấy nó vượt trội so với POI để xử lý Excel trong Java.

1

Tôi đã so sánh Apache POI với thư viện JExcel. Dường như JExcel là về lên đến 4x nhanh hơn Apache POI nhưng tiêu thụ bộ nhớ có vẻ là nhiều hơn hoặc ít hơn như nhau:

@Test 
public void createJExcelWorkbook() throws Exception { 
     WritableWorkbook workbook = Workbook.createWorkbook(new File("jexcel_workbook.xls")); 
     WritableSheet sheet = workbook.createSheet("sheet", 0); 
     for (int i=0; i < 65535; i++) { 
      for (int j=0; j < 10; j++) { 
       Label label = new Label(j, i, "some text " + i + " " + j); 
       sheet.addCell(label); 
      } 
     } 
     workbook.write(); 
     workbook.close(); 
} 

@Test 
public void createPoiWorkbook() throws Exception { 
    Workbook wb = new HSSFWorkbook(); 
    Sheet sheet = wb.createSheet("sheet"); 
    for (int i=0; i < 65535; i++) { 
     Row row = sheet.createRow(i); 
     for (int j=0; j < 10; j++) { 
      Cell cell = row.createCell(j); 
      cell.setCellValue("some text " + i + " " + j); 
     } 
    } 
    FileOutputStream fileOut = new FileOutputStream("poi_workbook.xls"); 
    wb.write(fileOut); 
    fileOut.close(); 
} 

Tôi đã thử nghiệm nó với JExcel phiên bản 2.6.12 và Apache POI phiên bản 3.7. Bạn cần tự mình tải xuống các phiên bản thư viện mới nhất và chạy các thử nghiệm đơn giản ở trên để có số liệu chính xác hơn.

<dependency org="org.apache.poi" name="poi" rev="3.7"/> 
<dependency org="net.sourceforge.jexcelapi" name="jxl" rev="2.6.12"/> 

Lưu ý: có một giới hạn trong Apache POI của 65535 hàng trên mỗi tờ.

+4

Giới hạn hàng là giới hạn định dạng tệp .xls của Excel, không phải là giới hạn POI. Nếu bạn sử dụng định dạng tệp .xlsx (sử dụng XSSF từ Apache POI) thì bạn có thể tạo thêm hàng – Gagravarr

9

Hiệu suất ghi tệp lớn với POI có thể bị giảm đáng kể nếu bạn sử dụng API POI 'trực tuyến' thay vì API chuẩn. Thật vậy theo mặc định POI sẽ giữ tất cả dữ liệu của bạn trong bộ nhớ trước khi viết tất cả trong một đi vào cuối. Dấu chân bộ nhớ của điều này có thể rất lớn đối với các tệp lớn. Thay vào đó, sử dụng API truyền trực tuyến, bạn có thể kiểm soát cách sử dụng bộ nhớ và dữ liệu được ghi vào đĩa liên tục.

Để tạo ra một luồng workbook, sử dụng một cái gì đó như:

SXSSFWorkbook book = new SXSSFWorkbook(); 
    book.setCompressTempFiles(true); 

    SXSSFSheet sheet = (SXSSFSheet) book.createSheet(); 
    sheet.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk 
    // ...