Python文件解析之Excel/Word/PDF的解析、處理、預(yù)覽與下載
1. 總覽:同一個入口,不同解析器
當(dāng)用戶上傳文件時,技術(shù)鏈路通常是:
- 接收文件并保存原件。
- 按擴(kuò)展名選擇對應(yīng)的 Python 解析函數(shù)。
- 生成可預(yù)覽數(shù)據(jù)。
- 前端展示原件與解析結(jié)果。
- 用戶編輯后保存。
- 提供原件下載與編輯結(jié)果下載。
2. 插件與依賴清單
先統(tǒng)一約定:本文里“插件”指第三方依賴包(Python 包 / 前端 npm 包)。
2.1 Python 端插件(后端)
| 插件 | 版本(示例) | 用途 | 是否必須 |
|---|---|---|---|
fastapi | 0.111.0 | 提供上傳、預(yù)覽、保存、下載 API | 必須 |
uvicorn | 0.29.0 | 啟動 FastAPI 服務(wù) | 必須 |
python-multipart | 0.0.9 | 支持 multipart/form-data 文件上傳 | 必須 |
openpyxl | 3.1.2 | 解析/回寫 Excel(xlsx) | Excel 必須 |
pandas | 2.2.2 | Excel/表格輔助清洗(可選但常用) | 推薦 |
python-docx | 1.1.0 | 解析/生成 Word(docx) | Word 必須 |
pymupdf (fitz) | 1.24.9 | PDF 文本、表格、分頁信息提取 | PDF 必須 |
對應(yīng) import 寫法(便于直接復(fù)制代碼):
from fastapi import FastAPI, UploadFile, Filefrom openpyxl import load_workbookfrom docx import Documentimport fitz(來自pymupdf)
2.2 前端插件(預(yù)覽與編輯)
| 插件 | 版本(示例) | 用途 | 是否必須 |
|---|---|---|---|
xlsx | ^0.18.5 | 瀏覽器端 Excel 預(yù)覽(按 sheet 渲染) | Excel 預(yù)覽必須 |
mammoth | ^1.11.0 | 瀏覽器端 Word 轉(zhuǎn) HTML 預(yù)覽 | Word 預(yù)覽必須 |
react-data-grid | 7.0.0-beta.59 | 表格編輯組件(Excel/Word 表格/PDF 表格修訂) | 需要編輯時必須 |
2.3 可選插件(PDF OCR 兜底)
| 插件 | 用途 | 是否必須 |
|---|---|---|
pytesseract + Pillow | PDF/圖片 OCR 兜底 | 可選 |
paddleocr | 中文 OCR 兜底(效果通常更好) | 可選 |
2.4 可選插件(兼容舊格式)
| 插件/工具 | 用途 | 是否必須 |
|---|---|---|
xlrd | 僅當(dāng)你要直接讀取 .xls 時使用 | 可選 |
libreoffice (soffice) | 把 .doc 轉(zhuǎn)成 .docx,再交給 python-docx 解析 | 可選 |
2.5 安裝命令示例
# Backend pip install fastapi uvicorn python-multipart openpyxl pandas python-docx pymupdf # Frontend npm install xlsx mammoth react-data-grid # Optional OCR fallback pip install pytesseract pillow # or pip install paddleocr # Optional legacy-format support pip install xlrd
3. 通用基礎(chǔ):上傳、存儲、路由
3.1 上傳接口示例
from pathlib import Path
from fastapi import APIRouter, UploadFile, File
router = APIRouter()
@router.post("/api/files/upload")
async def upload(files: list[UploadFile] = File(...)):
items = []
for f in files:
suffix = Path(f.filename).suffix.lower()
raw_path = save_raw_file(f) # 保存原件
if suffix == ".xlsx":
file_id = process_excel(raw_path)
file_type = "excel"
elif suffix == ".docx":
file_id = process_word(raw_path)
file_type = "word"
elif suffix == ".pdf":
file_id = process_pdf(raw_path)
file_type = "pdf"
else:
items.append({"filename": f.filename, "error": "unsupported file type"})
continue
items.append({"file_id": file_id, "type": file_type, "filename": f.filename})
return {"items": items}
說明:openpyxl 主流場景是 .xlsx,python-docx 主流場景是 .docx。
如果必須支持 .xls / .doc,建議先做“格式轉(zhuǎn)換”再進(jìn)入本文解析流水線。
3.2 原件下載接口(通用)
from fastapi.responses import FileResponse
@router.get("/api/files/{file_id}/download/raw")
def download_raw(file_id: str):
path = locate_raw_file(file_id)
return FileResponse(path, filename=path.name)
4. Excel:解析、處理、預(yù)覽、編輯保存、下載
本章用到的插件:openpyxl、pandas(可選)、xlsx、react-data-grid。
Excel 的特點(diǎn)是天然二維網(wǎng)格,所以處理策略是“保留 sheet + 保留行列”。
4.1 解析(Python)
from openpyxl import load_workbook
def parse_excel(path: str) -> dict:
wb = load_workbook(path, data_only=True)
sheets: dict[str, list[list[str]]] = {}
for sheet_name in wb.sheetnames:
ws = wb[sheet_name]
rows: list[list[str]] = []
for row in ws.iter_rows(values_only=True):
rows.append(["" if c is None else str(c) for c in row])
sheets[sheet_name] = rows
return {
"sheet_names": wb.sheetnames,
"sheets": sheets,
}
4.2 處理(可選)
常見的通用處理:
- 去掉尾部空行。
- 統(tǒng)一行長度(短行補(bǔ)空字符串)。
- 把非字符串安全轉(zhuǎn)成字符串,避免前端渲染異常。
def normalize_excel_rows(rows: list[list[str]]) -> list[list[str]]:
if not rows:
return [[""]]
width = max(len(r) for r in rows)
normalized = []
for r in rows:
row = ["" if c is None else str(c) for c in r]
if len(row) < width:
row += [""] * (width - len(row))
normalized.append(row[:width])
return normalized
4.3 前端預(yù)覽
前端展示方式:
- Sheet 名作為 tab。
- 當(dāng)前 sheet 用 table 或 DataGrid 渲染。
- 支持切換 sheet。
4.4 編輯保存
PUT /api/excel/{file_id}/edit
{
"sheet_name": "Sheet1",
"rows": [["A1", "B1"], ["A2", "B2"]]
}
后端可把編輯結(jié)果保存成:
excel_edits.json(便于二次編輯)。edited.xlsx(便于下載)。
4.5 下載
- 原件:
GET /api/excel/{file_id}/download/raw - 編輯版:
GET /api/excel/{file_id}/download/edited
@router.get("/api/excel/{file_id}/download/edited")
def download_excel_edited(file_id: str):
edited_path = build_edited_excel(file_id) # 根據(jù)保存的 rows 重建 xlsx
return FileResponse(edited_path, filename=edited_path.name)

5. Word:解析、處理、預(yù)覽、編輯保存、下載
本章用到的插件:python-docx、mammoth、react-data-grid。
Word 的天然結(jié)構(gòu)是“段落 + 表格”,不建議簡單壓平為純二維表。
5.1 解析(Python)
from docx import Document
def parse_word(path: str) -> dict:
doc = Document(path)
blocks: list[dict] = []
# 段落塊
for p in doc.paragraphs:
text = p.text.strip()
if text:
blocks.append({"type": "paragraph", "text": text})
# 表格塊
for table_index, table in enumerate(doc.tables):
rows = []
for row in table.rows:
rows.append([cell.text.strip() for cell in row.cells])
blocks.append({"type": "table", "table_index": table_index, "rows": rows})
return {"blocks": blocks}
5.2 處理(可選)
- 清理連續(xù)空段落。
- 表格行列補(bǔ)齊。
- 對超長文本做安全截?cái)啵▋H顯示時,不改原文)。
5.3 前端預(yù)覽
Word 常見做法是雙視圖:
- 原件預(yù)覽:
mammoth轉(zhuǎn) HTML,閱讀體驗(yàn)更接近原文檔。 - 編輯視圖:
- 段落塊用文本編輯器。
- 表格塊用 DataGrid。
5.4 編輯保存
PUT /api/word/{file_id}/edit
{
"blocks": [
{"type": "paragraph", "text": "Updated paragraph"},
{"type": "table", "table_index": 0, "rows": [["Header1", "Header2"], ["V1", "V2"]]}
]
}
后端可以:
- 保存
word_edits.json。 - 用
python-docx生成edited.docx。
5.5 下載
- 原件:
GET /api/word/{file_id}/download/raw - 編輯版:
GET /api/word/{file_id}/download/edited
@router.get("/api/word/{file_id}/download/edited")
def download_word_edited(file_id: str):
edited_docx = build_edited_word_docx(file_id)
return FileResponse(edited_docx, filename=edited_docx.name)
6. PDF:解析、處理、預(yù)覽、編輯保存、下載
本章用到的插件:pymupdf(可選 OCR:pytesseract/paddleocr)、react-data-grid。
PDF 的關(guān)鍵是“按頁處理”,因?yàn)轫撁媸撬奶烊粏挝弧?/p>
6.1 解析(Python)
import fitz
def parse_pdf(path: str) -> dict:
pages = []
with fitz.open(path) as doc:
for i in range(doc.page_count):
page = doc.load_page(i)
text = page.get_text("text") or ""
tables = []
finder = page.find_tables()
if finder and finder.tables:
for t in finder.tables:
tables.append([[str(c or "").strip() for c in row] for row in t.extract()])
pages.append({
"page_no": i + 1,
"text": text,
"tables": tables,
"width": float(page.rect.width),
"height": float(page.rect.height),
})
return {"page_count": len(pages), "pages": pages}
6.2 處理(可選)
- 當(dāng)
find_tables()抽不到表時,回退到page.get_text("words")做詞塊聚合。 - 對文本進(jìn)行頁級摘要(便于快速預(yù)覽)。
- 對識別結(jié)果增加
warnings字段(純技術(shù)提示)。
6.3 前端預(yù)覽
建議雙層:
- 原件:iframe/objectURL 直接預(yù)覽 PDF。
- 解析結(jié)果:按頁展示
text + tables。
6.4 編輯保存
PUT /api/pdf/{file_id}/edit
{
"page_no": 1,
"table_index": 0,
"rows": [["Col1", "Col2"], ["A", "B"]],
"notes": "manual correction"
}
后端可保存:
pdf_edits.jsonedited.pdf(可選實(shí)現(xiàn):加批注頁、嵌入修訂信息)
6.5 下載
- 原件:
GET /api/pdf/{file_id}/download/raw - 編輯版 PDF:
GET /api/pdf/{file_id}/download/edited - 編輯記錄 JSON(可選):
GET /api/pdf/{file_id}/download/edits-json

7. API 清單(示例)
| 類型 | 預(yù)覽接口 | 保存接口 | 下載接口 |
|---|---|---|---|
| Excel | GET /api/excel/{file_id}/preview | PUT /api/excel/{file_id}/edit | download/raw / download/edited |
| Word | GET /api/word/{file_id}/preview | PUT /api/word/{file_id}/edit | download/raw / download/edited |
GET /api/pdf/{file_id}/preview | PUT /api/pdf/{file_id}/edit | download/raw / download/edited |
說明:這三組接口可以由同一個服務(wù)實(shí)現(xiàn)。本文拆開寫,僅用于按文件格式獨(dú)立說明技術(shù)實(shí)現(xiàn)細(xì)節(jié)。
8. 工程落地建議(純技術(shù))
- 原件一定要保存,不要只存解析結(jié)果。
- 編輯結(jié)果建議落 JSON,再按需導(dǎo)出編輯版文件。
- 下載接口統(tǒng)一加
Content-Disposition: attachment。 - 所有預(yù)覽數(shù)據(jù)都做空值與類型兜底,前端會省很多判斷。
- 文件名建議帶時間戳,例如:
report_edited_20260224_1530.xlsxdoc_edited_20260224_1530.docxscan_edited_20260224_1530.pdf
9. 效果
excel預(yù)覽效果

word預(yù)覽效果

pdf 預(yù)覽效果

以上就是Python文件解析之Excel/Word/PDF的解析、處理、預(yù)覽與下載的詳細(xì)內(nèi)容,更多關(guān)于Python Excel/Word/PDF解析、處理、預(yù)覽與下載的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
numpy系列之?dāng)?shù)組重塑的實(shí)現(xiàn)
本文主要介紹了numpy數(shù)組重塑。所謂數(shù)組重塑就是更改數(shù)組的形狀,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09
Python程序打包成EXE的四種方法詳解與實(shí)戰(zhàn)
將Python代碼打包成可執(zhí)行文件是一種使你的應(yīng)用程序更易于分享和分發(fā)的方法,本文一步一步地教你如何用 Pyinstaller 模塊將Python程序打包成exe文件,這篇教程絕對是全網(wǎng)最全面、最詳細(xì)的教程,包含四種打包的方法,需要的朋友可以參考下2025-07-07
python爬取網(wǎng)易云音樂排行榜實(shí)例代碼
大家好,本篇文章主要講的是python爬取網(wǎng)易云音樂排行榜數(shù)據(jù)代碼,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽2021-12-12
Pycharm連接遠(yuǎn)程服務(wù)器并遠(yuǎn)程調(diào)試的全過程
PyCharm 是 JetBrains 開發(fā)的一款 Python 跨平臺編輯器,下面這篇文章主要介紹了Pycharm連接遠(yuǎn)程服務(wù)器并遠(yuǎn)程調(diào)試的全過程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2021-06-06
OpenCV實(shí)現(xiàn)圖片編解碼實(shí)踐
在很多應(yīng)用中,經(jīng)常會直接把圖片的二進(jìn)制數(shù)據(jù)進(jìn)行交換,這就需要對普通進(jìn)行編碼解碼,那么怎么才能實(shí)現(xiàn),本文就來介紹一下2021-06-06

