2013-01-10 118 views
1

我得到java.lang.IllegalStateException關閉時:ZIP文件是關閉的,當我嘗試讀取XLSX文件。該代碼正在從基於Spring的應用程序訪問。我正在使用apache poi 3.9。隨着Apache POI 3.8我越來越無法讀取文件。當我從本地eclipse運行時,相同的代碼工作正常,但是當應用程序部署在我的websphere服務器上並在託管在websphere上時進行訪問時,我得到異常。任何人都可以讓我知道問題是什麼?源代碼可以在下面找到。入門的Apache POI java.lang.IllegalStateException:Zip文件試圖讀取xlsx檔案

import java.io.IOException; 
import java.io.InputStream; 
import java.math.BigDecimal; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
import java.util.TreeMap; 

import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.parsers.SAXParser; 
import javax.xml.parsers.SAXParserFactory; 

import org.apache.commons.validator.GenericValidator; 
import org.apache.log4j.Logger; 
import org.apache.poi.openxml4j.exceptions.OpenXML4JException; 
import org.apache.poi.openxml4j.opc.OPCPackage; 
import org.apache.poi.ss.usermodel.BuiltinFormats; 
import org.apache.poi.ss.usermodel.DataFormatter; 
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable; 
import org.apache.poi.xssf.eventusermodel.XSSFReader; 
import org.apache.poi.xssf.model.StylesTable; 
import org.apache.poi.xssf.usermodel.XSSFCellStyle; 
import org.apache.poi.xssf.usermodel.XSSFRichTextString; 
import org.apache.struts.action.ActionMessage; 
import org.apache.struts.action.ActionMessages; 
import org.xml.sax.Attributes; 
import org.xml.sax.ContentHandler; 
import org.xml.sax.InputSource; 
import org.xml.sax.SAXException; 
import org.xml.sax.XMLReader; 
import org.xml.sax.helpers.DefaultHandler; 


public class XSSFListenerUtil { 

    private static List<String> allColValList = null; 
    private static boolean invalidTemplate = false; 
    private final static Logger log = Logger.getLogger(HSSFListenerUtil.class.getName()); // logger for the process. 
    private static BaseViewBean baseViewBean$Session; 

    /** 
    * The type of the data value is indicated by an attribute on the cell. 
    * The value is usually in a "v" element within the cell. 
    */ 
    enum xssfDataType { 
     BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER, 
    } 

    class MyXSSFSheetHandler extends DefaultHandler { 

     /** 
     * Table with styles 
     */ 
     private StylesTable stylesTable; 

     /** 
     * Table with unique strings 
     */ 
     private ReadOnlySharedStringsTable sharedStringsTable; 

     /** 
     * Destination for data 
     */ 
     //private final PrintStream output; 

     /** 
     * Number of columns to read starting with leftmost 
     */ 
     private final int minColumnCount; 

     // Set when V start element is seen 
     private boolean vIsOpen; 

     // Set when cell start element is seen; 
     // used when cell close element is seen. 
     private xssfDataType nextDataType; 

     // Used to format numeric cell values. 
     private short formatIndex; 
     private String formatString; 
     private final DataFormatter formatter; 

     private int thisColumn = -1; 
     // The last column printed to the output stream 
     private int lastColumnNumber = -1; 

     // Gathers characters as they are seen. 
     private StringBuffer value; 

     /** 
     * Accepts objects needed while parsing. 
     * 
     * @param styles Table of styles 
     * @param strings Table of shared strings 
     * @param cols Minimum number of columns to show 
     * @param target Sink for output 
     */ 
     public MyXSSFSheetHandler(
       StylesTable styles, 
       ReadOnlySharedStringsTable strings, 
       int cols) { 
      this.stylesTable = styles; 
      this.sharedStringsTable = strings; 
      this.minColumnCount = cols; 
      this.value = new StringBuffer(); 
      this.nextDataType = xssfDataType.NUMBER; 
      this.formatter = new DataFormatter(); 
     } 

     /* 
     * (non-Javadoc) 
     * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes) 
     */ 
     public void startElement(String uri, String localName, String name, 
           Attributes attributes) throws SAXException { 

      if ("inlineStr".equals(name) || "v".equals(name)) { 
       vIsOpen = true; 
       // Clear contents cache 
       value.setLength(0); 
      } 
      // c => cell 
      else if ("c".equals(name)) { 
       // Get the cell reference 
       String r = attributes.getValue("r"); 
       int firstDigit = -1; 
       for (int c = 0; c < r.length(); ++c) { 
        if (Character.isDigit(r.charAt(c))) { 
         firstDigit = c; 
         break; 
        } 
       } 
       thisColumn = nameToColumn(r.substring(0, firstDigit)); 

       // Set up defaults. 
       this.nextDataType = xssfDataType.NUMBER; 
       this.formatIndex = -1; 
       this.formatString = null; 
       String cellType = attributes.getValue("t"); 
       String cellStyleStr = attributes.getValue("s"); 
       if ("b".equals(cellType)) 
        nextDataType = xssfDataType.BOOL; 
       else if ("e".equals(cellType)) 
        nextDataType = xssfDataType.ERROR; 
       else if ("inlineStr".equals(cellType)) 
        nextDataType = xssfDataType.INLINESTR; 
       else if ("s".equals(cellType)) 
        nextDataType = xssfDataType.SSTINDEX; 
       else if ("str".equals(cellType)) 
        nextDataType = xssfDataType.FORMULA; 
       else if (cellStyleStr != null) { 
        // It's a number, but almost certainly one with a special style or format 
        int styleIndex = Integer.parseInt(cellStyleStr); 
        XSSFCellStyle style = stylesTable.getStyleAt(styleIndex); 
        this.formatIndex = style.getDataFormat(); 
        this.formatString = style.getDataFormatString(); 
        if (this.formatString == null) 
         this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex); 
       } 
      } 

     } 
     StringBuffer columnvalue = new StringBuffer(); 

     /* 
     * (non-Javadoc) 
     * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String) 
     */ 
     public void endElement(String uri, String localName, String name) 
       throws SAXException { 

      String thisStr = null; 

      // v => contents of a cell 
      if ("v".equals(name)) { 
       // Process the value contents as required. 
       // Do now, as characters() may be called more than once 
       switch (nextDataType) { 

        case BOOL: 
         char first = value.charAt(0); 
         thisStr = first == '0' ? "FALSE" : "TRUE"; 
         break; 

        case ERROR: 
         thisStr = "\"ERROR:" + value.toString() + '"'; 
         break; 

        case FORMULA: 
         // A formula could result in a string value, so always add double-quote characters. 
         thisStr = '"' + value.toString() + '"'; 
         break; 

        case INLINESTR: 
         XSSFRichTextString rtsi = new XSSFRichTextString(value.toString()); 
         thisStr = '"' + rtsi.toString() + '"'; 
         break; 

        case SSTINDEX: 
         String sstIndex = value.toString(); 
         try { 
          int idx = Integer.parseInt(sstIndex); 
          XSSFRichTextString rtss = new XSSFRichTextString(sharedStringsTable.getEntryAt(idx)); 
          thisStr = '"' + rtss.toString() + '"'; 
         } 
         catch (NumberFormatException ex) { 
          log.error("Failed to parse SST index '" + sstIndex + "': " + ex.toString()); 
          throw new SAXException("Failed to parse SST index '" + sstIndex + "': " + ex.toString()); 
         } 
         break; 

        case NUMBER: 
         String n = value.toString(); 
         if (this.formatString != null) 
          thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString); 
         else 
          thisStr = n; 
         break; 

        default: 
         thisStr = "(TODO: Unexpected type: " + nextDataType + ")"; 
         break; 
       } 

       // Output after we've seen the string contents 
       // Emit commas for any fields that were missing on this row 
       if (lastColumnNumber == -1) { 
        lastColumnNumber = 0; 
       } 
       for (int i = lastColumnNumber; i < thisColumn; ++i){ 
        //output.print(','); 
        columnvalue.append(","); 
       } 
       // Might be an empty string. 
       columnvalue.append(thisStr); 

       // Update column 
       if (thisColumn > -1) 
        lastColumnNumber = thisColumn; 

      } else if ("row".equals(name)) { 

       // Print out any missing commas if needed 
       if (minColumns > 0) { 
        // Columns are 0 based 
        if (lastColumnNumber == -1) { 
         lastColumnNumber = 0; 
        } 
        for (int i = lastColumnNumber; i < (this.minColumnCount); i++) { 
         //output.print(','); 
         columnvalue.append(","); 
        } 
       } 

       // We're onto a new row 
       if(!GenericValidator.isBlankOrNull(columnvalue.toString())){ 
        String completeVal = columnvalue.toString().replaceAll("\"", ""); 
        allColValList.add(completeVal); 
       } 
       columnvalue = new StringBuffer(""); 
       lastColumnNumber = -1; 
      } 

     } 

     /** 
     * Captures characters only if a suitable element is open. 
     * Originally was just "v"; extended for inlineStr also. 
     */ 
     public void characters(char[] ch, int start, int length) 
       throws SAXException { 
      if (vIsOpen) 
       value.append(ch, start, length); 
     } 

     /** 
     * Converts an Excel column name like "C" to a zero-based index. 
     * 
     * @param name 
     * @return Index corresponding to the specified name 
     */ 
     private int nameToColumn(String name) { 
      int column = -1; 
      for (int i = 0; i < name.length(); ++i) { 
       int c = name.charAt(i); 
       column = (column + 1) * 26 + c - 'A'; 
      } 
      return column; 
     } 

    } 

    private OPCPackage xlsxPackage; 
    private int minColumns; 

    /** 
    * 
    * @param pkg  The XLSX package to process 
    * @param output  The PrintStream to output the CSV to 
    * @param minColumns The minimum number of columns to output, or -1 for no minimum 
    */ 
    public XSSFListenerUtil(OPCPackage pkg, int minCol, ArrayList<String> colList, BaseViewBean baseViewBean$Session) { 
     this.xlsxPackage = pkg; 
     this.minColumns = minCol; 
     XSSFListenerUtil.allColValList = colList; 
     XSSFListenerUtil.baseViewBean$Session = baseViewBean$Session; 
    } 

    /** 
    * Parses and shows the content of one sheet 
    * using the specified styles and shared-strings tables. 
    * 
    * @param styles 
    * @param strings 
    * @param sheetInputStream 
    */ 
    public void processSheet(
      StylesTable styles, 
      ReadOnlySharedStringsTable strings, 
      InputStream sheetInputStream) 
      throws IOException, ParserConfigurationException, SAXException { 

     InputSource sheetSource = new InputSource(sheetInputStream); 
     SAXParserFactory saxFactory = SAXParserFactory.newInstance(); 
     SAXParser saxParser = saxFactory.newSAXParser(); 
     XMLReader sheetParser = saxParser.getXMLReader(); 
     ContentHandler handler = new MyXSSFSheetHandler(styles, strings, this.minColumns); 
     sheetParser.setContentHandler(handler); 
     sheetParser.parse(sheetSource); 
    } 

    /** 
    * Initiates the processing of the XLS workbook file to CSV. 
    * 
    * @throws IOException 
    * @throws OpenXML4JException 
    * @throws ParserConfigurationException 
    * @throws SAXException 
    */ 
    public void process() 
      throws IOException, OpenXML4JException, ParserConfigurationException, SAXException { 

     ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(xlsxPackage); 
     XSSFReader xssfReader = new XSSFReader(xlsxPackage); 
     StylesTable styles = xssfReader.getStylesTable(); 
     XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData(); 
     int index = 0; 
     while (iter.hasNext()) { 
      InputStream stream = iter.next(); 
      processSheet(styles, strings, stream); 
      stream.close(); 
      ++index; 
     } 
    } 

    public static void parseAndRetrieveExcelDetails(String filePath, InvestmentDimDao investmentDao, 
          BaseViewBean baseViewBean$Session, ActionMessages errors, boolean invalidTemplateIdentifier) throws Exception{ 

     int minColumns = -1; 
     invalidTemplate = invalidTemplateIdentifier; 
     ArrayList<String> initialList = new ArrayList<String>(); 
     //OPCPackage pkg = OPCPackage.open(filePath, PackageAccess.READ); 
     OPCPackage pkg = OPCPackage.open(filePath); 
     XSSFListenerUtil xssfSheetProcessor = new XSSFListenerUtil(pkg, minColumns, initialList, baseViewBean$Session); 
     xssfSheetProcessor.process(); 

     validateAndExtractExcelData(); 

     log.info("Finished processing all records"); 
     if(invalidTemplate){ 
      errors.add("failure", new ActionMessage("secaccess.file.invaliddata")); 
     }else{ 
      log.info("All records parsed successfully"); 
     } 

     allColValList.clear(); 
     allColValList = null; 
     pkg.close(); 
     System.gc(); 
    } 

    private static void validateAndExtractExcelData() throws NumberFormatException { 
     int rowCnt = 1; 
     int colCnt = 0; 
     ExcelListenerBean listenerBean; 
     ExcelListenerBean bean; 
     Map <String, ExcelListenerBean> excelRecords = new TreeMap<String, ExcelListenerBean>(); 
     for(String colVal : allColValList) { 
      if(rowCnt==1 && !AppGlobalConstants.HardCodedValues.G_L_CALC_HEADER1.equals(colVal)) { 
       invalidTemplate = true; 
      } 
      if(rowCnt==2 && !AppGlobalConstants.HardCodedValues.G_L_CALC_HEADER2.equals(colVal) & !invalidTemplate) { 
       invalidTemplate = true; 
      } 
      if(rowCnt==3 && !AppGlobalConstants.HardCodedValues.G_L_CALC_HEADER3.equals(colVal) & !invalidTemplate) { 
       invalidTemplate = true; 
      } 
      if(rowCnt > 3 && !invalidTemplate) { 
       listenerBean = new ExcelListenerBean(AppGlobalConstants.HardCodedValues.SQL_TYPE); 

       String[] allValues = colVal.split(","); 
       for(String cellContents : allValues){ 

        switch (colCnt) { 
         case 0: 
          if(GenericValidator.isBlankOrNull(cellContents)){ 
           invalidTemplate = true; 
          }else{ 
           listenerBean = new ExcelListenerBean(AppGlobalConstants.HardCodedValues.SQL_TYPE); 
           listenerBean.setId(rowCnt); 
           listenerBean.setShortName(cellContents); 
          } 
          break; 
         case 1: 
          if(GenericValidator.isBlankOrNull(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setFmrCusip(cellContents); 
          } 
          break; 
         case 2: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setIncorrectTrdShares(Double.valueOf(cellContents)); 
          } 
          break; 
         case 3: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setIncorrectTrdPrice(Double.valueOf(cellContents)); 
          } 
          break; 
         case 4: 
          if(GenericValidator.isBlankOrNull(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setIncorrectTrdBuySell(cellContents); 
          } 
          break; 
         case 5: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setIncorrectTrdCommRate(Double.valueOf(cellContents)); 
          } 
          break; 
         case 6: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setIncorrectTrdCommission(Double.valueOf(cellContents)); 
          } 
          break; 
         case 7: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setIncorrectTrdFees(Double.valueOf(cellContents)); 
          } 
          break; 
         case 8: 
          if(GenericValidator.isBlankOrNull(cellContents.toString()) || !GenericValidator.isDouble(cellContents.toString())){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setIncorrectTrdNet(Double.valueOf(cellContents.toString())); 
          } 
          break; 
         case 9: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setCorrectionTrdShares(Double.valueOf(cellContents)); 
          } 
          break; 
         case 10: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setCorrectionTrdPrice(Double.valueOf(cellContents)); 
          } 
          break; 
         case 11: 
          if(GenericValidator.isBlankOrNull(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setCorrectionTrdBuySell(cellContents); 
          } 
          break; 
         case 12: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setCorrectionTrdCommRate(Double.valueOf(cellContents)); 
          } 
          break; 
         case 13: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setCorrectionTrdCommission(Double.valueOf(cellContents)); 
          } 
          break; 
         case 14: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setCorrectionTrdFees(Double.valueOf(cellContents)); 
          } 
          break; 
         case 15: 
          if(GenericValidator.isBlankOrNull(cellContents) || !GenericValidator.isDouble(cellContents)){ 
           invalidTemplate = true; 
           break; 
          }else{ 
           listenerBean.setCorrectionTrdNet(Double.valueOf(cellContents)); 
          } 
          break; 
        } 
        colCnt++; 
       } 

       bean = excelRecords.get(listenerBean.getShortName()); 
       if (bean != null){ 
        listenerBean.setAcctGainLossAmt(new BigDecimal(Double.valueOf(bean.getAcctGainLossAmt()) + listenerBean.getCorrectionTrdNet() + listenerBean.getIncorrectTrdNet()).toPlainString()); 
       } else { 
        listenerBean.setAcctGainLossAmt(new BigDecimal(listenerBean.getCorrectionTrdNet() + listenerBean.getIncorrectTrdNet()).toPlainString()); 
       } 

       excelRecords.put(listenerBean.getShortName(), listenerBean); 
      } 
      colCnt = 0; 
      rowCnt++; 
     } 

     baseViewBean$Session.setExcelRecLst(new ArrayList<ExcelListenerBean>(excelRecords.values())); 
     log.info("Number of records for update is "+excelRecords.size()); 
    } 

} 
+2

完整的堆棧跟蹤將有助於。另外,您正試圖根據文件路徑讀取軟件包,websphere服務器上是否存在xlsx文件,並且websphere實例是否有足夠的權限來讀取該文件? – beny23

+0

不,文件路徑是我的本地系統路徑。服務器將無法處理它嗎? – sandy

+0

文件路徑將在服務器本地。服務器將無法在本地計算機上看到該磁盤。要處理服務器上的文件,您必須先上傳文件。 – beny23

回答

2

我也陷入了同樣的問題,但後來我意識到,我的文件名是TestData.xlsx我用TestData.csv

相關問題