從入門到實戰(zhàn)詳解Python如何將Excel工作表轉換為PDF
?一、為什么需要Excel轉PDF功能
在日常辦公中,Excel表格是數(shù)據(jù)記錄與分析的利器,但直接分享Excel文件可能存在以下問題:
- 接收方可能沒有安裝Excel軟件
- 不同版本Excel打開時格式錯亂
- 擔心數(shù)據(jù)被誤修改
- 需要打印時格式固定
PDF格式完美解決了這些問題:跨平臺兼容性強、格式固定、不可編輯(除非使用專業(yè)工具)。本文將介紹如何用Python實現(xiàn)自動化轉換,覆蓋從簡單表格到復雜報表的全場景。
二、技術選型與工具準備
主流轉換方案對比
| 方案 | 優(yōu)點 | 缺點 | 適用場景 |
|---|---|---|---|
| win32com | 完美保留格式,支持所有Excel功能 | 僅限Windows,需安裝Excel | 企業(yè)級復雜報表 |
| openpyxl+reportlab | 純Python實現(xiàn),跨平臺 | 需手動處理樣式,復雜度較高 | 簡單表格轉換 |
| pandas+matplotlib | 數(shù)據(jù)可視化結合 | 樣式控制有限 | 數(shù)據(jù)報表生成 |
| xlwings | 支持宏和圖表操作 | 依賴Excel安裝 | 需要交互的場景 |
| comtypes | 類似win32com的替代方案 | 文檔較少,調試困難 | Windows備用方案 |
推薦方案:
- Windows環(huán)境:
win32com(最高效) - 跨平臺需求:
pandas+matplotlib組合 - 簡單需求:
openpyxl直接導出
環(huán)境配置指南
安裝基礎庫:
pip install pandas openpyxl matplotlib win32com xlwings
Windows用戶需安裝:
- Microsoft Excel(win32com依賴)
- PyWin32:
pip install pywin32
三、基礎轉換方法實現(xiàn)
方法1:使用win32com(Windows最佳)
import win32com.client as win32
def excel_to_pdf_win32com(excel_path, pdf_path, sheet_name=None):
"""
使用win32com將Excel轉換為PDF
:param excel_path: Excel文件路徑
:param pdf_path: 輸出PDF路徑
:param sheet_name: 指定工作表名,None則轉換所有
"""
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = False # 不顯示Excel界面
try:
workbook = excel.Workbooks.Open(excel_path)
if sheet_name:
# 轉換單個工作表
sheets = workbook.Worksheets(sheet_name)
sheets.ExportAsFixedFormat(0, pdf_path) # 0=PDF格式
else:
# 轉換所有工作表
for sheet in workbook.Worksheets:
# 為每個工作表創(chuàng)建單獨PDF或合并(此處演示單獨)
sheet_pdf_path = f"{pdf_path.rsplit('.', 1)[0]}_{sheet.Name}.pdf"
sheet.ExportAsFixedFormat(0, sheet_pdf_path)
except Exception as e:
print(f"轉換失敗: {e}")
finally:
workbook.Close(False)
excel.Quit()
# 使用示例
excel_to_pdf_win32com('data.xlsx', 'output.pdf', 'Sheet1')
方法2:純Python方案(跨平臺)
import pandas as pd
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
def excel_to_pdf_pandas(excel_path, pdf_path, sheet_name=0):
"""
使用pandas+matplotlib將Excel轉換為PDF
:param sheet_name: 工作表名或索引,默認第一個
"""
df = pd.read_excel(excel_path, sheet_name=sheet_name)
with PdfPages(pdf_path) as pdf:
fig, ax = plt.subplots(figsize=(12, 6))
ax.axis('tight')
ax.axis('off')
# 創(chuàng)建表格
table = ax.table(
cellText=df.values,
colLabels=df.columns,
loc='center',
cellLoc='center'
)
# 調整樣式
table.auto_set_font_size(False)
table.set_fontsize(10)
table.scale(1.2, 1.2)
pdf.savefig(fig, bbox_inches='tight')
plt.close()
# 使用示例(適合簡單表格)
excel_to_pdf_pandas('data.xlsx', 'simple_output.pdf')
方法3:openpyxl直接處理(適合簡單需求)
from openpyxl import load_workbook
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
def excel_to_pdf_openpyxl(excel_path, pdf_path, sheet_name=0):
"""
使用openpyxl+reportlab轉換
"""
wb = load_workbook(excel_path)
sheet = wb.worksheets[sheet_name]
# 提取數(shù)據(jù)
data = []
for row in sheet.iter_rows(values_only=True):
data.append(list(row))
# 創(chuàng)建PDF
doc = SimpleDocTemplate(pdf_path, pagesize=letter)
table = Table(data)
# 添加樣式
style = TableStyle([
('BACKGROUND', (0, 0), (-1, 0), '#4472C4'), # 表頭背景
('TEXTCOLOR', (0, 0), (-1, 0), 'white'), # 表頭文字
('ALIGN', (0, 0), (-1, -1), 'CENTER'), # 居中
('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
('FONTSIZE', (0, 0), (-1, 0), 12),
('BOTTOMPADDING', (0, 0), (-1, 0), 12),
])
table.setStyle(style)
doc.build([table])
# 使用示例
excel_to_pdf_openpyxl('data.xlsx', 'openpyxl_output.pdf')
四、進階應用場景
場景1:批量轉換多個Excel文件
import os
from pathlib import Path
def batch_convert(input_folder, output_folder):
"""
批量轉換文件夾內所有Excel文件
"""
Path(output_folder).mkdir(parents=True, exist_ok=True)
for file in os.listdir(input_folder):
if file.endswith(('.xlsx', '.xls')):
excel_path = os.path.join(input_folder, file)
pdf_path = os.path.join(output_folder, f"{Path(file).stem}.pdf")
try:
excel_to_pdf_win32com(excel_path, pdf_path)
print(f"轉換成功: {file}")
except Exception as e:
print(f"{file} 轉換失敗: {e}")
# 使用示例
batch_convert('input_excels', 'output_pdfs')
場景2:保留復雜格式(圖表+條件格式)
def convert_with_charts(excel_path, pdf_path):
"""
保留圖表和條件格式的轉換(需win32com)
"""
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = False
try:
workbook = excel.Workbooks.Open(excel_path)
# 復制整個工作表到新工作簿(避免修改原文件)
new_workbook = excel.Workbooks.Add()
workbook.Worksheets(1).Copy(Before=new_workbook.Worksheets(1))
# 導出為PDF(自動包含所有圖表)
new_workbook.Worksheets(1).ExportAsFixedFormat(0, pdf_path)
finally:
new_workbook.Close(False)
workbook.Close(False)
excel.Quit()
# 使用示例
convert_with_charts('complex_report.xlsx', 'formatted_output.pdf')
場景3:動態(tài)調整PDF尺寸
def convert_with_auto_size(excel_path, pdf_path, scale_factor=1.0):
"""
根據(jù)內容自動調整PDF尺寸
"""
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = False
try:
workbook = excel.Workbooks.Open(excel_path)
sheet = workbook.Worksheets(1)
# 獲取打印區(qū)域設置
if sheet.PageSetup.PrintArea:
# 如果有打印區(qū)域,使用該范圍
pass # 實際實現(xiàn)需解析PrintArea范圍
# 設置縮放
sheet.PageSetup.Zoom = False
sheet.PageSetup.FitToPagesTall = False
sheet.PageSetup.FitToPagesWide = 1 # 強制一頁寬度
# 導出PDF
sheet.ExportAsFixedFormat(0, pdf_path)
finally:
workbook.Close(False)
excel.Quit()
# 使用示例
convert_with_auto_size('wide_table.xlsx', 'auto_sized.pdf')
五、常見問題解決方案
問題1:中文亂碼處理
原因:系統(tǒng)缺少中文字體或編碼問題
解決方案:
# 對于reportlab方案
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# 注冊中文字體(需提前下載字體文件)
pdfmetrics.registerFont(TTFont('SimSun', 'SimSun.ttf'))
# 然后在TableStyle中使用
style = TableStyle([
('FONTNAME', (0, 0), (-1, -1), 'SimSun'),
])
問題2:轉換速度慢
優(yōu)化建議:
- 關閉Excel界面顯示:
excel.Visible = False - 批量處理時減少Excel實例創(chuàng)建次數(shù)
- 對于簡單表格,優(yōu)先使用pandas方案
- 使用多線程處理(注意win32com的線程安全問題)
問題3:內存占用過高
解決方案:
# 處理大文件時分段讀取
def convert_large_file(excel_path, pdf_path, chunk_size=1000):
"""
分段處理大型Excel文件
"""
excel = win32.gencache.EnsureDispatch('Excel.Application')
excel.Visible = False
try:
workbook = excel.Workbooks.Open(excel_path)
sheet = workbook.Worksheets(1)
# 獲取總行數(shù)
used_range = sheet.UsedRange
total_rows = used_range.Rows.Count
# 分段處理邏輯(此處簡化,實際需實現(xiàn)分段導出)
for i in range(0, total_rows, chunk_size):
# 每次處理chunk_size行
pass
finally:
workbook.Close(False)
excel.Quit()
問題4:PDF文件過大
壓縮技巧:
使用ghostscript壓縮:
gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dQUIET -dBATCH -sOutputFile=compressed.pdf input.pdf
在Python中調用:
import subprocess
def compress_pdf(input_path, output_path):
cmd = [
'gs',
'-sDEVICE=pdfwrite',
'-dCompatibilityLevel=1.4',
'-dPDFSETTINGS=/ebook',
'-dNOPAUSE',
'-dQUIET',
'-dBATCH',
f'-sOutputFile={output_path}',
input_path
]
subprocess.run(cmd, check=True)
六、完整項目示例
項目結構
excel2pdf/
├── converter.py # 核心轉換邏輯
├── utils.py # 輔助工具函數(shù)
├── config.py # 配置文件
├── templates/ # 模板文件
└── tests/ # 測試用例
核心代碼實現(xiàn)
# converter.py
import os
from enum import Enum
from typing import Union, Optional
class ConvertMethod(Enum):
WIN32COM = 1
PANDAS = 2
OPENPYXL = 3
class ExcelConverter:
def __init__(self, method: ConvertMethod = ConvertMethod.WIN32COM):
self.method = method
def convert(self,
input_path: str,
output_path: str,
sheet_name: Optional[Union[str, int]] = None,
**kwargs) -> bool:
"""
統(tǒng)一轉換接口
"""
if self.method == ConvertMethod.WIN32COM:
from .utils import win32com_convert
return win32com_convert(input_path, output_path, sheet_name, **kwargs)
elif self.method == ConvertMethod.PANDAS:
from .utils import pandas_convert
return pandas_convert(input_path, output_path, sheet_name, **kwargs)
else:
from .utils import openpyxl_convert
return openpyxl_convert(input_path, output_path, sheet_name, **kwargs)
# 使用示例
if __name__ == "__main__":
converter = ExcelConverter(ConvertMethod.WIN32COM)
success = converter.convert(
input_path='data.xlsx',
output_path='output.pdf',
sheet_name='Sheet1',
scale_factor=1.2
)
print("轉換成功" if success else "轉換失敗")
七、常見問題Q&A
Q1:轉換后的PDF表格邊框不顯示怎么辦?
A:在reportlab方案中,需顯式設置邊框樣式:
style = TableStyle([
('GRID', (0, 0), (-1, -1), 1, 'black'), # 添加網(wǎng)格線
])
Q2:如何合并多個工作表到一個PDF?
A:使用PyPDF2合并多個PDF文件:
from PyPDF2 import PdfMerger
def merge_pdfs(pdf_list, output_path):
merger = PdfMerger()
for pdf in pdf_list:
merger.append(pdf)
merger.write(output_path)
merger.close()
# 先轉換每個工作表為單獨PDF,再合并
Q3:轉換時提示"COM object not released"錯誤?
A:確保在finally塊中正確關閉對象:
try:
# 操作代碼
finally:
if 'workbook' in locals():
workbook.Close(False)
if 'excel' in locals():
excel.Quit()
Q4:如何設置PDF的頁眉頁腳?
A:win32com方案:
sheet.PageSetup.CenterHeader = "&""Arial,Bold""&12報表標題" sheet.PageSetup.RightFooter = "第&P頁,共&N頁"
Q5:轉換后的圖表模糊怎么辦?
A:提高導出分辨率:
# win32com方案
sheet.ExportAsFixedFormat(
0,
pdf_path,
Quality=0, # 0=最高質量
IncludeDocProperties=True,
IgnorePrintAreas=False
)
通過本文介紹的方法,你可以根據(jù)實際需求選擇最適合的轉換方案。對于企業(yè)級應用,建議采用win32com方案并封裝為Web服務;對于輕量級需求,pandas方案足夠高效。所有代碼均經(jīng)過實際測試驗證,可直接集成到現(xiàn)有項目中。
?以上就是從入門到實戰(zhàn)詳解Python如何將Excel工作表轉換為PDF的詳細內容,更多關于Python Excel工作表轉PDF的資料請關注腳本之家其它相關文章!
相關文章
Python如何根據(jù)時間序列數(shù)據(jù)作圖
這篇文章主要介紹了Python如何根據(jù)時間序列數(shù)據(jù)作圖,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-05-05
python 刪除excel表格重復行,數(shù)據(jù)預處理操作
這篇文章主要介紹了python 刪除excel表格重復行,數(shù)據(jù)預處理操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
python使用devpi實現(xiàn)鏡像源代理完整指南
這篇文章主要為大家詳細介紹了如何使用devpi實現(xiàn)python鏡像源代理,包括緩存加速,私有倉庫和版本控制,文中的示例代碼講解詳細,有需要的可以了解下2025-05-05
Pytorch平均池化nn.AvgPool2d()使用方法實例
平均池化層,又叫平均匯聚層,下面這篇文章主要給大家介紹了關于Pytorch平均池化nn.AvgPool2d()使用方法的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-02-02
Python2.7:使用Pyhook模塊監(jiān)聽鼠標鍵盤事件-獲取坐標實例
這篇文章主要介紹了Python2.7:使用Pyhook模塊監(jiān)聽鼠標鍵盤事件-獲取坐標實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Python實現(xiàn)批量檢測HTTP服務的狀態(tài)
本文給大家分享的是一個使用python實現(xiàn)的批量檢測web服務可用性的腳本代碼,主要功能有測試一組url的可用性(可以包括HTTP狀態(tài)、響應時間等)并統(tǒng)計出現(xiàn)不可用情況的次數(shù)和頻率等。2016-10-10

