Мне очень сложно редактировать некоторые файлы 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.
Он вызывает исключение только тогда, когда 'self.seen [s]:' оценивает значение 'True'. Так распечатайте «я».[s] 'и' s' и посмотреть, где в файле он задыхается. Затем обновите свой вопрос с помощью этих деталей. –
Вы имеете в виду изменить файл xlrd, чтобы сделать это? И s равно 2, если вы посмотрите на ошибку, это показывает «Коррекция рабочей книги: увидено [2] == 4' –
Заявление прямо под' 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 «Но это трудно прочитать здесь, я отредактирую свой вопрос. –