2013-05-17 3 views
4

Мне очень сложно редактировать некоторые файлы Excel с помощью PHP и python.xlrd сбой при чтении файла .xls, измененного PHPExcel

Я изначально делал все на PHP с помощью PHPExcel, но я обрабатывал очень большие файлы, и PHPExcel разбился, когда у него закончилась нехватка памяти. Поэтому я изменил его, чтобы выполнить некоторую работу с помощью PHP, а остальное - с помощью python.

Так процесс:

  • Разбор XML отправил в PHP скрипт
  • Вставка строк в Excel (.xls) файлов на основе XML-данных
  • Pass файл (.xls) и XML-данных в сценарий python для заполнения электронной таблицы
  • ex. python upload.py Example.xls data.xml вызывается PHP
  • питон скрипт использует xlrd, xlwt и xlutils для заполнения Excel файл

Проблема у меня в том, что если сценарий питона изменяет регулярный .xls файл, который я создал вручную, это работает отлично. Но как только PHP Excel изменяет файл Excel, сценарий питона производит следующее сообщение об ошибке:

_locate_stream(Workbook): seen 
    0 5 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
20 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
100= 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 
120 4 4 4 4 4 4 4 4 4 4 4 4 4 3 2 2 
File "upload.py", line 63, in <module> 
workbook_readonly = open_workbook(excel,formatting_info=True,on_demand=True) 
File "/home/student/eamorde/public_html/dining/xlrd/__init__.py", line 435, in open_workbook 
ragged_rows=ragged_rows, 
File "/home/student/eamorde/public_html/dining/xlrd/book.py", line 87, in open_workbook_xls 
ragged_rows=ragged_rows, 
File "/home/student/eamorde/public_html/dining/xlrd/book.py", line 619, in biff2_8_load 
cd.locate_named_stream(UNICODE_LITERAL(qname)) 
File "/home/student/eamorde/public_html/dining/xlrd/compdoc.py", line 390, in locate_named_stream 
d.tot_size, qname, d.DID+6) 
File "/home/student/eamorde/public_html/dining/xlrd/compdoc.py", line 418, in _locate_stream 
raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s])) 
xlrd.compdoc.CompDocError: Workbook corruption: seen[2] == 4 

Так я вырыл через исходный код xlrd и нашел линию, которая производит ошибку:

def _locate_stream(self, mem, base, sat, sec_size, start_sid, expected_stream_size, qname, seen_id): 
    # print >> self.logfile, "_locate_stream", base, sec_size, start_sid, expected_stream_size 
    s = start_sid 
    if s < 0: 
     raise CompDocError("_locate_stream: start_sid (%d) is -ve" % start_sid) 
    p = -99 # dummy previous SID 
    start_pos = -9999 
    end_pos = -8888 
    slices = [] 
    tot_found = 0 
    found_limit = (expected_stream_size + sec_size - 1) // sec_size 
    while s >= 0: 
     if self.seen[s]: 
      print("_locate_stream(%s): seen" % qname, file=self.logfile); dump_list(self.seen, 20, self.logfile) 
      raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s])) 

Последней линией является та, которая поднимает исключение:

raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s])) 

Может ли это объяснить это? Файл не поврежден, поскольку открытие его в Excel отлично работает, но xlrd, похоже, не может его прочитать.

Мой PHP скрипт выполняет следующие действия (грубый эскиз):

$phpExcel = new PHPExcel(); 
$file = "MyFile.xls"; 
$reader = new PHPExcel_Reader_Excel5(); 
$phpExcel = $reader->load($file); 
//(... insert rows based on xml) 
$writer = new PHPExcel_Writer_Excel5(); 
$writer->save('MyFile.xls'); 
exec("python upload.py MyFile.xls data.xml"); 

Если кто-нибудь знает, почему это может происходить или даже лучшее решение моих проблем (проблемы с памятью PHPExcel) было бы весьма признателен.

Редактировать: Исходный код файла, который вызывает ошибку, можно найти here.

Редактировать: Я создал пример, в основном взял мой файл excel и удалил любую идентифицирующую информацию. Попробуйте сами, см. Раздел here.

+0

Он вызывает исключение только тогда, когда 'self.seen [s]:' оценивает значение 'True'. Так распечатайте «я».[s] 'и' s' и посмотреть, где в файле он задыхается. Затем обновите свой вопрос с помощью этих деталей. –

+0

Вы имеете в виду изменить файл xlrd, чтобы сделать это? И s равно 2, если вы посмотрите на ошибку, это показывает «Коррекция рабочей книги: увидено [2] == 4' –

+0

Заявление прямо под' if self.seen [2]: 'напечатало следующее:' 0 5 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 100 = 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 120 4 4 4 4 4 4 4 4 4 4 4 4 4 3 2 2 «Но это трудно прочитать здесь, я отредактирую свой вопрос. –

ответ

3

У меня такая же ошибка с одним из моих файлов .xls (excel может открыть их просто отлично, но xlrd не удается). Как я думаю, массив Compdoc.seen отслеживает уже прочитанные сектора «FAT». В моем случае блок чтения Root Entry (SSCS) получает все сектора, отмеченные как видимые, что приводит к увеличению рейса в будущем. U может попытаться найти ошибку в логике чтения секторов и внести свой вклад в xlrd :) или просто прокомментировать эти строки с повышением вероятности, что, скорее всего, решит проблему в вашем случае (как и у меня) и дождитесь обновления xlrd.

+0

Проблема в том, что это не xlrd, это PHPExcel. Просмотрите поток комментариев по моему вопросу - я протестировал его с использованием файлов xls и xlsx с двумя различными библиотеками excel python, а другой пользователь SO протестировал его с помощью анализатора javascript xls, и все одинаковое повреждение появилось на всех них. Я попытался посмотреть, как PHPExcels вставляет функцию строки, но это немного над моей головой. Я мог бы еще раз взглянуть на это. –

+0

Возможно, вам следует избегать использования PHPExcel и позволить python xlrd выполнять всю работу. Просто передайте свои входные данные на python с самого начала.Что касается модификации файлов, вероятно, лучшим способом является чтение данных из существующего файла и создание нового и вставка ваших данных. Не изменяйте - это сложно. – glmvrml

+0

Да, как я уже говорил в другом комментарии, с тех пор я перешел на использование xlsx-writer для создания файла с нуля. Я больше не использую PHPExcel или не изменяю существующие файлы. –

0

Для всех, кто связывается, где вам нужны данные с удаленной службы, это взломать, но строка комментариев 419 (raise CompDocError("%s corruption: seen[%d] == %d" % (qname, s, self.seen[s]))) в compdoc.py, похоже, работает нормально.

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