在Excel 2007中导入带有换行符的CSV文件

154

我正在开发一个功能,将搜索结果导出到CSV文件中以在Excel中打开。其中一个字段是自由文本字段,可能包含换行符、逗号、引号等等。为了解决这个问题,我已经用双引号(")将该字段括起来。

然而,当我将数据导入Excel 2007中,并设置适当的分隔符和文本限定符为双引号时,换行符仍然会在换行处创建新记录,而我希望在单个单元格中看到整个文本字段。

我也尝试用CR/LF (\r\n)替换为只有CR (\r),再用只有LF (\n),但是没有成功。

有没有其他人遇到过这种情况,如果有,你们是如何解决的呢?

TIA,
-J

编辑:
这里是我手动编写的快速文件,用于复制该问题。

  

ID,Name,Description
  "12345","Smith, Joe","嘿。
  我叫乔。”

当我将其导入Excel 2007时,我得到一个标题行和两个记录。请注意,"Smith, Joe"中的逗号被正确处理。只有换行符会导致问题。


我已经在Notepad++中查看了CSV文件,一切似乎都是正确的。我有其他带逗号的字段,它们被正确导入了。只是换行符引起了问题。 - jeremyalan
7
我对包含多行数据的UTF8 .csv文件和Excel存在问题。最终我只能将文件上传至Google文档,然后在Google表格中打开并下载为.xls文件。这样对我来说效果很好。 - creuzerm
25个回答

65

Excel(至少在XP上的Office 2007版本中)根据CSV文件是通过文件->打开菜单打开还是双击浏览器中的文件而表现不同。

我有一个UTF-8编码的包含一些单元格换行符的CSV文件。如果我从Excel的文件->打开菜单打开此文件,则会弹出“导入CSV”向导,并且文件无法正确导入:即使加了引号,换行符也会开始新的行。如果我在资源管理器窗口中双击它打开,则不需要使用向导即可正常打开。


2
有什么办法可以获得与双击相同的设置吗? - Michiel Thalen
9
没错!多奇怪。 - David
5
如果您使用德语区域设置,为了使双击功能正常工作,您需要在CSV文件中使用分号 (;) 而不是逗号 (,)。 - user1859022
3
对我来说这个方法不起作用。使用“,”作为分隔符,双击打开的所有内容都在同一列中显示。使用“;”作为分隔符导入时,除了多行文本字段以外,其他都被正确导入,但多行文本字段被导入为多个记录。我使用的是Excel 2010。 - Andrej Adamenko
2
@user1859022 我也同意在匈牙利语环境下使用这种方法。实际上,任何使用逗号作为小数分隔符的语言环境都必须使用分号作为字段分隔符,以便双击打开 CSV 文件时能正常工作。 - robotik
显示剩余3条评论

58

所有建议的解决方案都没有对我起作用。

真正有效的方法是(适用于任何编码):

从csv文件中复制/粘贴数据(在文本编辑器中打开),然后执行“文本转列”--> 数据会被不正确地转换。

下一步是前往最近的空列或空工作表,再次复制/粘贴(与您已经在剪贴板中拥有的内容相同)--> 现在自动魔法般地工作。


2
在我的情况下,这种方法有效:它正确地将CSV折叠为单个记录,但删除了换行符后一个字段中的所有数据。 - Lilienthal
1
这个可以运行,有什么想法为什么从Excel导入CSV时不起作用? - Rafael Sisto
2
我可以确认这个有效,你甚至可以在不重复“文本分列”命令的情况下在不同的工作表中粘贴更多数据。如果你需要导入多个文件,这非常有用。 - Alex
1
为什么这个方法可行,但是打开CSV文件或者使用所有正确设置的文本数据添加却不行呢?感谢您的提示。复制/粘贴团队需要与数据导入团队交流! - alexGIS
3
天哪,这真的有效。而且它的原理也有点讲得通。在Excel中使用“文本分列”功能时,它会记住设置并自动转换。当你已经将文本分隔到各行时,它将逐行查看并忽略新行。我认为微软应该包括一个复选框,无论是保留行为还是重新扫描数据。我不在乎,...它真的有效。 - user853710
显示剩余6条评论

32

如果您手动处理,请下载LibreOffice并使用LibreOffice Calc导入CSV文件。它在这方面的表现比我尝试过的任何Excel版本都要好得多,如果需要转移到Excel之后,它可以保存为XLS或XLSX。

但是,如果您被困在Excel中并需要更好的解决方案,似乎有一种方法。这似乎取决于地区设置(在我看来很愚蠢)。我没有Excel 2007,但我有Excel 2010,并且给出了示例:

ID,Name,Description
"12345","Smith, Joe","Hey.
My name is Joe."

无法正常工作。我在记事本中编写了它并选择“另存为...”,在保存按钮旁边,您可以选择编码方式。我按建议选择了UTF-8,但没有成功。然而,将逗号改为分号对我很有用。我没有改变其他任何东西,它就能正常工作了。因此,我将示例更改为以下形式,并在记事本中保存时选择UTF-8编码:

ID;Name;Description
"12345";"Smith, Joe";"Hey.
My name is Joe."

但是有一个限制!它只有在双击CSV文件以在Excel中打开它的情况下才能正常工作。如果我尝试从文本导入数据并选择这个CSV,那么它仍然无法处理带引号的换行符。

但是还有另一个限制!工作字段分隔符(在原始示例中为逗号,在我的情况下为分号)似乎取决于系统的区域设置(在控制面板-区域和语言下设置)。在挪威,逗号是小数分隔符。Excel似乎避免使用这个字符,而倾向于使用分号。我可以访问另一台设置为英国英语区域设置的计算机,在那台计算机上,第一个逗号分隔符的示例可以很好地工作(只有在双击时),而分号分隔符的示例实际上失败了!这就是互操作性。如果您想在网上发布此CSV,并且用户可能拥有Excel,则必须发布两个版本,并建议人们检查哪个文件给出正确的行数。

因此,我能够收集到使其正常工作的所有细节如下:

  1. 文件必须保存为UTF-8格式,并带有BOM,这是Notepad在选择UTF-8时执行的操作。我尝试过不带BOM的UTF-8格式(可以在Notepad++中轻松切换),但是双击文档失败了。
  2. 您必须使用逗号或分号分隔符,但不能使用区域设置中的小数分隔符。也许其他字符也可以使用,但我不知道哪些。
  3. 必须使用“”字符引用包含换行的字段。
  4. 我在文本字段和记录分隔符中都使用了Windows行结束符(\r\n),这很有效。
  5. 必须双击文件以打开它,从文本导入数据无法工作。

希望这对某人有所帮助。


是的,每次导入文本或进行文本分列时,您都需要重新校准复制/粘贴在给定会话中的工作方式。它甚至适用于您创建的新工作簿,直到您关闭Excel。这也可能很令人沮丧。一旦您使用特定的分隔符进行导入,即使您只想将一个句子粘贴到单元格中,它也会按照该分隔符分隔您的文本。您必须使用制表符重新导入,或重新启动Excel才能停止它。 - robotik
你的技巧似乎真的很有效。但是看起来分号与解决方案无关。问题在于,Excel根据区域设置不同处理CSV文件。我来自德国,对我而言,来自Excel的CSV文件总是使用分号而不是逗号(原因是在德国,小数分隔符是逗号而不是点)。真正的解决方案似乎是,Excel完全不同于所有其他文本文件加载CSV文件。因此,包含引号之间换行符的CSV文件似乎可以工作。所有其他文本文件都不行。 - Martini Bianco
@Martini,是的,我有挪威版的Excel,我们也使用逗号作为小数分隔符,所以我已经提到这取决于区域设置(尽管我称之为语言环境)。也许我应该重新表达一下以便更清楚。 - ketil
1
这是所有使用逗号作为小数分隔符的地区的人们的答案。请注意,对于这些地区,Excel也使用分号作为公式参数分隔符(=FOO(1;2)而不是=FOO(1,2)),但很明显,Excel将其应用于文件格式解析器是不正确的(哪个程序会根据语言环境解析标准文件格式?) - leemes
这个问题是关于Excel的,而不是LibreOffice。 - Zimba
显示剩余5条评论

26

我终于找到了问题所在!

原来我们是使用Unicode编码而不是ASCII或UTF-8来写文件。改变FileStream的编码似乎解决了问题。

谢谢大家提供的所有建议!


30
ASCII编码对于我来说似乎不能解决这个问题(尽管我使用的是MacOS),并且我的字段被引用,没有前导空格。相同的文档在Google Docs中可以很好地导入。真是令人沮丧。顺便说一下,“Unicode”编码的文本文件不存在。它必须是Unicode实现之一(例如UTF-8、UTF-16、UTF-32等)。 - Ben
11
谢谢您提供的解决方案。我仍然很好奇答案是什么,所以我尝试在Excel中创建一个带有换行符的csv并查看它保存了什么。结果发现Excel在单元格中仅使用换行符来换行。如果我尝试在记事本中创建相同的csv,则会使用换行符和回车符来进行换行。因此,对于单个单元格中的换行符,请确保仅使用换行符(LF或\n),而不是回车符(CR或\r)。 Excel确实同时使用两者来终止一行。 - xr280xr
1
ASCII编码对我也没有解决这个问题——Excel 2000,Windows 7。 - ChrisJJ
1
对于Macintosh上的OS X,请保存为“Windows逗号分隔(csv)”。这将添加换行符而不是换行符。它将在“特殊格式”下拉菜单中列出。 - taco
应该使用哪种 Unicode 编码(UTF-8、UTF-16)? - Andrej Adamenko
尽量使用UTF-8,UTF-16正在开发用于双字节字符,而这些在几乎所有语言中都非常罕见。 - htm11h

12

使用Google Sheets并导入CSV文件。

然后您可以将其导出以在Excel中使用。


1
好的提示!如果您可以上传CSV文件到第三方服务(即非机密数据),那么这是最方便的转换方法。请注意,在导入时可能需要手动设置分隔符。并且,您可能需要调整生成的Excel文件中的单元格大小以正确显示。 - m000
还适用于 Office 365 中浏览器中的 Excel。我无法使用桌面版 Excel 应用程序正确打开带有单元格内换行符的 CSV(尝试了此页面上的大多数建议),但是 office.com 上的 Excel 可以正确打开它。 - georg w.
1
在我的情况下,这是唯一的解决方案,因为我必须稍后重新导入更改后的CSV到我的数据库中,只有Google Sheets能够正确解释嵌入文本中的换行符。非常感谢! - Rogério Dec
这个有效。没得说。 - Maarten

7

简短回答

使用Notepad++删除换行符(\n)。Excel仍然可以识别回车符(\r)来分隔记录。

长篇回答

如上所述,CSV字段内支持换行符,但Excel并不总是处理得很好。我曾遇到过一个第三方CSV文件,可能存在编码问题,但即使进行编码更改也无法改善这个问题。

对我有用的方法是删除所有换行符(\n)。这将把字段合并成单个记录,假设您的记录是由回车和换行(CR/LF)组合分隔的。Excel将正确导入文件,并通过回车符识别新记录。

显然,更干净的解决方案是首先将真实的换行符(\r\n)替换为临时字符组合,将换行符(\n)替换为您选择的分隔字符(例如,在分号文件中使用逗号),然后再将临时字符替换为真实的换行符。


1
我遇到了相反的情况:行之间有\n,值内部有\r\n。我只是在Notepad++中去掉了后者。 - Rarst
我尝试了两种方法,但都无法在Office专业增强版2013上运行。 - m1m1k
1
仅为完整起见,我还有另一种情况——值中的\n,行之间的\r\n——删除\r使我能够正确使用“文本分列”。 - GriffoGoes

6
可以使用以下步骤在支持Power Query的Excel版本中轻松导入多行CSV文件(已在Excel 365版2207中测试):
  1. 进入“数据”选项卡
  2. 单击功能区上的“从文本/CSV”按钮
  3. 选择文件并单击导入
  4. 单击“转换数据”以打开Power Query编辑器
  5. 单击Power Query编辑器功能区上的“数据源设置”
  6. 单击“更改源”
  7. 从“行结束符”下拉菜单中选择“忽略带引号的换行符”。
  8. 单击确定 -> 关闭 -> 关闭并加载

尽管默认情况下选择了“忽略引用行断点”,但是你的提示起作用了 - 在打开这个对话框后再次关闭。谢谢! - undefined

5
如果字段包含前导空格,Excel会将双引号视为文本限定符而忽略它。解决方法是在逗号(字段分隔符)和双引号之间消除前导空格。例如:
错误的格式:
Name,Title,Description
"John", "Mr.", "My detailed description"
正确的格式:
Name,Title,Description
"John","Mr.","My detailed description"

3
我同意,但我的输出中没有前导空格。有什么想法吗? - jeremyalan
我们需要换行:( - Luke

4
如果有人偶然发现这个帖子并正在寻找一个明确的答案,那么请看下面的步骤(感谢提到LibreOffice的人):
1) 安装LibreOffice 2) 打开Calc并导入文件 3) 我的文本文件中,字段用逗号分隔,字符字段用引号括起来 4) 另存为ODS文件 5) 在Excel中打开ODS文件 6) 另存为 .xls(x) 格式 7) 完成。 8) 这对我完美地起作用,并且节省了我很多时间!

3
无需保存为ODS格式,LibreOffice可以直接保存为xls(x)格式。 - robotik
很遗憾,这仍然是处理无法通过剪贴板处理的大型数据文件的唯一可靠解决方案。 - Marcel

4

概述

距离最初的帖子已经过去近10年,Excel在导入CSV文件方面并未有所改善。不过,我发现它在导入HTML表格方面要好得多。因此,我们可以使用Python将CSV转换为HTML,然后将生成的HTML导入Excel。

这种方法的优点是:(a) 它可靠地工作,(b) 您不需要将数据发送到第三方服务(例如Google表格),(c) 对于大多数用户而言,无需安装额外的“重若鸿毛”的软件(如LibreOffice、Numbers等) ,(d) 比处理CR/LF字符和BOM标记更高级别,(e) 无需调整区域设置。

步骤

只要安装了Python 3,以下步骤就可以在任何类似bash的shell上运行。虽然Python可以直接读取CSV,但csvkit用于进行中间转换为JSON。这样我们就可以避免在Python代码中处理CSV的复杂性。

首先,将以下脚本另存为json2html.py。该脚本从stdin读取JSON文件,并将其转储为HTML表格:

#!/usr/bin/env python3
import sys, json, html

if __name__ == '__main__':
    header_emitted = False
    make_th = lambda s: "<th>%s</th>" % (html.escape(s if s else ""))
    make_td = lambda s: "<td>%s</td>" % (html.escape(s if s else ""))
    make_tr = lambda l, make_cell: "<tr>%s</tr>" % ( "".join([make_cell(v) for v in l]) )
    print("<html><body>\n<table>")
    for line in json.load(sys.stdin):
        lk, lv = zip(*line.items())
        if not header_emitted:
            print(make_tr(lk, make_th))
            header_emitted = True
        print(make_tr(lv, make_td))
    print("</table\n</body></html>")

然后,使用虚拟环境安装csvkit,并使用csvjson将输入文件提供给我们的脚本。最好使用-I参数禁用单元格类型猜测:

$ virtualenv -p python3 pyenv
$ . ./pyenv/bin/activate
$ pip install csvkit
$ csvjson -I input.csv | python3 json2html.py > output.html

现在,output.html 可以导入Excel。单元格中的换行符将被保留。
可选地,您可能希望清理您的Python虚拟环境:
$ deactivate
$ rm -rf pyenv

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接