2009-01-25 11 views
5

डाउनलोड करने के लिए एक्सेल स्प्रेडशीट (एक्सएलएस) उत्पन्न करने वाला जेएसपी मेरे पास यह एप्लिकेशन है जो मैं जेएसपी में विकसित कर रहा हूं और मैं एक्सएलएस (एमएस एक्सेल प्रारूप) में डेटाबेस से कुछ डेटा निर्यात करना चाहता हूं।जेएसपी

क्या यह एक फ़ाइल लिखने के लिए टॉमकैट के तहत संभव है जैसे कि यह एक सामान्य जावा एप्लिकेशन था, और फिर इस फ़ाइल के लिए एक लिंक उत्पन्न करें? या मुझे इसके लिए एक विशिष्ट एपीआई का उपयोग करने की ज़रूरत है?

क्या ऐसा करने पर मुझे अनुमति समस्या होगी?

उत्तर

9

जबकि आप JExcelAPI जैसी पूर्ण लाइब्रेरी का उपयोग कर सकते हैं, तो एक्सेल सीएसवी और सादा HTML टेबल भी पढ़ेगा बशर्ते आप "एप्लिकेशन/vnd.ms-excel" जैसी प्रतिक्रिया MIME प्रकार को सेट करें।

स्प्रेडशीट को कितना जटिल होना चाहिए इस पर निर्भर करते हुए, सीएसवी या एचटीएमएल तीसरे पक्ष की लाइब्रेरी के बिना आपके लिए नौकरी कर सकता है।

+0

+1 "सादा HTML" टिप के लिए +1; कई मामलों में यह काम करेगा, और यह बहुत आसान है। – Jonik

+1

इसे सरल रखना अक्सर सबसे अच्छा तरीका है। अच्छा जवाब – SWD

3

आपको शायद JExcelAPI ("jxl") या POI जैसे एक्सेल फ़ाइलों में हेरफेर करने के लिए लाइब्रेरी की आवश्यकता होगी। मैं jxl से अधिक परिचित हूं और यह निश्चित रूप से फाइलें लिख सकता है। आप उन्हें उत्पन्न कर सकते हैं और उन्हें एक यूआरएल की सेवा करके स्टोर कर सकते हैं लेकिन मैं नहीं करूँगा। जेनरेट की गई फाइलें दर्द हैं। वे समरूपता, सफाई प्रक्रियाओं आदि पर प्रपत्र में जटिलता जोड़ते हैं।

यदि आप फ्लाई पर फ़ाइल जेनरेट कर सकते हैं और क्लाइंट को मानक सर्वलेट तंत्र के माध्यम से स्ट्रीम कर सकते हैं।

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

0

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

8

application/vnd.ms-excel सामग्री प्रकार के साथ सादे HTML तालिका का उपयोग न करें। फिर आप मूल रूप से Excel को गलत सामग्री प्रकार के साथ बेवकूफ़ बना रहे हैं जो नवीनतम Excel संस्करणों में विफलता और/या चेतावनियों का कारण बनता है। जब आप एक्सेल में इसे संपादित और सहेजते हैं तो यह मूल HTML स्रोत को भी गड़बड़ कर देगा। बस ऐसा मत करो।

बदले में सीएसवी एक मानक प्रारूप है जो बिना किसी समस्या के एक्सेल से डिफ़ॉल्ट समर्थन का आनंद लेता है और वास्तव में उत्पन्न करने के लिए आसान और स्मृति-कुशल है। यद्यपि पुस्तकालय हैं, आप वास्तव में 20 से कम लाइनों में आसानी से लिख सकते हैं (उन लोगों के लिए मजाकिया जो प्रतिरोध नहीं कर सकते हैं)।

  1. फील्ड्स अल्पविराम से अलग कर रहे हैं: तुम बस RFC 4180 कल्पना जो मूल रूप से केवल 3 नियम शामिल हैं पालन करने के लिए है।
  2. यदि कोई अल्पविराम किसी क्षेत्र के भीतर होता है, तो फ़ील्ड को डबल कोट्स से घिरा होना चाहिए।
  3. यदि किसी फ़ील्ड के भीतर एक डबल कोट होता है, तो फ़ील्ड को डबल कोट्स से घिरा होना चाहिए और फ़ील्ड के भीतर डबल कोट को दूसरे डबल कोट से बचाना होगा।

    public static void main(String[] args) throws IOException { 
        List<List<String>> csv = new ArrayList<List<String>>(); 
        csv.add(Arrays.asList("field1", "field2", "field3")); 
        csv.add(Arrays.asList("field1,", "field2", "fie\"ld3")); 
        csv.add(Arrays.asList("\"field1\"", ",field2,", ",\",\",\"")); 
        writeCsv(csv, ',', System.out); 
    } 
    

    और एक सर्वलेट अंदर (हाँ, सर्वलेट, JSP इस के लिए उपयोग नहीं करते हैं:

    public static <T> void writeCsv (List<List<T>> csv, char separator, OutputStream output) throws IOException { 
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(output, "UTF-8")); 
        for (List<T> row : csv) { 
         for (Iterator<T> iter = row.iterator(); iter.hasNext();) { 
          String field = String.valueOf(iter.next()).replace("\"", "\"\""); 
          if (field.indexOf(separator) > -1 || field.indexOf('"') > -1) { 
           field = '"' + field + '"'; 
          } 
          writer.append(field); 
          if (iter.hasNext()) { 
           writer.append(separator); 
          } 
         } 
         writer.newLine(); 
        } 
        writer.flush(); 
    } 
    

    यहाँ एक उदाहरण है कि कैसे आप इसका इस्तेमाल कर सकते हैं:

यहाँ एक किकऑफ़ उदाहरण है !) आप मूल रूप से कर सकते हैं:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    String filename = request.getPathInfo().substring(1); 
    List<List<Object>> csv = someDAO().findCsvContentFor(filename); 
    response.setHeader("content-type", "text/csv"); 
    response.setHeader("content-disposition", "attachment;filename=\"" + filename + "\""); 
    writeCsv(csv, ';', response.getOutputStream()); 
} 

इस सर्वलेट को कुछ पसंद पर मानचित्र करें ई /csv/* और इसे http://example.com/context/csv/filename.csv जैसे कुछ के रूप में आमंत्रित करें। बस इतना ही।

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

+0

आपके पास "एक्सेल एक अल्पविराम या अर्धविराम स्वीकार करेगा" साझा करने के साथ अनुभव है? –

+1

@Thor: यदि दाएं विभाजक का उपयोग किया जाता है, तो एक्सेल सही कोशिकाओं में स्वचालित रूप से इसे खोल देगा। विभाजक (डिफ़ॉल्ट) एक्सेल कॉन्फ़िगरेशन और लोकेल पर निर्भर करता है। उदाहरण के लिए यूरोपीय लोकेशंस में, यह अक्सर अर्धविराम होता है। तो यह वास्तव में आपके लक्षित दर्शकों पर निर्भर करता है जो विभाजक निर्यात के दौरान चुनने के लिए चुनते हैं। अंततः अन्यथा इसे मैन्युअल रूप से आयात करने और विभाजक निर्दिष्ट करने के लिए है। – BalusC

+0

फ़ाइल नाम चीनी का समर्थन नहीं करता है, मैं एक स्थिर फ़ाइल नाम = "下载 物品" का उपयोग करता हूं, लेकिन डाउनलोड फ़ाइल नाम मैपिंग यूआरएल आता है, springmvc में xxx.do कहें, या सर्वलेट पर मैपिंग पथ कहें। चीनी फ़ाइल नाम का समर्थन कैसे करें? – Jaskey

1

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

0
try { 
      String absoluteDiskPath = test.xls"; 
      File f = new File(absoluteDiskPath); 
      response.setContentType("application/xlsx"); 
      response.setHeader("Content-Disposition", "attachment; filename=" + absoluteDiskPath); 
      String name = f.getName().substring(f.getName().lastIndexOf("/") + 1, f.getName().length()); 
      InputStream in = new FileInputStream(f); 
      out.clear(); //clear outputStream prevent illegalStateException write binary data to outputStream 
      ServletOutputStream outs = response.getOutputStream(); 
      int bit = 256; 
      int i = 0; 
      try { 
       while ((bit) >= 0) { 
        bit = in.read(); 
        outs.write(bit); 
       } 
       outs.flush(); 
       outs.close(); 
       in.close(); 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } finally { 
       try { 
        if(outs != null) 
         outs.close(); 
        if(in != null) 
         in.close(); 
       }catch (Exception ioe2) { 
        ioe2.printStackTrace(); 
       } 
      } 
    } catch (Exception ex) { 
     ex.printStackTrace(); 

    }