>我正在编写一个Java应用程序,将数据从Oracle导出到csv文件
不幸的是,数据的内容可能非常棘手。逗号仍然是delimator,但一行上的一些数据可能是这样的:
| ID | FN | LN | AGE | COMMENT |
|----------------------------------------------------------------|
| 123 | John | Smith | 39 | I said "Hey, I am 5'10"." |
|----------------------------------------------------------------|
所以这是comment
列上的字符串之一:
我说"嘿,我是5'10"。
不开玩笑,我需要在 excel 中显示上面的评论,或者从 Java 生成的 CSV 文件中打开办公室,当然也不能弄乱其他常规转义情况(即常规双引号和元组中的常规逗号)。我知道正则表达式很强大,但是在如此复杂的情况下,我们如何实现目标?
有几个库。下面是两个示例:
❐ Apache Commons Lang
Apache Commons Lang包含一个特殊的类来转义或取消转义字符串(CSV,EcmaScript,HTML,Java,Json,XML): org.apache.commons.lang3.StringEscapeUtils
。
-
转义为 CSV
String escaped = StringEscapeUtils .escapeCsv("I said "Hey, I am 5'10".""); // I said "Hey, I am 5'10"." System.out.println(escaped); // "I said ""Hey, I am 5'10""."""
-
从 CSV 中取消逃脱
String unescaped = StringEscapeUtils .unescapeCsv(""I said ""Hey, I am 5'10"".""""); // "I said ""Hey, I am 5'10"".""" System.out.println(unescaped); // I said "Hey, I am 5'10"."
*您可以从这里下载。
❐ 打开CSV
如果您使用 OpenCSV,则无需担心转义或取消转义,只需写入或读取内容即可。
-
写入文件:
FileOutputStream fos = new FileOutputStream("awesomefile.csv"); OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8"); CSVWriter writer = new CSVWriter(osw); ... String[] row = { "123", "John", "Smith", "39", "I said "Hey, I am 5'10"."" }; writer.writeNext(row); ... writer.close(); osw.close(); os.close();
-
读取文件:
FileInputStream fis = new FileInputStream("awesomefile.csv"); InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); CSVReader reader = new CSVReader(isr); for (String[] row; (row = reader.readNext()) != null;) { System.out.println(Arrays.toString(row)); } reader.close(); isr.close(); fis.close();
*您可以从这里下载。
Excel必须能够处理完全相同的情况。
将这些内容放入Excel中,将它们另存为CSV,然后使用文本编辑器检查文件。 然后,您将知道Excel应用于这些情况的规则。
使 Java 产生相同的输出。
顺便说一下,Excel 使用的格式已发布...
编辑 1:**** 以下是 Excel 的功能
编辑 2:**** 请注意,如果您使用 " 作为外壳,php 的fputcsv
与 excel 完全相同。
rdeslonde@mydomain.com
Richard
"This is what I think"
被转换成这样:
Email,Fname,Quoted
rdeslonde@mydomain.com,Richard,"""This is what I think"""
感谢托尼和保罗的快速反馈,它非常有帮助。我实际上通过POJO找到了解决方案。在这里:
if (cell_value.indexOf(""") != -1 || cell_value.indexOf(",") != -1) {
cell_value = cell_value.replaceAll(""", """");
row.append(""");
row.append(cell_value);
row.append(""");
} else {
row.append(cell_value);
}
简而言之,如果单元格侧面的字符串中有逗号或双引号等特殊字符,则首先通过添加额外的双引号(如""""
)来转义双引号("""
),然后将整个内容放入双引号中(如"""+theWholeThing+"""
)
您还可以查看Python如何编写与Excel兼容的csv
文件。
我相信 Excel 的默认设置是文字引号字符加倍 - 也就是说,文字引号"
写为 ""
.
如果您使用的是CSVWriter。检查您是否没有该选项
.withQuotechar(CSVWriter.NO_QUOTE_CHARACTER)
当我删除它时,逗号按预期显示,而不是将其视为新列
"cell one","cell "" two","cell "" ,three"
将其保存到csv文件并查看结果,因此使用双引号进行转义
重要说明
"cell one","cell "" two", "cell "" ,three"
会给你一个不同的结果,因为逗号后面有一个空格,这将被视为"
String stringWithQuates = """+ "your,comma,separated,string" + """;
这将保留 CSV 文件中的逗号
在 openCSV 中,使用以下方法创建 csvWriter obj,
CSVWriter csvWriter = new CSVWriter(writer, CSVWriter.DEFAULT_SEPARATOR, CSVWriter.DEFAULT_ESCAPE_CHARACTER, CSVWriter.DEFAULT_LINE_END, CSVWriter.DEFAULT_QUOTE_CHARACTER);
在这方面,DEFAULT_QUOTE_CHARACTER
非常重要。如果您想在csv文件中插入任何","或",它将完美运行。