Как сохранить символ новой строки при преобразовании потока печати из класса XSSF XLSX2CSV в ByteInputStream? - PullRequest
0 голосов
/ 06 ноября 2018

Я использую анализатор 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), используя собственную утилиту массовой загрузки - copy - command.

Я изменил следующее в основном методе 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)

Когда я печатаю строку 'data', кажется, что она имеет новую строку, и значения выводятся правильно ... однако она не загружается при выполнении массовой загрузки в БД.

Как сохранить символ новой строки в приведенном выше сценарии, чтобы загрузка происходила правильно? Или, если есть способ преобразовать поток печати в стандартный ввод, это тоже работает. Спасибо!

1 Ответ

0 голосов
/ 06 ноября 2018

Попробуйте: "\ 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 теряет символы новой строки при импорте S3

Добавление примера кода, который был опробован в 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
...