You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Django和Python在浏览器中预览Excel文件?

问题描述

我希望在浏览器中查看Excel文件,无需进行编辑,仅需实现文件预览功能。已搭建好可用的PDF预览系统,通过Django服务器可在新标签页打开PDF文件,但运行Excel文件相关代码时,文件会直接下载,且不想为所有访问文件的电脑获取许可证。现有Django视图代码如下:

res = download(token, path)

with open(file_name, 'wb') as f:
    f.write(res.content)
with open(file_name, 'rb') as f:
    res = HttpResponse(f.read(), content_type=res.headers['Content-Type'])

该代码可完美实现PDF预览,还需要实现Excel及Docs文件的预览功能。

解决方案

1. 调整响应头强制浏览器内联预览

浏览器直接下载Office文件,往往是因为响应头未明确告知浏览器“内联打开”。可以通过设置Content-Disposition为inline,同时指定正确的Content-Type来尝试让浏览器内置预览器(或已安装的兼容插件)打开文件。

修改后的视图代码:

res = download(token, path)

with open(file_name, 'wb') as f:
    f.write(res.content)

# 映射Office文件对应的Content-Type
content_type_map = {
    'xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    'xls': 'application/vnd.ms-excel',
    'doc': 'application/msword'
}
file_ext = file_name.split('.')[-1].lower()
content_type = content_type_map.get(file_ext, res.headers['Content-Type'])

with open(file_name, 'rb') as f:
    response = HttpResponse(f.read(), content_type=content_type)
    # 强制浏览器内联预览,而非下载
    response['Content-Disposition'] = f'inline; filename="{file_name}"'

注意:这个方法依赖浏览器对Office文件的支持程度,部分浏览器或无对应插件的环境仍会触发下载,属于最简单但兼容性有限的方案。

2. 转换为PDF后复用现有预览逻辑

将Excel/Docs文件转换为PDF格式,直接复用已有的PDF预览系统,完全不需要客户端许可证,兼容性最好。可以借助LibreOffice的命令行工具实现跨平台转换,需要先在服务器上安装LibreOffice。

修改后的视图代码:

import subprocess
import os

res = download(token, path)

with open(file_name, 'wb') as f:
    f.write(res.content)

file_ext = file_name.split('.')[-1].lower()
# 针对Office文件转换为PDF
if file_ext in ['xlsx', 'docx', 'xls', 'doc']:
    pdf_filename = os.path.splitext(file_name)[0] + '.pdf'
    # 调用LibreOffice无头模式转换
    subprocess.run([
        'libreoffice', '--headless', '--convert-to', 'pdf',
        '--outdir', os.path.dirname(pdf_filename), file_name
    ], check=True)
    
    # 返回PDF文件,复用现有预览逻辑
    with open(pdf_filename, 'rb') as f:
        response = HttpResponse(f.read(), content_type='application/pdf')
        response['Content-Disposition'] = f'inline; filename="{os.path.basename(pdf_filename)}"'
    # 可选:删除临时生成的PDF文件(根据需求决定是否保留)
    # os.remove(pdf_filename)
else:
    # 非Office文件沿用原逻辑
    with open(file_name, 'rb') as f:
        response = HttpResponse(f.read(), content_type=res.headers['Content-Type'])
        response['Content-Disposition'] = f'inline; filename="{file_name}"'

优点:格式还原度高,兼容所有支持PDF预览的浏览器;缺点:需要服务器安装LibreOffice,转换大文件可能耗时。

3. 转换为HTML在浏览器直接渲染

使用Python库将Office文件内容提取并转换为HTML,直接返回HTML响应让浏览器渲染,无需外部工具,轻量快捷。

修改后的视图代码:

from openpyxl import load_workbook
from docx import Document

res = download(token, path)

with open(file_name, 'wb') as f:
    f.write(res.content)

file_ext = file_name.split('.')[-1].lower()
if file_ext == 'xlsx':
    wb = load_workbook(file_name)
    ws = wb.active
    # 生成HTML表格
    html = '<table border="1" cellpadding="4" cellspacing="0">'
    # 写入表头
    html += '<tr>'
    for col in range(1, ws.max_column + 1):
        html += f'<th>{ws.cell(row=1, column=col).value or ""}</th>'
    html += '</tr>'
    # 写入数据行
    for row in range(2, ws.max_row + 1):
        html += '<tr>'
        for col in range(1, ws.max_column + 1):
            html += f'<td>{ws.cell(row=row, column=col).value or ""}</td>'
        html += '</tr>'
    html += '</table>'
    response = HttpResponse(html, content_type='text/html')
elif file_ext == 'docx':
    doc = Document(file_name)
    # 生成HTML文本
    html = '<div style="padding: 16px; font-size: 14px;">'
    for para in doc.paragraphs:
        html += f'<p style="margin: 8px 0;">{para.text}</p>'
    html += '</div>'
    response = HttpResponse(html, content_type='text/html')
else:
    # 其他文件沿用原逻辑
    with open(file_name, 'rb') as f:
        response = HttpResponse(f.read(), content_type=res.headers['Content-Type'])
        response['Content-Disposition'] = f'inline; filename="{file_name}"'

优点:无需外部依赖,响应速度快;缺点:复杂格式(如公式、图表、样式)会丢失,仅适合纯内容预览场景。


内容的提问来源于stack exchange,提问作者DaCoPro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:55:34