簡體   English   中英

JSP和SPRING Boot:從JSON輸入生成CSV文件嗎?

[英]JSP and SPRING Boot : Generate CSV file from JSON input?

我做了一些研究,但是找不到解決方法。 當用戶單擊客戶側的“使用mailId導出記錄時”,我希望能夠從數據庫中將一些記錄導出到CSV。 實現此目標的最佳方法是什么? 在我的研究中,我發現人們僅使用Servlet作為示例,但對我而言,我不使用Servlet。

這是我的控制器:

 @RequestMapping(value = "/eblnotif/exportMailId", method = RequestMethod.POST, produces = "application/json")
        public @ResponseBody List<EblNotifResource> exportMailIdCsv(@RequestBody Filters filters)
                throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException,
                SecurityException, IOException {

            List<EblNotif> eblnotif_list = accountSservice.exportMailIdCsv(filters);

            List<EblNotifResource> eblnotifres = new ArrayList<>();

            for (EblNotif eblNotif : eblnotif_list) {
                EblNotifResource eblres = new EblNotifResource();
                eblres.setFormName(eblNotif.getFormName());
                eblres.setSendingDate(eblNotif.getSendingDate());
                eblres.setMode(eblNotif.getMode());
                eblres.setLanguage(eblNotif.getLanguage());
                eblres.setGpart(eblNotif.getGpart());
                eblres.setEmail(eblNotif.getEmail());
                eblres.setMailId(eblNotif.getMailId());
                eblnotifres.add(eblres);
            }
            return eblnotifres;
    }
}

並將此json格式返回給客戶端(JSP):

 [
   {
      "formName":"FormName1",
      "mode":"S",
      "language":"F",
      "sendingDate":"2017-04-03",
      "gpart":"555",
      "email":"",
      "mailId":"96318"
   },
   {
      "formName":"FormName2",
      "mode":"S",
      "language":"F",
      "sendingDate":"2017-04-03",
      "gpart":"444",
      "email":"",
      "mailId":"96325"
   }
]

所需的csv輸出如下所示:

formName;mode;language;sendingDate;gpart;email;mailId
FormName1;S;F;2017-04-03;555;testing@test;96318
FormName2;S;F;2017-04-03;444;testing@test;96325

如果只需要一次性下載CSV,則在控制器方法內部轉換相關對象可能是最簡單的選擇。 但是,如果需要在多個位置進行這種下載,則將來通過HttpMessageConverter向Spring MVC Rest添加CSV支持可能會更有益。

第1步 :可選,但建議

使用OpenCSVuniVocitySmooks (僅CSV解析器)之類的CSV轉換庫在CSV之間進行對象轉換。 使用良好的庫將節省大量樣板代碼,還可用於擴展對其他格式的支持,例如制表符分隔的值(TSV)和固定寬度的列。

步驟2 :實現GenericHttpMessageConverter

創建GenericHttpMessageConverter的實現,以使用在步驟1中選擇的CSV轉換庫將對象與CSV相互轉換。此步驟有點棘手,因為HttpMessageConverter通常用於將單個對象轉換為所需的內容類型,而CSV內容是對象的集合(每行代表一個對象)。 但是,Spring團隊在Jaxb2CollectionHttpMessageConverter提供了一個出色的示例,用於將對象的集合轉換為所需的內容類型。 需要牢記以下幾點:

  1. 可以使boolean canRead(Class<?>, MediaType)方法始終返回false因為CSV內容是對象的集合,因此無法將其讀取為類型指定的單個對象。
  2. boolean canRead(Type, Class<?>, MediaType)方法應檢查Type以確保它指定Collection類型,並且還指定了期望該collection保留的元素類型。
  3. 應該實現T read(Type, Class<?>, HttpInputMessage)方法來讀取CSV內容。
  4. 應該實現void write(T, Type, Class<?>, HttpInputMessage)方法來寫入CSV內容。

步驟3 :CSV消息轉換器應在配置中注冊

@Override
protected void configureMessageConverters(final List<HttpMessageConverter<?>> converters)
{
  converters.add(csvMessageConverter());

  super.addDefaultHttpMessageConverters(converters);
}

步驟4 :應使用控制器方法來返回所需對象的集合

public List<?> get() { ... }

Github上有一個示例應用程序顯示了這一功能。 啟動應用程序,然后將請求發送到http://localhost:8080/persons.csvhttp://localhost:8080/persons.json分別檢索CSV或JSON格式的數據。

有多種方法可以轉換為CSV,但一種方法

    @RequestMapping(value = "/eblnotif/exportMailId", method = RequestMethod.POST, produces = "application/json")
public @ResponseBody String exportMailIdCsv(@RequestBody Filters filters) throws IllegalAccessException,
        IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException, IOException {

    List<EblNotif> eblnotif_list = accountSservice.exportMailIdCsv(filters);

    String separator = ";";
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    StringBuilder sb = new StringBuilder();
    sb.append("formName;mode;language;sendingDate;gpart;email;mailId").append(System.lineSeparator());
    for (EblNotif eblNotif : eblnotif_list) {
        sb.append(eblNotif.getFormName()).append(separator);
        sb.append(eblNotif.getMode()).append(separator);
        sb.append(eblNotif.getLanguage()).append(separator);
        sb.append(dateFormat.format(eblNotif.getSendingDate())).append(separator);
        sb.append(eblNotif.getGpart()).append(separator);
        sb.append(eblNotif.getEmail()).append(separator);
        sb.append(eblNotif.getMailId()).append(separator);
        sb.append(System.lineSeparator());
    }
    return sb.toString();
}

使用Apache Commons CSV,您可以執行以下操作:

 @RequestMapping(value = "/download/eblnotif")
    public void download(@RequestBody @Valid Filters filter,
                         HttpServletResponse httpServletResponse) throws Exception {
        List<EblNotifResource> resources = //find from the fitler 
        CSVPrinter csvPrinter = CSVWriterUtil.transformResourcesToCSVPrinter(new BufferedWriter(httpServletResponse.getWriter()), resources);
        httpServletResponse.setHeader("Content-Disposition", "attachment; filename=\"file.csv\"");
        csvPrinter.flush();
        csvPrinter.close();
    }


    public final class CSVWriterUtil {

    private static final String NEW_LINE_SEPARATOR = "\n";

    private CSVWriterUtil() {
    }

    public static CSVPrinter transformResourcesToCSVPrinter(Writer writer, List<EblNotifResource> eblNotifResources) {
        try {
            CSVPrinter csvPrinter = new CSVPrinter(new BufferedWriter(writer), CSVFormat.DEFAULT.withRecordSeparator(NEW_LINE_SEPARATOR));
            for (EblNotifResource eblNotifResource : eblNotifResources) {
                List<String> dataRecords = new ArrayList<>();
                dataRecords.add(eblNotifResource.getFormName());
                dataRecords.add(eblNotifResource.getSendingDate());
                //...etc 
                csvPrinter.printRecord(dataRecords);
            }
            return csvPrinter;
        } catch (IOException e) {
            throw new SystemException("Exception occurred while converting file", e);
        }
    }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM