2015-08-28 45 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')