2011-02-04 27 views
28

मुझे बड़ी पंक्तियों (30k + पंक्तियों) xlsx फ़ाइल में सभी पंक्तियों को स्वत: फिट करने की आवश्यकता है।प्रसंस्करण बड़ी xlsx फ़ाइल

Apache POI के माध्यम से निम्नलिखित कोड छोटे फ़ाइलों पर काम करता है, लेकिन बड़े लोगों पर OutOfMemoryError साथ बाहर चला जाता है:

Workbook workbook = WorkbookFactory.create(inputStream); 
Sheet sheet = workbook.getSheetAt(0); 

for (Row row : sheet) { 
    row.setHeight((short) -1); 
} 

workbook.write(outputStream); 

अद्यतन: दुर्भाग्य से, ढेर आकार में वृद्धि एक विकल्प नहीं है - OutOfMemoryError-Xmx1024m दिखाई देता है और 30k पंक्तियां ऊपरी सीमा नहीं है।

+0

आप इस कोड को कहां चला रहे हैं? ऐप/वेब सर्वर या स्टैंडअलोन के अंदर? – JSS

+0

मैं इसे टॉमकैट 6.0 – miah

+0

के अंदर चला रहा हूं क्या स्टार्टअप पर टॉमकैट को डिफ़ॉल्ट मेमोरी असाइन की गई है? – JSS

उत्तर

31

ईवेंट API का उपयोग करने का प्रयास करें। विवरण के लिए पीओआई दस्तावेज में Event API (HSSF only) और XSSF and SAX (Event API) देखें। उस पृष्ठ से उद्धरण के एक जोड़े:

HSSF:

The event API is newer than the User API. It is intended for intermediate developers who are willing to learn a little bit of the low level API structures. Its relatively simple to use, but requires a basic understanding of the parts of an Excel file (or willingness to learn). The advantage provided is that you can read an XLS with a relatively small memory footprint.

XSSF:

If memory footprint is an issue, then for XSSF, you can get at the underlying XML data, and process it yourself. This is intended for intermediate developers who are willing to learn a little bit of low level structure of .xlsx files, and who are happy processing XML in java. Its relatively simple to use, but requires a basic understanding of the file structure. The advantage provided is that you can read a XLSX file with a relatively small memory footprint.

उत्पादन के लिए, एक संभव दृष्टिकोण ब्लॉग पोस्ट Streaming xlsx files में वर्णित है। (मूल रूप से, एक कंटेनर एक्सएमएल फ़ाइल उत्पन्न करने के लिए एक्सएसएसएफ का उपयोग करें, फिर वास्तविक सामग्री को xlsx ज़िप संग्रह के उचित xml भाग में सादा पाठ के रूप में स्ट्रीम करें।)

+1

हाय भी बड़ी एक्सेल फ़ाइलों को पढ़ने की एक ही समस्या है। स्मृति मुद्दों से बाहर निकलना। मैंने http://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api देखा है और यह एक्सेल फ़ाइलों को पढ़ने के लिए निर्दिष्ट नहीं करता है। कृपया मदद करे। – ashishjmeshram

+0

@ आशीष: कृपया अधिक जानकारी के साथ स्टैक ओवरफ़्लो पर एक अलग प्रश्न के रूप में अपना अनुरोध पोस्ट करें। इस तरह, अन्य उपयोगकर्ता भी आपकी मदद कर सकते हैं। – markusk

+0

बड़ी एक्सेल फ़ाइलों को पढ़ने के लिए आप इस छोटी और सरल लाइब्रेरी पर एक नज़र डाल सकते हैं: https://github.com/davidpelfree/sjxlsx –

1

मैंने एक एचएसएसएफ फ़ाइल (.xls) के लिए इवेंट एपीआई का उपयोग किया, और मैंने रिकॉर्ड के आदेश के बारे में दस्तावेज की भयानक कमी की खोज की।

+0

मुझे पता है कि यह पुराना है: लेकिन क्या आपको एचएसएसएफ में घटनाओं के क्रम के बारे में कुछ मिला और/या एक्सएसएसएफ? – cripox

0

यहां एक उदाहरण है जो मैंने पाया है कि बहुत बड़ी एक्सएलएसएक्स फाइलों को संभालेगा। मेरा परीक्षण अब तक अच्छा दिखता है। यह स्मृति समस्याओं के बिना बहुत बड़ी फ़ाइलों को संभालने में सक्षम है।

http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java

+3

बस एक लिंक जोड़ना इतना उपयोगी नहीं है, क्या आप इस उत्तर में कम से कम एक सारांश ले सकते हैं? –

3

मैं पंक्ति का एक बहुत कम है, लेकिन बड़े तार के साथ एक ही समस्या हो रही थी।

चूंकि मुझे अपना डेटा लोड नहीं करना है, इसलिए मुझे पता चला कि मैं एक्सएसएसएफ के बजाय एसएक्सएसएसएफ का उपयोग कर सकता हूं।

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

यहां लिंक है। http://poi.apache.org/spreadsheet/how-to.html#sxssf

10

स्मृति उपयोग में नाटकीय सुधार स्ट्रीम के बजाय फ़ाइल का उपयोग करके किया जा सकता है। (यह एक स्ट्रीमिंग एपीआई का उपयोग करने के लिए बेहतर है, लेकिन स्ट्रीमिंग एपीआई सीमाएं हैं, http://poi.apache.org/spreadsheet/index.html देखें)

बजाय

Workbook workbook = WorkbookFactory.create(inputStream); 

की कर

Workbook workbook = WorkbookFactory.create(new File("yourfile.xlsx")); 

इस के अनुसार: http://poi.apache.org/spreadsheet/quick-guide.html#FileInputStream

फ़ाइलें बनाम इनपुटस्ट्रीम

"कार्यपुस्तिका खोलते समय, या तो एक .xls HSSFWorkbook, या .xlsx XSSFWorkbook, कार्यपुस्तिका को फ़ाइल या इनपुटस्ट्रीम से लोड किया जा सकता है।एक फ़ाइल वस्तु कम स्मृति की खपत के लिए अनुमति देता है का उपयोग के रूप में यह पूरी फ़ाइल बफ़र होना है, जबकि एक InputStream अधिक स्मृति की आवश्यकता है। "

+0

यह मुझे एक त्रुटि बताता है: 'पकड़ा गया: java.lang.LinkageError: लोडर बाधा उल्लंघन: इंटरफ़ेस विधि को हल करते समय "org.xml.sax.XMLReader.setEntityResolver (लॉर्ग/xml/sax/EntityResolver;) V" वर्ग लोडर (विधि वर्ग परिभाषा वर्ग, संगठन/xml/sax/XMLReader के लिए वर्तमान वर्ग, संगठन/dom4j/io/SAXReader, और वर्ग लोडर ( का उदाहरण) के संगठन/ कोडहॉस/ग्रोवी/टूल्स/रूटलोडर) का उदाहरण, हस्ताक्षर में उपयोग किए गए प्रकार org/xml/sax/EntityResolver के लिए अलग-अलग C लस ऑब्जेक्ट्स हैं 'मैं 'poi-3.9' – kiltek

+1

@rjdkolb का उपयोग कर रहा हूं, क्या आप मेरी पोस्ट https://stackoverflow.com/questions/48772021/how देख सकते हैं करने वाली हल-जावा-ढेर-अंतरिक्ष त्रुटि जबकि लोडिंग-बड़े xls-फ़ाइल-का उपयोग कर-पो – Mandrek

0

आप लेखन xlsx के लिए कर रहे हैं, मैं के विभिन्न शीट को लिख कर एक सुधार पाया एक ही एक्सेल फ़ाइल। आपको विभिन्न एक्सेल फ़ाइलों को लिखकर भी सुधार मिल सकता है। लेकिन पहले विभिन्न चादरों को लिखने का प्रयास करें।

2

यदि आप शैलियों को ऑटो-फिट या सेट करना चाहते हैं या बड़ी पंक्तियों (30k + पंक्तियां) xlsx में सभी पंक्तियां लिखना चाहते हैं फ़ाइल, SXSSFWorkbook का उपयोग करें। यहां नमूना कोड है जो आपको मदद करता है ...

SXSSFWorkbook wb = new SXSSFWorkbook(); 
      SXSSFSheet sheet = (SXSSFSheet) wb.createSheet("writetoexcel"); 
      Font font = wb.createFont(); 
       font.setBoldweight((short) 700); 
       // Create Styles for sheet. 
       XSSFCellStyle Style = (XSSFCellStyle) wb.createCellStyle(); 
       Style.setFillForegroundColor(new XSSFColor(java.awt.Color.LIGHT_GRAY)); 
       Style.setFillPattern(XSSFCellStyle.SOLID_FOREGROUND); 
       Style.setFont(font); 
       //iterating r number of rows 
      for (int r=0;r < 30000; r++) 
      { 
       Row row = sheet.createRow(r); 
       //iterating c number of columns 
       for (int c=0;c < 75; c++) 
       { 
        Cell cell = row.createCell(c); 
        cell.setCellValue("Hello"); 
        cell.setCellStyle(Style); 
       } 
    } 
      FileOutputStream fileOut = new FileOutputStream("E:" + File.separator + "NewTest.xlsx"); 
0

इसके लिए सबसे अच्छा उदाहरण निम्नलिखित ढेर अतिप्रवाह धागा में वर्णित है: Error While Reading Large Excel Files (xlsx) Via Apache POI

उस विषय में मुख्य जवाब में कोड स्निपेट दर्शाता है SAX XML पार्सिंग के आसपास Apache POI कफन, और कैसे आप सब कुछ खत्म पाश तुच्छता से कर सकते हैं चादरें और फिर प्रत्येक व्यक्तिगत सेल पर।

कोड अपाचे पीओआई एपीआई के वर्तमान कार्यान्वयन के साथ पुराना है, क्योंकि endRow() एपीआई वर्तमान पंक्ति संख्या प्रदान करता है जो प्रसंस्करण के लिए समाप्त हो गया है।

उस कोड स्निपेट के साथ सेल द्वारा एक बड़े एक्सएलएसएक्स फ़ाइल सेल को पार्स करने के लिए यह छोटा होना चाहिए। जैसे प्रत्येक शीट के लिए; प्रत्येक पंक्ति कोशिका के लिए; पंक्ति घटना समाप्त हो गया है। आप एप लॉजिक बना सकते हैं जहां प्रत्येक पंक्ति में आप सेलवैल नाम के कॉलमनेनाम का नक्शा बनाते हैं।

0

मुझे 800,000 कोशिकाओं और 3 एम वर्णों के साथ एक ही समस्या थी जहां एक्सएसएसएफ 1 जीबी ढेर आवंटित करता था!

मैंने xlsx फ़ाइल (जावा कोड से) पढ़ने के लिए openpyxl और numpy के साथ पायथन का उपयोग किया और पहले इसे सामान्य टेक्स्ट में परिवर्तित कर दिया। तब मैंने जावा में टेक्स्ट फ़ाइल लोड की। ऐसा लगता है कि यह बड़े उपरांत है, लेकिन यह वास्तव में तेज़ है।

अजगर स्क्रिप्ट लग रहा है

तरह
import openpyxl as px 
import numpy as np 

# xlsx file is given through command line foo.xlsx 
fname = sys.argv[1] 
W = px.load_workbook(fname, read_only = True) 
p = W.get_sheet_by_name(name = 'Sheet1') 

a=[] 
# number of rows and columns 
m = p.max_row 
n = p.max_column 

for row in p.iter_rows(): 
    for k in row: 
     a.append(k.value) 

# convert list a to matrix (for example maxRows*maxColumns) 
aa= np.resize(a, [m, n]) 

# output file is also given in the command line foo.txt 
oname = sys.argv[2] 
print (oname) 
file = open(oname,"w") 
mm = m-1 
for i in range(mm): 
    for j in range(n): 
     file.write("%s " %aa[i,j] ) 
    file.write ("\n") 

# to prevent extra newline in the text file 
for j in range(n): 
    file.write("%s " %aa[m-1,j]) 

file.close() 
तब मेरे जावा कोड में

, मैं

try { 
    // `pwd`\python_script foo.xlsx foo.txt 
    String pythonScript = System.getProperty("user.dir") + "\\exread.py "; 
    String cmdline = "python " + pythonScript + 
        workingDirectoryPath + "\\" + fullFileName + " " + 
        workingDirectoryPath + "\\" + shortFileName + ".txt"; 
    Process p = Runtime.getRuntime().exec(cmdline); 
    int exitCode = p.waitFor(); 
    if (exitCode != 0) { 
    throw new IOException("Python command exited with " + exitCode); 
    } 
} catch (IOException e) { 
    System.out.println(e.getMessage()); 
} catch (InterruptedException e) { 
    ReadInfo.append(e.getMessage()); 
} 

उसके बाद लिखा था, आप, foo.txt जो foo.xlsx के समान है मिल जाएगा, लेकिन में पाठ प्रारूप

0

मैंने एक्सएमएल संरचना को संसाधित करने के लिए SAX पार्सर का उपयोग किया। यह एक्सएलएसएक्स फाइलों के लिए काम करता है।

https://stackoverflow.com/a/44969009/4587961

संबंधित मुद्दे