2012-09-05 44 views
6

Tôi đã sử dụng stackoverflow trong một thời gian và nó đã giúp tôi rất thường xuyên. Bây giờ tôi có một vấn đề tôi không thể giải quyết bản thân mình hoặc thông qua tìm kiếm. Tôi đang cố gắng để xuất tập tin excel của tôi được tạo ra bởi openpyxl trong trình duyệt như tôi đã làm nó với phpexcel. Phương pháp này có vẻ giống nhau, nhưng tôi chỉ nhận được tệp bị hỏng. Mã của tôi trông giống như sau:cách xuất xlsx do Openpyxl tạo ra cho trình duyệt?

from openpyxl.workbook import Workbook 
from openpyxl.writer.excel import ExcelWriter 
from openpyxl.writer.excel import save_virtual_workbook 
from openpyxl.cell import get_column_letter 
from StringIO import StringIO 

print 'Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
print 'Content-Disposition: attachment;filename="results.xlsx"' 
print 'Cache-Control: max-age=0\n' 

output = StringIO() 

wb = Workbook() 

ws = wb.worksheets[0] 

ws.cell('A1').value = 3.14 

wb.save(output) 
print output.getvalue() 
#print save_virtual_workbook(wb) 

Tôi sử dụng phiên bản 1.5.8 và python 2.7. Không có cách tiếp cận nào hoạt động. Khi tôi chỉ sử dụng nó từ máy tính để bàn và không phải trình duyệt nó hoạt động hoàn hảo. Tôi sẽ rất biết ơn sự giúp đỡ.

P.S. xin vui lòng không cho tôi biết rằng việc sử dụng ngôn ngữ hoặc chương trình khác sẽ dễ dàng hơn. Tôi cần phải giải quyết điều này với python.

+0

Từ câu hỏi này, tôi đoán bạn không có kinh nghiệm về lập trình web trong python. Bạn không thể đặt mã này bên trong * .py trong thư mục gốc của tài liệu và mong muốn nó chạy giống như * .php. – Dikei

+0

Nội dung của bạn- * tiêu đề trông thiếu sót. Họ nên sử dụng kết thúc dòng CR/LF. Bạn có thể lấy mẫu 'text/html' đơn giản được cung cấp chính xác bởi tập lệnh này không? Nếu không, hãy sửa lỗi đó trước. – tripleee

+0

Tôi có đủ kinh nghiệm để biết chạy nó từ cgi-bin. Tôi có các kịch bản khác đang chạy. Đây là lần đầu tiên không xuất ra những gì tôi cần. Có văn bản sạch/html hoạt động hoàn hảo, ít nhất là theo như tôi đã thử nghiệm. Tôi không thấy lý do tại sao tôi nên sử dụng CR/LF ... – seeebek

Trả lời

-5

Nếu bạn muốn xây dựng một bảng HTML trông giống như bảng tính của bạn, bạn có thể muốn làm việc với CSV. Hoặc là làm điều này, thay vì Excel, HOẶC chuyển đổi Excel sang CSV sau khi bạn xây dựng nó.

Trong mọi trường hợp, một khi bạn có dữ liệu ở định dạng CSV, sau đó nó chỉ đơn giản là vấn đề của việc sử dụng python để xây dựng các trang HTML và lặp qua các dữ liệu CSV, trong khi chèn <table>, <tr><td> thẻ của bạn, nếu thích hợp .

+0

Có, tôi không có quá nhiều kinh nghiệm với lập trình web trong python. Mork của tôi là dịch một số loại ứng dụng này từ php sang python và giờ tôi bị kẹt với phppyton -> openpyxl. Tôi cần hành vi tương tự. đó là nhận dữ liệu từ một tập lệnh khác, gửi tập lệnh này đến tập lệnh này, đặt nó vào tệp excel và xuất ra dưới dạng tải xuống trình duyệt. Có thể không lưu nó vào máy chủ trước đây. – seeebek

+0

@Được hỏi câu hỏi cụ thể về việc phân phát tệp Excel. –

0

Tập lệnh của bạn hoạt động cho tôi như bạn mong đợi mà không bị thay đổi.

Tôi chỉ có thể giả sử bạn gặp sự cố với thiết lập tập lệnh cgi của mình.

Đảm bảo bạn có thư mục nơi tập lệnh thực sự được máy chủ web phân phát. Trên apache bạn có thể đạt được điều này với:

ScriptAlias /cgi-bin/ /home/WWW/localhost/cgi-bin/ 

Đảm bảo rằng tập lệnh có thể thay thế bằng cách đặt quyền tập lệnh. Đối với hoạt động dòng lệnh (python scriptname) không cần thiết, đối với trình duyệt web của bạn. Và đảm bảo rằng chủ sở hữu của máy chủ web có thể thực hiện các tập lệnh, vì máy chủ web có thể không chạy như bạn.

1

Viết đầu ra xlsx vào đĩa và sau đó phân phối nó qua Apache hoạt động hoàn hảo, nhưng đưa nó ra trực tiếp gây ra lỗi trong Excel và các vấn đề khác.

Tôi đã thêm một số bước mở rộng và thực hiện một thay đổi nhỏ để mã của bạn:

buffer=output.getvalue() 

Trong các tiêu đề HTTP:

print "Content-Length: " + str(len(buffer)) 

Và sử dụng write() thay vì print() để đẩy bộ đệm vào luồng đầu ra tiêu chuẩn:

stdout.write(buffer) 
+0

+1 để bao gồm tiêu đề 'Content-Length'. Tôi _could_ không có được điều này để làm việc mà không có nó. Khi tôi sử dụng 'print save_virtual_workbook (wb)', file nén kết quả của tôi có thêm hai byte. Nếu tôi sử dụng 'stdout.write()' nó có thêm một byte. Cung cấp 'Content-Length' đã sửa nó. – Auspex

5

tính năng này phù hợp với tôi. Tôi sử dụng python 2.7 và mới nhất openpyxlsend_file từ bình

... code ... 

import StringIO 
from openpyxl import Workbook 
wb = Workbook() 
ws = wb.active # worksheet 
ws.title = "Excel Using Openpyxl" 
c = ws.cell(row=5, column=5) 
c.value = "Hi on 5,5" 
out = StringIO.StringIO() 
wb.save(out) 
out.seek(0) 

return send_file(out, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 
      attachment_filename='xxl.xlsx', as_attachment=True) 
+2

Đó là bí danh khủng khiếp! 'từ io nhập khẩu BytesIO' là cách để làm điều này. –

0

Bởi vì Excel sử dụng một định dạng nhị phân bạn nên sử dụng BytesIO để đệm.

from io import BytesIO

Nhưng những gì lỗi bạn đang nhận được nếu bạn sử dụng save_virtual_workbook() mà thực hiện điều này cho bạn?

2
output = HttpResponse(mimetype='application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') 
file_name = "Test.xlsx" 
output['Content-Disposition'] = 'attachment; filename='+ file_name 

wb = Workbook() 

ws = wb.worksheets[0] 

ws.cell('A1').value = 3.14 

wb.save(output) 

return output 

Tôi đã sử dụng mẹo này để tải xuống tệp của mình bằng openpyxl. Hy vọng rằng sẽ giúp

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