Pytanie w sprawie java, jsf, csv, download – Pobieranie pliku CSV za pomocą JSF

5

Nie wiem, jak pobrać plik CSV. CSV zostanie wygenerowany w czasie wykonywania. Czy muszę najpierw zapisać plik w katalogu WEB-INF tomcat? Używam JSF 1.2.

Przy okazji, jaki jest preferowany komponent JSF dla tego rodzaju zadań?

Edytuj (05.05.2012 - 15:53)

Spróbowałem rozwiązaniaBalusC stwierdził w swoim pierwszympołączyć, ale jeśli kliknę na przycisk polecenia, zawartość pliku zostanie wyświetlona na stronie internetowej. Może jest problem zmimetype?

plik xhtml:

<code><a4j:form>
    <a4j:commandButton action="#{surveyEvaluationBean.doDataExport}" value="#{msg.srvExportButton}" />
</a4j:form>
</code>

główna fasola:

<code>    public String doDataExport() {

    try {
        export.downloadFile();  
    } catch (SurveyException e) {
        hasErrors = true;
    }
    return "";
}
</code>

fasola eksportowa:

<code>public void downloadFile() throws SurveyException {

    try {

        String filename = "analysis.csv";

        FacesContext fc = FacesContext.getCurrentInstance();
        HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();

        response.reset();
        response.setContentType("text/comma-separated-values");
        response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");

        OutputStream output = response.getOutputStream();

        // writing just sample data
        List<String> strings = new ArrayList<String>();

        strings.add("filename" + ";" + "description" + "\n");
        strings.add(filename + ";" + "this is just a test" + "\n");

        for (String s : strings) {
            output.write(s.getBytes());
        }

        output.flush();
        output.close();

        fc.responseComplete();

    } catch (IOException e) {
        throw new SurveyException("an error occurred");
    }
}
</code>

Edytuj (05.05.2012 - 16:27)

Rozwiązałem mój problem. Muszę użyć<h:commandButton> zamiast<a4j:commandButton> a teraz to działa!

Twoja odpowiedź

2   odpowiedź
4

Czy muszę najpierw zapisać plik w katalogu WEB-INF tomcat?

Nie, po prostu zapisz go bezpośrednio do treści odpowiedzi HTTP, tak jak to uzyskujeszExternalContext#getResponseOutputStream() po ustawieniu odpowiednich nagłówków odpowiedzi, które informują przeglądarkę o tym, co będzie pobierane.

Zrób matematykę na podstawie konkretnych przykładów znalezionych w następujących odpowiedziach:

Jak zapewnić pobieranie plików z komponentu bean JSF?Arkusz kalkulacyjny Excel generujący JSP (XLS) do pobrania

Gruntownie:

<code>List<List<Object>> csv = createItSomehow();
writeCsv(csv, ';', ec.getResponseOutputStream());
</code>

Przy okazji, jaki jest ulubiony komponent jsf dla tego rodzaju zadań?

To jest subiektywne. Ale i tak używamy<p:dataExporter> do pełnej satysfakcji.

Nie sądzę, żebym mógł użyćPrimeFaces, ponieważ od tego czasu nie obsługują JSF 1.2PrimeFaces 2.0 kiedy mam rację? yves.beutler
Jeśli używama4j:components wtedy to nie zadziała, ale teraz zmieniłem na<h:commandButton> i działa poprawnie. Dzięki BalusC za kolejną świetną odpowiedź! yves.beutler
Znam wady jsf 1.2, ale w tej chwili nie jesteśmy w stanie przejść na wyższy poziom. Próbowałem zrozumieć twój pierwszy link, ale to nie działa. Użyłem typu MIMEtext/comma-separated-values Znalazłem w sieci, ale przeglądarki (IE, FF, Chrome) nie interpretują tego poprawnie. yves.beutler
Nie ma za co. Rzeczywiście, nie można pobierać plików przez ajax. Jest to już wspomniane w pierwszym linku. BalusC
To prawda, starożytny JSF 1.x zbliża się ku końcowi, więc nie należy oczekiwać, że nowa biblioteka komponentów będzie dla niego odpowiednia. Po prostu przeprowadź transmisję strumieniową ręcznie. Musisz tylko złapać surowyHttpServletResponse przezExternalContext#getResponse() a następnie wywołanie jejgetOutputStream() zamiast tego, ale to już zostało opisane w pierwszym linku. Lub, oczywiście, uaktualnienie do JSF 2. Oferuje tak wiele korzyści w porównaniu z JSF 1.2. BalusC
0


Możesz na to spojrzećpołączyć.

Jeśli nie, możesz to zrobić w ten sposób:

<code>List<Object> report = new ArrayList<Object>(); // fill your arraylist with relevant data 
String filename = "report.csv";    
File file = new File(filename);
Writer output = new BufferedWriter(new FileWriter(file));
output.append("Column1");
output.append(",");
output.append("Column2");
output.append("\n");
//your data goes here, Replcae Object with your bean
for (Object row:report){
    output.append(row.field1);
    output.append(",");
    output.append(row.field2);
    output.append("\n");
}
output.flush();
output.close();
</code>

Powiązane pytania