2010-04-20 13 views
15

पर एक पीओआई कार्यपुस्तिका स्ट्रीमिंग मैं अपने वेब सर्वर पर एक बहुत बड़ी पीओआई कार्यपुस्तिका का निर्माण करता हूं। स्मृति में पूरी कार्यपुस्तिका को पकड़ना, एकाधिक समवर्ती अनुरोधों के लिए स्केल नहीं करेगा। क्या कोई तरीका है कि मैं सर्वलेट आउटपुट स्ट्रीम में कार्यपुस्तिका को प्रगतिशील रूप से लिख सकता हूं। इससे प्रतिक्रिया समय कम हो सकता है, साथ ही प्रक्रिया मेमोरी को प्रभावी बना दिया जाना चाहिए।सर्वलेट आउटपुट स्ट्रीम

उत्तर

3

दुर्भाग्यवश, अनुक्रमिक डेटा का कोई मतलब नहीं होने पर यह असंभव है। मैं एक और प्रारूप की तलाश करने का सुझाव दूंगा, उदा। सीएसवी या एक्सएमएल। दोनों क्रमशः लिखा जा सकता है। यदि यह डीबी से आ रहा है, तो इसे और अधिक कुशल भी किया जा सकता है क्योंकि एक सभ्य डीबी ने उन प्रारूपों को कुशलता से निर्यात करने के लिए सुविधाओं का निर्माण किया है। आपको बस बाइट्स को एक तरफ से दूसरी तरफ स्ट्रीम करना होगा।

0

यदि आप JExcel का उपयोग करते हैं तो इसमें सर्वलेट से और उसके लिए स्ट्रीम कोड पढ़ने के लिए नमूना कोड है। http://jexcelapi.sourceforge.net/resources/faq/

इस एपीआई का एकमात्र नकारात्मक पक्ष ऐसा लगता है कि यह केवल एक्सेल 2003 के लिए समर्थन करता है।

पीओआई का उपयोग करना - क्या आप फ़ाइल नहीं बना सकते हैं और फ़ाइल के बाइट्स को सर्वलेट आउटपुट स्ट्रीम में सेवा दे सकते हैं?

+0

मैं सर्वलेट outputstream POI को कार्यपुस्तिका लिख ​​रहा हूँ:

यहाँ प्रलेखन से उदाहरण दिया गया है। दृश्यों के पीछे क्या होता है, क्या यह आउटपुटस्ट्रीम में थेट बाइट लिखता है। मेरा सवाल है, मुझे नहीं पता कि इसे कैसे प्रगतिशील तरीके से लिखना है। मुझे पूरी कार्यपुस्तिका बनने तक इंतजार करना है, और उसके बाद ही इसे I/O पर लिखें। और I/O को लिखने में लगभग एक मिनट लगते हैं। पता नहीं है कि यह उचित है या नहीं। –

+0

आपकी स्प्रेडशीट कितनी बड़ी है? क्या आप स्प्रेडशीट बनाते हैं, या यह आपको दिया जाता है? यदि यह आपको दिया गया है, तो क्या आप इसे संशोधित करते हैं? I/O को लिखने के लिए इतना समय क्यों ले रहा है? –

7

आप के बारे में Excel 2007 (xslx) उत्पन्न करने के लिए तो आप BigGridDemo.java के दृष्टिकोण खुद को अनुकूलित कर का वर्णन यहां हैं: http://web.archive.org/web/20110821054135/http://www.realdevelopers.com/blog/code/excel

समाधान POI एक टेम्पलेट केवल और धारा के रूप में एक कंटेनर xslx उत्पन्न जाने के लिए है एक ज़िप आउटपुट स्ट्रीम में एक्सएमएल के रूप में वास्तविक स्प्रेडशीट डेटा। एक्सएमएल पीढ़ी को सुव्यवस्थित करना आपके ऊपर है।

+0

यूआरएल समाप्त हो गया है, क्या आप इसे ठीक कर सकते हैं। – rohit

0

क्या आपने सीधे HttpServletResponse.getOutputStream() पर लिखने की विधि के साथ प्रयास किया था?

कृपया निम्न उदाहरण पर एक नज़र डालें:

HSSFWorkbook wb = new HSSFWorkbook(); 
HSSFSheet sheet = wb.createSheet("new sheet"); 
... 
OutputStream out = response.getOutputStream(); 
wb.write(out); 
out.close(); 
+2

-1 यह सवाल का जवाब नहीं देता है। ओपी स्पष्ट रूप से बताता है कि वह जिस मुद्दे को हल करने की कोशिश कर रहा है वह यह है कि सबकुछ बनाने से बचें और फिर इसे एक साथ लिखना कैसे है। – Ophidian

+0

-1 आप एक एक्सएलएक्स स्ट्रीम नहीं कर सकते हैं।ओपी की तरह ही – hellojava

+0

का उल्लेख किया गया है यह तब तक स्मृति में रहेगा जब तक कि सभी पंक्तियां wb पर लिखी न हों –

2

स्थिति में सुधार हुआ है काफी के बाद से उत्तर के बाकी लिखा गया था - स्ट्रीमिंग अब अपाचे पोई का हिस्सा है।

SXSSFWorkbook कक्षा, और documentation here देखें। यह शीट पर एक स्ट्रीमिंग विंडो का उपयोग करता है, जो खिड़की के बाहर पुरानी पंक्तियों को अस्थायी फ़ाइलों में फिसलता है।

यह BigGridDemo पर आधारित है hlg's answer में उपयोग किया गया दृष्टिकोण, लेकिन अब आधिकारिक वितरण का हिस्सा है।

public static void main(String[] args) throws Throwable { 
    // keep 100 rows in memory, exceeding rows will be flushed to disk 
    SXSSFWorkbook wb = new SXSSFWorkbook(100); 
    Sheet sh = wb.createSheet(); 
    for(int rownum = 0; rownum < 1000; rownum++){ 
     Row row = sh.createRow(rownum); 
     for(int cellnum = 0; cellnum < 10; cellnum++){ 
      Cell cell = row.createCell(cellnum); 
      String address = new CellReference(cell).formatAsString(); 
      cell.setCellValue(address); 
     } 

    } 

    // Rows with rownum < 900 are flushed and not accessible 
    for(int rownum = 0; rownum < 900; rownum++){ 
     Assert.assertNull(sh.getRow(rownum)); 
    } 

    // ther last 100 rows are still in memory 
    for(int rownum = 900; rownum < 1000; rownum++){ 
     Assert.assertNotNull(sh.getRow(rownum)); 
    } 

    FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx"); 
    wb.write(out); 
    out.close(); 

    // dispose of temporary files backing this workbook on disk 
    wb.dispose(); 
} 
संबंधित मुद्दे