我尝试将计算机上的所有Excel文件转换为CSV文件(逐页)。一些.xlsx文件非常庞大(超过100MB)。我还有几个问题:
1.我删除非unicode字符的功能非常慢
2.我不确定我是否正确使用了openpyxl的迭代,因为我还在使用大量内存而且我担心如果我真的让这个东西运行,它会出现内存错误
另外,一般来说,寻找任何编码帮助,因为我对代码一般都是新手。
import csv
from formic import FileSet
from openpyxl import load_workbook
import re
from os.path import basename
import os
import string
def uclean(s): # Clean out non-unicode chars for csv.writer - SLOW
try:
return ''.join(char for char in s if char in string.printable).strip()
except:
return ''
def fclean(s): # Clean out non-filename-safe chars
return ''.join([c for c in s if re.match(r'\w', c)])
xlsx_files = FileSet(directory='C:\\', include='**\\*.xlsx') # the whole computer's excel files
for filename in xlsx_files:
wb = load_workbook(filename, use_iterators=True, read_only=True) # This is still using > 600 MBs
for sheet in wb.worksheets:
i = wb.worksheets.index(sheet)
bf = os.path.splitext(
basename(filename))[0]
sn = fclean(str(wb.get_sheet_names()[i]))
f = bf + '_' + sn + '.csv'
if not os.path.exists(f):
with open(f, 'wb') as outf:
out_writer = csv.writer(outf)
for row in sheet.iter_rows():
out_writer.writerow([uclean(cell.value) for cell in row])
答案 0 :(得分:1)
使用encode
会更快:
#lines is some French text
In [80]: %timeit [s.encode('ascii', errors='ignore').strip() for s in lines]
10000 loops, best of 3: 15.3 µs per loop
In [81]: %timeit [uclean(s) for s in lines]
1000 loops, best of 3: 522 µs per loop
至于你的openpyxl问题,我将不得不回复你 - 我现在唯一能想到的是,一次只能加载一个工作表而不是整个工作簿。请注意,由于wb
是循环的局部,因此每次迭代都会被新对象替换,因此它不会像您一样使用< em>每个文件的附加 600mb内存。
答案 1 :(得分:1)
只读模式确实一次读取一个单元格,因此内存使用量最小。但是,基于您想要将所有文本转换为ascii,我想知道原因是Excel文件中有很多文本。 Excel采用优化,它将所有字符串存储在单元格引用的大列表中。如果你有很多独特的字符串,那么它们可能是任何内存问题的根源,因为我们必须将它们保存在内存中才能读取它们。
关于转换:您可以使用包装器保存为UTF-8,因此删除任何内联编码。