2017-01-29 46 views
6

Tôi có một chương trình ghi vào bảng tính bằng cách sử dụng openpyxl. Khi thực hiện chương trình, các ô được lấp đầy như mong đợi nhưng bảng tính bị hỏng. Excel sửa chữa bảng tính và sau đó tôi có thể xem lại nó.Sử dụng mô-đun openpyxl để ghi vào bảng tính tạo bảng tính bị hỏng, cách khắc phục bằng mô-đun zipfile?

import openpyxl 
from openpyxl import load_workbook 
amounts, row = [1, 2, 3, 4, 5], 2 
book = load_workbook("output.xlsx") 
sheet = book.active 

for i, value in enumerate(amounts): 
    sheet.cell(column=i+1, row=row, value=value) 
print ("Sheet updating complete.") 
book.save("output.xlsx") 

Tôi đã thử sử dụng Open XML SDK Productivity Tool từ Microsoft để so sánh tệp tốt và xấu với nhau và nhận thấy rằng thiếu styles.xml. Tôi cố gắng để sao chép này hơn bằng cách sử dụng mã nguồn sau đây tôi đã thu được từ một câu hỏi khác, nhưng nó không giải quyết vấn đề cho tôi.

import zipfile 
with zipfile.ZipFile('outputcopy.xlsx', 'r') as zgood: 
    styles_xml = zgood.read('xl/styles.xml') 
with zipfile.ZipFile('output.xlsx', 'a') as zbad: 
    zbad.writestr('xl/styles.xml', styles_xml) 

Tôi có thể xác nhận từ nhật ký sửa Excel tạo ra, vấn đề là với xl/styles.xml. Tôi cần phải sao chép tập tin xml này từ bản sao tốt, vào bản sao xấu.

Làm cách nào để sao chép tệp xl/styles.xml để chương trình có thể chạy mà không làm hỏng output.xlsx?

Tôi đã thực hiện một nỗ lực khác để khắc phục sự cố này. Trong trường hợp không thể sao chép styles.xml từ một tệp Excel khác; Tôi đã mở styles.xml từ output.xlsx trước book.save("output.xlsx"). Sau khi lưu, tôi nhận được styles.xml từ trước câu lệnh lưu và viết nó. Thật không may, điều này đã không thay đổi bất cứ điều gì và tôi vẫn nhận được một tập tin Excel bị hư hỏng. Với nỗ lực này, mã thử nghiệm của tôi trông giống như sau:

import openpyxl 
import zipfile 

from openpyxl import load_workbook 
amounts, indexValue, row = [1, 2, 3, 4, 5], 0, 2 
book = load_workbook("output.xlsx") 
sheet = book.active 

for i, value in enumerate(amounts): 
    sheet.cell(column=i+1, row=row, value=value) 
print ("Sheet updating complete.") 

with zipfile.ZipFile('output.xlsx', 'r') as zgood: 
    styles_xml = zgood.read('xl/styles.xml') 

book.save("output.xlsx") 

with zipfile.ZipFile('output.xlsx', 'a') as zbad: 
    zbad.writestr('xl/styles.xml', styles_xml) 

Tôi đã thử lưu dưới dạng tệp Excel hoàn toàn mới nhưng vẫn gặp sự cố tương tự. Tôi đã thử sử dụng zip file để mở từ output.xlsx và ghi vào tệp mới được lưu, nhưng vẫn không có kết quả.

import openpyxl 
import zipfile 
from openpyxl import load_workbook 

amounts, indexValue, row, cell = [1, 2, 3, 4, 5], 0, 2, "A2" 
book = load_workbook("output.xlsx") 
sheet = book.active 

while indexValue != 5: 
    sheet[cell] = amounts[indexValue] 
    indexValue += 1 
    cell = chr(ord(cell[0]) + 1) + str(cell[1]) 
print ("Sheet updating complete.") 

book.save("test.xlsx") 

with zipfile.ZipFile('output.xlsx', 'r') as zgood: 
    styles_xml = zgood.read('xl/styles.xml') 
with zipfile.ZipFile('test.xlsx', 'a') as zbad: 
    zbad.writestr('xl/styles.xml', styles_xml) 

Mặc dù tôi đã khắc phục vấn đề này, nhưng cần lưu ý rằng vấn đề này dường như chỉ xảy ra khi tải sổ làm việc. Tôi đã tạo một chương trình khác với các bảng tính tạo ra một bảng tính, thay vì tải nó. Do đó, bảng tính không được lưu.

+0

Bạn đang sử dụng phiên bản Microsoft Excel nào? Tôi đang sử dụng MS Excel 2010 và nó cho thấy không có lỗi bằng cách sử dụng ví dụ của bạn. – Brian

+0

@Brian Tôi đang sử dụng các phiên bản mới nhất của Microsoft Excel, 2016. Tôi đã thử mở tệp Excel trên cả OS X và Windows 10. Trên một lưu ý phụ, số của Apple dường như có thể mở tệp hoàn toàn tốt. –

Trả lời

4

Sau khi xác nhận rằng vấn đề là với styles.xml, tôi đã xác định rằng vấn đề rất có thể xảy ra với định dạng kiểu của ô được viết. Bằng cách sử dụng styles từ mô-đun openpyxl, tôi đã khắc phục sự cố.

Tôi tuyên bố một biến, fontStyle trong trường hợp này, và đặt tất cả các thiết lập phong cách:

fontStyle = Font(name="Calibri", size=12, color=colors.BLACK) 

Khi viết amounts để mỗi tế bào, tôi cũng thiết lập các phong cách của các tế bào sử dụng fontStyle:

sheet[cell].font = fontStyle 

Mã hoàn chỉnh, trông giống như sau:

import openpyxl 
from openpyxl import load_workbook 
from openpyxl.styles import colors 
from openpyxl.styles import Font, Color 

fontStyle = Font(name="Calibri", size=12, color=colors.BLACK) 
amounts, indexValue, cell = [1, 2, 3, 4, 5], 0, "A2" 
book = load_workbook("output.xlsx") 
sheet = book.active 

while indexValue != 5: 
    sheet[cell] = amounts[indexValue] 
    sheet[cell].font = fontStyle 
    indexValue += 1 
    cell = chr(ord(cell[0]) + 1) + str(cell[1]) 

print ("Sheet updating complete.") 
book.save("output.xlsx") 

Tôi tin rằng điều này đã làm việc vì phương pháp viết không có cài đặt kiểu mặc định. Điều này sẽ giải thích tại sao thiếu styles.xml khi sử dụng Công cụ năng suất mở XML SDK. Khi kiểm tra tệp Excel này sau khi sửa chữa, tôi có thể xác nhận rằng styles.xml không còn bị thiếu.

Tệp không còn bị hỏng khi được lưu và có thể mở lại bình thường. Ngoài ra, tôi bây giờ có thể thực thi kịch bản này để ghi vào tệp Excel một lần nữa, mà không cần phải mở và đóng để sửa chữa nó.

Lưu ý rằng tôi cũng đã thay đổi vòng lặp của mình từ vòng lặp gốc - như một phần của một trong những nỗ lực của tôi để khắc phục sự cố. Điều này đã không có ảnh hưởng đến kết quả cuối cùng - tất cả đều rơi vào kiểu dáng của các tế bào được viết.

Điều này không chính xác trả lời câu hỏi giải quyết vấn đề cụ thể với zipfile nhưng nó giải quyết được sự cố.

Các vấn đề liên quan