【问题标题】:How to retain newline character while converting the printstream from XSSF XLSX2CSV class to ByteInputStream?如何在将打印流从 XSSF XLSX2CSV 类转换为 ByteInputStream 时保留换行符?
【发布时间】:2019-04-09 11:32:55
【问题描述】:

我正在使用 Java SAX 解析器从 Excel 中读取数据(使用 XSSF XLSX2CSV 类)并将其加载到 Greenplum 数据库中。我正在使用以下链接中的代码:

http://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java

我从上述代码中捕获 PrintStream 输出,将其转换为 ByteInputStream,然后使用本机批量加载实用程序 - 复制 - 命令将其加载到 Postgres(Greenplum)。

我在 XLSX2CSV 的主要方法中修改了以下内容以捕获打印流并将其转换为字节输入流。

ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream ps = new PrintStream(baos, true, "UTF-8");

// The package open is instantaneous, as it should be.
try (OPCPackage p = OPCPackage.open(xlsxFile.getPath(), PackageAccess.READ)) {
XLSX2CSV xlsx2csv = new XLSX2CSV(p, ps, minColumns);
xlsx2csv.process();
System.out.println(ps);
String data = new String(baos.toByteArray(), StandardCharsets.UTF_8);
System.out.println(data);
byte[] bytes = data.getBytes("UTF8");
ByteArrayInputStream orinput = new ByteArrayInputStream(bytes);
String dbURL1 = "jdbc:postgresql://xxxxx:xxxxx/xxxxx";
String user = "xxxxxx";
String pass = "xxxxxx";
Connection GPConnection = DriverManager.getConnection(dbURL1, user, pass);

 Statement  GPsqlStatement = GPConnection.createStatement();
 String GPStgTableTrunc = "truncate test_table";
 GPsqlStatement.execute(GPStgTableTrunc);
 System.out.print("Load to Greenplum starts "+ 
  Calendar.getInstance().getTime() + "\r\n");

 CopyManager copyManager = new CopyManager((BaseConnection) GPConnection);
copyManager.copyIn("copy test_table from stdin csv",orinput);
System.out.print("Load to Greenplum ends "+ 
Calendar.getInstance().getTime() + "\r\n");

但是在转换为 ByteInputStream 的过程中,换行符似乎丢失了,并且在加载到 Greenplum 时出现以下错误..

ERROR: COPY metadata not found. This probably means that there is a mixture of newline types in the data. Use the NEWLINE keyword in order to resolve this reliably. (seg40 sdw6.gphd.local:1025 pid=101588)

当我打印字符串“数据”时,它似乎有换行符,并且值被正确打印。但是在批量加载到数据库时它不会加载。

如何在上述情况下保留换行符以便正确加载?或者,如果有办法将 printsream 转换为标准输入,那也可以。谢谢!

【问题讨论】:

  • 如何添加新行? \n 或 \r
  • XLSX2CSV 用这一行将它添加到最后一行函数中.. output.append('\n');
  • 添加 \r 也应该有帮助

标签: java apache-poi sax greenplum xssf


【解决方案1】:

尝试:“\r\n”而不是“\n”

ByteArrayOutputStream output = new ByteArrayOutputStream();
output.write("something\r\n"".getBytes());
output.write("something\r\n"".getBytes());

ByteArrayOutputStream input = new ByteArrayInputStream(output.getBytes());
s3.putStream(input);

看起来类似于:

ByteArrayOutputStream/InputStream losing newline characters on S3 Import

在下面添加已尝试使用 PrintStream 的示例代码:

static void printStream() throws Exception {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PrintStream ps = new PrintStream(baos, true, "UTF-8");
        ps.println("test 1");
        ps.println("test 2");
        ps.println("test 3");
        System.out.print(new String(baos.toByteArray()));
    }

正在打印:

test 1
test 2
test 3

【讨论】:

  • 您好,感谢您查看。我将打印流输出直接加载到字节输入流中。所以任何需要添加的东西都应该直接添加到打印流中。所以,我尝试将 output.append('\n') 更改为 output.append('\r\n');,但 append 似乎只需要一个字符。所以我添加了 output.append('\r');如下所示,但不幸的是在每个数据行之后引入了一个空白行。
  • 好的。在已编辑的答案中添加了代码尝试PrintStream 及其相应的输出。如果您分享导致问题的代码会有所帮助
  • 代码在链接里,我是按原样使用的。您可以提供任何 excel 作为输入,它应该能够将其转换并打印为 CSV。这个问题提供了我所做的进一步更改。
猜你喜欢
  • 2013-02-28
  • 2014-02-09
  • 2021-07-19
  • 2015-03-11
  • 2019-03-23
  • 2014-04-16
  • 1970-01-01
  • 1970-01-01
  • 2018-11-19
相关资源
最近更新 更多