2015-08-28 49 views
2

相关的问题: 1. Error in converting txt to xlsx using python的MemoryError而转换到TXT XLSX

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

    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” 和 打印“你好world2” 检查,如果之前的“Hello World”的所有零件都正常运行。

    我检查了代码打印 '世界你好',但不是 '你好world2'

    所以,它真的很可能是 wb.save(output_path)

    引起的问题。

    +0

    有多大的文件? –

    +0

    @PadraicCunningham One是19MB,另一个是32MB。两者都失败。 – user3123767

    +0

    我认为可以安全地说,你有足够的内存,它总是保存你得到的错误? –

    回答

    1

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

    我也建议你安装lxml以提高速度。这些都在文档中涵盖。

    +0

    @Charlie_Clark谢谢你的回应。顺便说一下,我应该如何编辑代码以写入“wb = Workbook(write_only = True)”?我尝试用“wb = Workbook(write_only = True)”和“”wb = openpyxl.Workbook(write_only = True)替换“wb = openpyxl.Workbook()”,但都失败了。 – user3123767

    +0

    对不起,没有代码和文件,我们不能帮助你。必须有其他事情正在进行。 –

    +0

    可能会成为问题的一件事是如果每个单元格都有唯一的字符串。但即使如此,32GB,这应该不是一个问题。 –

    0

    以下三种选择:

    RANGE FOR循环

    可能,这两个enumerate()调用可能存在内存占用为索引必须在嵌套发生的循环。考虑将csv.reader内容传递给列表(可以使用subscriptable)并使用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库

    最后,可以考虑使用,你在Excel中打开CSV并保存为xlsx or xls workbook内置win32com库。请注意,此软件包仅适用于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() 
    
    0

    这里有饥荒预警系统点,你可以考虑:

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

    下面是我的代码:

    #!/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')