我有一个包含复杂数据的类似 csv 的文件,想在 LibreOffice Calc、Microsoft Excel 或其他电子表格程序中打开它。
我所说的 csv-喜欢:
- 字段由 ASCII 分隔单位分隔符
\037
//\x1F
31 十进制(常规 csv 将使用,
)。 - 记录被分开无效的字节
\0
(常规 csv 将使用\n
)。 - 字段包含几乎任意的数据,例如(不成对的)引号(
"
,'
)和换行符(\r
,\n
,或两者)。沒有引述机制,因此字段和记录分隔符不能存储在字段内。
转换为电子表格文档后,我想要保留所有数据与输入完全相同。如果文件中的字段包含换行符、引号或任何其他特殊符号,则输出中的相应单元格也应如此。这意味着结果电子表格中的所有单元格都必须格式化为文本。
保留原始数据非常重要。由于文件很大,我无法手动查看结果并确定转换是否成功或数据是否损坏。
由于数据是由 bash 脚本生成的,如果该脚本也可以进行转换就好了。欢迎使用其他自动解决方案。转换为常规 csv 文件可能可以使用 csv 的引用机制,但除非 Calc 或 Excel 中有可靠的一键式 csv 导入,否则这是不可能的。据我所知,手动导入 csv 文件需要相当长的时间,而且容易出错(在 Calc 和 Excel 中,您必须手动指定分隔符、引用机制、列数据类型 = 文本。在较新的 Excel 版本中,您还必须处理不需要的数据连接)。
是否有一个工具(如ssconvert
),或一个简单的脚本,或 Calc / Excel 中的选项来
转换我的 csv 类文件未损坏的转换为任何电子表格格式(ods、odf、xls、xlxs)?
答案1
我使用 python 库解决了我的问题写入器以及一个小的自定义脚本。
使用安装库
pip install XlsxWriter
将以下脚本保存为csvlike2xlsx.py
。
#! /usr/bin/env python3
# converts an unquoted csv file with custom delimiters into a xlsx spreadsheet
# such that all data is shown exactly as in the text file (no processing of numbers, dates, formulas, ...)
import sys
import xlsxwriter
# delimiters / separators
fs="\037" # field separator is ASCII unit separator (US)
rs="\000" # record separator is ASCII null byte (NUL)
workbook = xlsxwriter.Workbook('out.xlsx', {
'strings_to_numbers': False,
'strings_to_formulas': False,
'strings_to_urls': False,
'constant_memory': True})
textformat = workbook.add_format()
textformat.set_num_format('@') # text format
# optional display option, useful when dealing with lots of linebreaks inside fields
# textformat.set_text_wrap()
for argpos, infilename in enumerate(sys.argv[1:], start=1):
with open(infilename, 'r', newline='') as infile:
infilecontent = infile.read();
worksheet = workbook.add_worksheet(str(argpos))
maxcol = 0
for row, record in enumerate(infilecontent.split(rs)):
if len(record) > maxcol:
maxcol = len(record)
worksheet.set_column(0, maxcol, None, textformat)
for col, field in enumerate(record.split(fs)):
worksheet.write(row, col, field)
workbook.close() # writes file to disk
然后使用以下方法在你的文件上运行脚本
python3 csvlike2xlsx.py file [...]
结果将被写入到out.xlsx
包含每个转换后的 csv 文件的一个表/选项卡的文件中。
改进空间
- 对于转换,输入文件会被完全读入内存。我认为这不应该是个问题,因为无论如何都不应该将大于内存的文件导入 Excel。但是,如果您知道在 Python 中高效读取直到下一个(记录或字段)分隔符的快速解决方法,请随意编辑此答案。根据我的研究,只有预定义的方法可以使用预定义的分隔符(文件结尾)、、、和(通用行结尾)读取下一
''
行'\n'
,请参阅'\r'
'\r\n'
None
记录open(..., newline=...)
。 - 生成的 xlsx 文件中的表已编号。第一个 csv 文件的表名为
1
,第二个 csv 文件的表名为2
,依此类推。如果表名是 csv 文件名就好了。但是,Excel 对表名有很多限制(长度限制为 32,无特殊符号,唯一名称),因此并不总是可以使用 csv 文件名。