将txt转换为xlsx时出现MemoryError

时间:2015-08-28 12:50:03

标签: python python-2.7 openpyxl

相关问题: 1. Error in converting txt to xlsx using python

  1. Converting txt to xlsx while setting the cell property for number cells as number
  2. 我的代码是

        import csv
        import openpyxl
    
        import sys
    
    
        def convert(input_path, output_path):
            """
            Read a csv file (with no quoting), and save its contents in an excel file.
            """
            wb = openpyxl.Workbook()
            ws = wb.worksheets[0]
    
            with open(input_path) as f:
                reader = csv.reader(f, delimiter='\t', quoting=csv.QUOTE_NONE)
                for row_index, row in enumerate(reader, 1):
                    for col_index, value in enumerate(row, 1):
                        ws.cell(row=row_index, column=col_index).value = value
            print 'hello world'
    
            wb.save(output_path)
    
            print 'hello world2'
    
    
        def main():
            try:
                input_path, output_path = sys.argv[1:]
            except ValueError:
                print 'Usage: python %s input_path output_path' % (sys.argv[0],)
            else:
                convert(input_path, output_path)
    
    
        if __name__ == '__main__':
            main()
    

    此代码有效,但某些输入文件除外。我无法找到导致此问题的输入txt和输入txt之间的区别。

    我的第一个猜测是编码。我尝试使用BOM将输入文件的编码更改为UTF-8和UTF-8。但这失败了。

    我的第二个猜测是它使用了太多的内存。但我的电脑配有32 GB RAM的SSD。

    那么也许这段代码没有充分利用这个RAM的容量?

    我该如何解决这个问题?

    enter image description here 编辑:我添加了那一行     打印' hello world' 和     打印' hello world2' 在“你好世界”之前检查是否所有部件都是'运行正确。

    我检查了代码打印' hello world',但没有' hello world2'

    所以,看起来真的很可能     wb.save(output_path)

    造成了这个问题。

3 个答案:

答案 0 :(得分:1)

openpyxl具有用于读取和写入大文件的优化模式。 wb = Workbook(write_only=True)将启用此功能。

我还建议您安装lxml以提高速度。这些都包含在文档中。

答案 1 :(得分:0)

以下是三种选择:

ROPE FOR LOOP

可能两个enumerate()调用可能有内存占用,因为索引必须在嵌套for循环中发生。考虑将csv.reader内容传递到列表(可订阅)并使用range()。虽然可以肯定的是,从Python 3开始,每个range()调用(与已弃用的xrange相比)在内存中创建自己的列表也可能效率不高。

with open(input_path) as f:
  reader = csv.reader(f)

  row = []
  for data in reader:
      row.append(data)

  for i in range(len(row)):
      for j in range(len(row[0])):
          ws.cell(row=i, column=j).value = row[i][j]

优化的作家

OpenPyXL甚至警告即使不分配值滚动单元格也会将它们保留在内存中。作为解决方案,您可以使用Optimized Writer使用csv.reader生成的row列表。此路由将整行附加到只写工作簿实例中:

from openpyxl import Workbook
wb = Workbook(write_only=True)
ws = wb.create_sheet()

i = 0
for irow in row:
   ws.append(['%s' % j for j in row[j]])
   i += 1

wb.save('C:\Path\To\Outputfile.xlsx') 

WIN32COM LIBRARY

最后,考虑使用内置的win32com库,在Excel中打开csv并保存为xlsx or xls workbook。请注意,此程序包仅适用于Python Windows安装。

import win32com.client as win32

excel = win32.Dispatch('Excel.Application')

# OPEN CSV DIRECTLY INSIDE EXCEL
wb = excel.Workbooks.Open(input_path)
excel.Visible = False
outxl=r'C:\Path\To\Outputfile.xlsx'

# SAVE EXCEL AS xlOpenXMLWorkbook TYPE (51)
wb.SaveAs(outxl, FileFormat=51)
wb.Close(False)
excel.Quit()

答案 2 :(得分:0)

您可以考虑以下几点:

  1. 检查/tmp文件夹,默认文件夹中创建的tmp文件;
  2. 您的代码正在使用该文件夹中的完整空间。要么增加该文件夹,要么在创建工作簿时更改tmp文件路径;
  3. 我在内存中用于执行我的任务并且它有效。
  4. 以下是我的代码:

    #!/usr/bin/python
    import os
    import csv
    import io
    import sys
    import traceback
    from xlsxwriter.workbook import Workbook
    
    
    fileNames=sys.argv[1]
    
    try:
        f=open(fileNames, mode='r')
        workbook = Workbook(fileNames[:-4] + '.xlsx',{'in_memory': True})
        worksheet = workbook.add_worksheet()
        workbook.use_zip64()
        rowCnt=0
        #Create the bold style for the header row
        for line in f:
            rowCnt = rowCnt + 1
            row = line.split("\001")
            for j in range(len(row)):
                worksheet.write(rowCnt, j, row[j].strip())
        f.close()
        workbook.close()
        print ('success')
    except ValueError:
        print ('failure')