2011-10-19 12 views
16

JDK 1.6, JSF 2.1, PrimeFaces 2.2.1, POI 3.2, और अपाचे बिलाव का उपयोग करते हुए 7निर्यात और PrimeFaces

मैं सेटअप करने के लिए एक सर्वलेट के आधार पर एक एक्सेल फ़ाइल की एक डाउनलोड अनुमति देने के लिए कोशिश कर रहा हूँ उपयोगकर्ता चयन एक्सेल दस्तावेज़ रनटाइम पर बनाया गया है।

कोई त्रुटि नहीं और कोड सर्वलेट में मिलता है।

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

ExportExcelReports.java

protected void processRequest(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException {  
    response.setContentType("application/vnd.ms-excel"); 
    response.setHeader("Content-Disposition", "attachment; filename=\"my.xls\"");     

    HSSFWorkbook workbook = new HSSFWorkbook(); 

    HSSFSheet sheet = workbook.createSheet(); 
    HSSFRow row = sheet.createRow(0); 
    HSSFCell cell = row.createCell(0); 
    cell.setCellValue(0.0); 

    FileOutputStream out = new FileOutputStream("my.xls"); 
    workbook.write(out); 
    out.close(); 
} 

ProjectReportBean.java

public void getReportData() { 
    try { 
     FacesContext ctx = FacesContext.getCurrentInstance(); 
     ExternalContext ectx = ctx.getExternalContext(); 
     HttpServletRequest request = (HttpServletRequest) ectx.getRequest(); 
     HttpServletResponse response = (HttpServletResponse) ectx.getResponse(); 
     RequestDispatcher dispatcher = request.getRequestDispatcher("/ExportExcelReports"); 
     dispatcher.forward(request, response); 
     ctx.responseComplete(); 
    } catch (Exception e) {} 
} 

index.xhtml

<h:form id="reportsForm"> 
    <h:outputLabel for="report" value="Reports" /><br /> 
    <h:selectOneMenu id="report" value="#{projectReportBean.selectedReport}" required="true" requiredMessage="Select Report"> 
     <f:selectItem itemLabel="---" noSelectionOption="true" /> 
     <f:selectItems value="#{projectReportBean.reports}" /> 
    </h:selectOneMenu> 

    <p:commandButton action="#{projectReportBean.getReportData}" value="Export" update="revgrid" />      
</h:form> 

उत्तर

25

दो समस्याएं हैं।

पहली समस्या यह है कि <p:commandButton> डिफ़ॉल्ट रूप से एक अजाक्स अनुरोध भेजता है। यह अनुरोध जावास्क्रिप्ट कोड द्वारा निकाल दिया गया है। हालांकि, जावास्क्रिप्ट एक प्रतिक्रिया के साथ कुछ भी नहीं कर सकता जिसमें फ़ाइल डाउनलोड होता है। सुरक्षा प्रतिबंधों के कारण जावास्क्रिप्ट को संवाद या कुछ के रूप में सहेजें नहीं जा सकता है। प्रतिक्रिया मूल रूप से पूरी तरह से अनदेखा किया जाता है।

आप <p:commandButton> को ajax="false" जोड़ने के लिए ajax बंद करने के लिए इतना है कि बटन एक सामान्य तुल्यकालिक HTTP अनुरोध आग की जरूरत है, या आप मानक <h:commandButton> से बदल की जरूरत है।

<p:commandButton ajax="false" ... /> 

या

<h:commandButton ... /> 

दूसरी समस्या यह है कि आपके सर्वलेट एक्सेल बिल्कुल जवाबी कार्रवाई के लिए फाइल लिखने नहीं है, लेकिन इसके बजाय जो सर्वर के काम-काज निर्देशिका में संग्रहीत किया जाता है एक स्थानीय फाइल करने के लिए है। असल में, HTTP प्रतिक्रिया में कुछ भी शामिल नहीं है। आपको को WorkBook#write() विधि पर पास करने की आवश्यकता है।

workbook.write(response.getOutputStream()); 

एक असंबंधित नोट पर, मुझे आश्चर्य है कि सर्वलेट यहां कैसे उपयोगी है। क्या आप इसे जेएसएफ के बाहर पुन: उपयोग करना चाहते हैं? यदि नहीं, तो आपको सर्वलेट को प्रेषण की आवश्यकता नहीं है, लेकिन बीन की एक्शन विधि में केवल उसी कोड को निष्पादित करें। वह खाली catch ब्लॉक भी अच्छा नहीं है। मैं इसे विधि में throws के रूप में घोषित करता हूं या कम से कम इसे new FacesException(e) के रूप में पुनर्स्थापित करता हूं। टिप्पणियों के अनुसार


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

public void getReportData() throws IOException { 
    HSSFWorkbook workbook = new HSSFWorkbook(); 
    HSSFSheet sheet = workbook.createSheet(); 
    HSSFRow row = sheet.createRow(0); 
    HSSFCell cell = row.createCell(0); 
    cell.setCellValue(0.0); 

    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 
    externalContext.setResponseContentType("application/vnd.ms-excel"); 
    externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"my.xls\""); 

    workbook.write(externalContext.getResponseOutputStream()); 
    facesContext.responseComplete(); 
} 
+0

मैं सर्वलेट का उपयोग नहीं करना चाहता। सोचा था कि मैं भी था। बदले में यह बदलने के बाद कि मैं यह काम करने के बाद। –

+1

उस स्थिति में, एक पुनर्लेखन सुझाव के लिए उत्तर अद्यतन की जांच करें। 'बाहरी कॉन्टेक्स्ट' में बहुत से प्रतिनिधि विधियां हैं। उनका उपयोग करें। http://download.oracle.com/javaee/6/api/javax/faces/context/ExternalContext.html आप अंततः अपने जेएसएफ कोड में ** शून्य ** 'javax.servlet' आयात के साथ समाप्त करना चाहते हैं। – BalusC

+0

बस इसे सर्वलेट के बिना काम कर गया। वास्तव में मदद की सराहना करते हैं। –

0

मैं प्राइमफ़ेस फ़ाइलडाउनलोड का उपयोग करने की भी सिफारिश करता हूं। आपकी संरचना के आधार पर यह सब कुछ बहुत आसान बना सकता है। आपको केवल एक प्रबंधित बीन एक सर्वलेट बनाना नहीं होगा जो ContentStream प्रदान कर सकता है।

चूंकि आपके पास पहले से ही सर्वलेट लिखा गया है, इसलिए बदलने के लिए कोई बात नहीं है, केवल विचार के लिए भोजन।

1

यहां यह है कि मैंने पहले और काम करने वाले मामले को लिखा था;

xhtml;

<h:panelGrid id="viewCommand" style="float:right;" > 
         <p:commandButton value="Export Excel" icon="ui-icon-document" 
          ajax="false" actionListener="#{xxx.export2Excel}" 
          rendered="#{xxx.showTable}"> 
          <p:fileDownload value="#{xxx.exportFile}" 
           contentDisposition="attachment" /> 
         </p:commandButton></h:panelGrid> 

जावा पक्ष (पीओआई के साथ);

protected void lOBExport2Excel(List table) throws Throwable { 
    Row row = null; 
    Cell cell = null; 
    try { 

     Workbook wb = new HSSFWorkbook(); 
     HSSFCellStyle styleHeader = (HSSFCellStyle) wb.createCellStyle(); 
     HSSFFont fontHeader = (HSSFFont) wb.createFont(); 
     fontHeader.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); 
     styleHeader.setFont(fontHeader); 
     Sheet sheet = wb.createSheet("sheet"); 
     row = sheet.createRow((short) 0); 

     for (int i = 0; i < columnNames.size(); i++) { 
      cell = row.createCell(i); 
      cell.setCellValue(columnNames.get(i)); 
      cell.setCellStyle(styleHeader); 
     } 

     int j = 1; 

     for (DBData[] temp : tabularData) { 
      row = sheet.createRow((short) j); 
      for (int k = 0; k < temp.length; k++) { 
       HSSFCellStyle styleRow = (HSSFCellStyle) wb.createCellStyle(); 
       HSSFFont fontRow = (HSSFFont) wb.createFont(); 
       fontRow.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL); 
       styleRow.setFont(fontRow); 
       cell = row.createCell(k); 
       setStyleFormat(temp[k].getDataType(), styleRow, wb); 
       cell.setCellValue(temp[k].toFullString()); 
       cell.setCellStyle(styleRow); 
      } 

      j++; 
     } 

     String excelFileName = getFileName("xls"); 

     FileOutputStream fos = new FileOutputStream(excelFileName); 
     wb.write(fos); 
     fos.flush(); 
     fos.close(); 

     InputStream stream = new BufferedInputStream(new FileInputStream(excelFileName)); 
     exportFile = new DefaultStreamedContent(stream, "application/xls", excelFileName); 


    } catch (Exception e) { 
     catchError(e); 
    } 

} 
+0

क्या आप पूरा काम कर रहे कोड – spt

+0

@spt को पहले से ही काम कर रहे डेटा को रख सकते हैं जो "जावा पक्ष (पीओआई के साथ)" विषय के साथ जोड़ा गया है। – newuserua