2015-01-06 3 views
2

У меня есть скрипт, который открывает файл шаблона xlsx с помощью openpyxl, а затем делает через каждый из шести листов, добавляет некоторые данные из списков, созданных ранее в скрипте, и меняет формат ячеек ,MemoryError Использование openpyxl для записи 500k + строк

Проблема у меня в том, что будут экземпляры, где на одном листе мне нужно написать 9 столбцов и 500k + строк, и это дает мне MemoryError.

Traceback (most recent call last): 
    File "C:\python27\labs\labs\sqrdist\new_main_ui.py", line 667, in request_and_send_reports 
    x = sqr_pull.main() 
    File "C:\Python27\lib\site-packages\memory_profiler-0.32-py2.7.egg\memory_profiler.py", line 801, in wrapper 
    val = prof(func)(*args, **kwargs) 
    File "C:\Python27\lib\site-packages\memory_profiler-0.32-py2.7.egg\memory_profiler.py", line 445, in f 
    result = func(*args, **kwds) 
    File "C:\python27\labs\labs\sqrdist\sqr_pull.py", line 327, in main 
    os.remove(temp_attach_filepath) 
    File "build\bdist.win32\egg\openpyxl\workbook\workbook.py", line 281, in save 
    File "build\bdist.win32\egg\openpyxl\writer\excel.py", line 214, in save_workbook 
    File "build\bdist.win32\egg\openpyxl\writer\excel.py", line 197, in save 
    File "build\bdist.win32\egg\openpyxl\writer\excel.py", line 109, in write_data 
    File "build\bdist.win32\egg\openpyxl\writer\excel.py", line 134, in _write_worksheets 
    File "build\bdist.win32\egg\openpyxl\writer\worksheet.py", line 281, in write_worksheet 
    File "build\bdist.win32\egg\openpyxl\writer\worksheet.py", line 381, in write_worksheet_data 
    File "build\bdist.win32\egg\openpyxl\writer\worksheet.py", line 404, in write_cell 
    File "build\bdist.win32\egg\openpyxl\xml\functions.py", line 142, in start_tag 
    File "C:\Python27\lib\xml\sax\saxutils.py", line 159, in startElement 
    self._write(u' %s=%s' % (name, quoteattr(value))) 
    File "C:\Python27\lib\xml\sax\saxutils.py", line 104, in write 
    self.flush() 
MemoryError 

Код, который я думаю, что является причиной этого является следующее, где KeywordReport список списков.

ws_keywords = wb.get_sheet_by_name("E_KWs") 
for r, row in enumerate(KeywordReport, start=1): 
    for c, val in enumerate(row, start=1): 
     mycell = ws_keywords.cell(row=r, column=c) 
     mycell.value = val 
     mycell.style = Style(border=thin_border) 

ws_keywords.column_dimensions['A'].width = 60.0 
ws_keywords.column_dimensions['B'].width = 50.0 
ws_keywords.column_dimensions['C'].width = 50.0 
ws_keywords.column_dimensions['D'].width = 15.0 
ws_keywords.column_dimensions['E'].width = 16.0 
ws_keywords.column_dimensions['F'].width = 16.0 
ws_keywords.column_dimensions['G'].width = 16.0 

for ref in ['A1','B1','C1','D1','E1','F1','G1']: 
    cell = ws_keywords.cell(ref) 
    cell.style = Style(font=Font(bold=True),fill=PatternFill(patternType='solid', fgColor=Color('ffd156')), border=thin_border) 

gc.collect() 
del KeywordReport[:] 
gc.collect() 

print "start of save" 
wb.save(attach_filepath) 
gc.collect() 

os.remove(temp_attach_filepath) 
QCoreApplication.processEvents() 

Я посмотрел на http://openpyxl.readthedocs.org/en/latest/optimized.html однако я не думаю, что я могу использовать это, чтобы писать без просто демпинг в новую книгу, но мне нужны данные в моем существующем шаблоне.

Есть ли способ обойти это?

+0

Вы уверены? '>>> a = [1,2,3] >>> del a [:] >>> a []' – samg86

+0

Ах, вы правы, извините. Я удалю свой комментарий. –

ответ

2

500k строк не должно быть слишком большой проблемой. Но я думаю, это также зависит от количества листов, которые у вас есть. Сколько у вас памяти в системе?

Установка lxml будет быстрее (как и для создания любых стилей за пределами циклов), но я бы не ожидал, что это значительно снизит использование памяти.

Если вам нужно скопировать данные из существующей книги, вы можете подумать об использовании отдельной книги для изменений, которые позволят вам уменьшить память, используя как чтение, так и запись. Дальнейшее обсуждение, вероятно, лучше всего в списке рассылки.

+0

Системная память составляет 8 ГБ, поэтому должно быть хорошо, я думаю. Я пробую несколько разных способов сделать это, и так будет обратная связь, если я смогу найти решение и опубликовать в списке рассылки, если нет. Благодаря! – samg86

+0

Память является только проблемой при сохранении файлов? У вас много текста в файлах? Не могли бы вы привести пример данных, которые вы добавляете? –

+0

Правильно, только при сохранении. Существует действительно много текста, каждая ячейка содержит строку около 30-50 символов. – samg86

Смежные вопросы