java - 在获取多行期间使用 spring-jdbctemplate 的 csv 输出

标签 java spring csv spring-jdbc

我正在使用 spring jdbctemplate 与 Oracle 数据库交互。 为了获取给定条件的多行,我想将结果存储在以列名称作为标题的 csv 文件中。

我尝试了几种方法 -

List<Bean> list = jdbcTemplate.query('query','parameters',customizedrowmapper);

在customizedrowmapper中,我从结果集中获取行并设置Bean类中的字段。我找不到任何简单的方法将 bean 转换为 csv 文件。因为我无权访问 bean 类代码。

我发现的第二种方法是使用 opencsv 库将 ResultSet 直接写入 csv 文件,如下所示。

CSVWriter wr = new CSVWriter(new FileWriter("Report.csv"), ','); wr.writeAll(rs, true); wr.flush(); wr.close();

这工作正常,但在写入 csv 时会跳过一行。我尝试了一些查询。手动时,我可以在结果中看到 4 行,但在 CSV 中,它只存储三行。有人遇到过类似的问题吗?

或者我们可以通过任何其他方式实现相同的目的,而无需手动从 ResultSet 获取每条记录并将其制成逗号分隔的字符串并存储在文件中。

最佳答案

此代码保存查询结果并将其作为 csv 文件返回(您可以使用端点下载它)。但是,如果您不需要将其返回给 Controller 中的用户,则可以轻松地将所有数据转发到 FileOutputStream

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

@RestController
@RequestMapping("/api/report")
public class UserReportController {
    private JdbcTemplate jdbcTemplate;

    public UserReportController(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    private static String ALL_USERS_QUERY = "select * from users";

    @GetMapping("/all-users")
    public void allUsers(HttpServletResponse response) throws IOException {
        response.setContentType("text/csv");
        jdbcTemplate.query(ALL_USERS_QUERY, new StreamingCsvResultSetExtractor(response.getOutputStream()));
    }


    class StreamingCsvResultSetExtractor
        implements ResultSetExtractor<Void> {

        private char DELIMITER = ',';

        private final OutputStream os;

        
        public StreamingCsvResultSetExtractor(final OutputStream os) {
            this.os = os;
        }

        @Override
        public Void extractData(final ResultSet rs) {
            try (PrintWriter pw = new PrintWriter(os, true)) {
                final ResultSetMetaData rsmd = rs.getMetaData();
                final int columnCount = rsmd.getColumnCount();
                writeHeader(rsmd, columnCount, pw);
                while (rs.next()) {
                    for (int i = 1; i <= columnCount; i++) {
                        final Object value = rs.getObject(i);
                        String strValue = value == null ? "" : value.toString();
                        pw.write(strValue.contains(",") ? "\"" + strValue+ "\"" : strValue);
                        if (i != columnCount) {
                            pw.append(DELIMITER);
                        }
                    }
                    pw.println();
                }
                pw.flush();
            } catch (final SQLException e) {
                throw new RuntimeException(e);
            }
            return null;
        }

        private void writeHeader(final ResultSetMetaData rsmd,
                                 final int columnCount, final PrintWriter pw) throws SQLException {
            for (int i = 1; i <= columnCount; i++) {
                pw.write(rsmd.getColumnName(i));
                if (i != columnCount) {
                    pw.append(DELIMITER);
                }
            }
            pw.println();
        }
    }

}

关于java - 在获取多行期间使用 spring-jdbctemplate 的 csv 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39909715/

相关文章:

java - 使用不同的事务属性调用 Spring Bean 的方法?

java - ORA-01000 - 超出最大打开游标数 - Spring JDBC 3.2.5

python - 编辑代码以根据条件创建过滤器,然后剥离条件

java - 在 Java 8 中展开多个可选变量

java - 在单独安装 MYSQL 的同时使用 XAMPP- phpmyadmin

java - 在 BottomNavigationView 中禁用重新选择

java - 覆盖来自外部库的 bean

python - 使用 Python CSV 模块读取带有 BOM 的 UTF-8 会导致不需要的额外字符

python - 从 csv 文件中删除不需要的值的快速、准确、可靠的方法

java - 在文件 jgrasp 中找不到主要方法、小程序或 Midlet