You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Java Struts中动态生成CSV文件并上传至FTP服务器

解决方案:内存生成CSV并直接上传FTP

原代码存在的问题

  1. 使用FileWriter将CSV落地到本地磁盘,不符合无磁盘IO的需求
  2. 直接调用business.toString()和position.toString()会输出数组内存地址,而非实际数据内容
  3. FileWriter并没有getInputStream()方法,这段代码会抛出编译错误

修改后的实现思路

利用内存流(ByteArrayOutputStream + ByteArrayInputStream)在内存中构建CSV内容,无需落地文件,直接将内存流转为输入流传给FTP上传方法。同时正确处理CSV格式,将数组数据按规范写入。

完整修改代码

public ActionForward generatePayroll(ActionMapping mapping, ActionForm form,
                       HttpServletRequest request, HttpServletResponse response) {
   SessionInfoForm _form = (SessionInfoForm) form;
   SisTransactionsSession _config = _form.getSisTransactionsSession();
   String loggedInUser = _form.getLoggedinEmployeeDVO().getLoginId().toUpperCase();
   String[] business = request.getParameterValues("selectedBusinessValues");
   String[] position = request.getParameterValues("selectedPositionValues");
   InputStream isFixedValue = null;
   try {
      // 使用内存流替代文件流,避免磁盘IO
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      OutputStreamWriter osw = new OutputStreamWriter(baos, StandardCharsets.UTF_8);
      BufferedWriter writer = new BufferedWriter(osw);

      // 写入CSV表头(按需调整)
      writer.write("Business,Position");
      writer.newLine();

      // 逐行写入数据:假设business和position数组长度一致
      if (business != null && position != null && business.length == position.length) {
          for (int i = 0; i < business.length; i++) {
              // 处理CSV特殊字符:内容含逗号/引号时用双引号包裹
              String businessVal = escapeCsvField(business[i]);
              String positionVal = escapeCsvField(position[i]);
              writer.write(businessVal + "," + positionVal);
              writer.newLine();
          }
      }

      // 刷新并关闭写入流
      writer.flush();
      writer.close();

      // 将内存输出流转为输入流,用于FTP上传
      isFixedValue = new ByteArrayInputStream(baos.toByteArray());

      // 调用FTP上传方法,替换为实际目标目录
      String dirName = "/ftp/payroll";
      String fileName = "PAYROLL_PRM.csv";
      fileUpload(isFixedValue, dirName, loggedInUser, fileName);

   } catch (IOException e) {
      e.printStackTrace();
   } finally {
       // 确保输入流被关闭,避免资源泄漏
       if (isFixedValue != null) {
           try {
               isFixedValue.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
   }
   return mapping.findForward("success");
}

// CSV字段转义工具方法,符合RFC 4180标准
private String escapeCsvField(String field) {
    if (field == null) {
        return "";
    }
    // 字段含逗号、双引号或换行时,用双引号包裹并转义内部双引号
    if (field.contains(",") || field.contains("\"") || field.contains("\n") || field.contains("\r")) {
        return "\"" + field.replace("\"", "\"\"") + "\"";
    }
    return field;
}

关键改动说明

  • 无磁盘IO:用ByteArrayOutputStream在内存中构建CSV内容,完全跳过本地文件操作
  • 规范CSV格式:遍历数组写入每行数据,添加字段转义逻辑,避免格式错误
  • 流转适配:将内存输出流转换为输入流,直接适配已有的fileUpload方法
  • 资源管理:添加finally块确保输入流被正确关闭,避免资源泄漏

内容的提问来源于stack exchange,提问作者Kannuri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 21:15:18