CSV文件以纯文本形式存储表格数据,通用性极强,但在正式场合——比如向客户交付数据报表、归档项目文档或打印材料时,它的短板就暴露出来了:没有格式、列宽不均、分页混乱,阅读体验大打折扣。
PDF则恰好弥补了这些缺陷。它固定排版,跨平台显示一致,是正式文档的首选格式。本文介绍一种简单直接的方法:利用 Spire.XLS for Python 库,将CSV文件加载为工作簿,调整表格样式,再导出为规整的PDF文档。整个过程只需十几行代码,无需安装Microsoft Excel。

在开始编码之前,先安装所需的依赖库:
pip install Spire.XLS
Spire.XLS for Python 是一个功能强大的Excel操作库,支持读取、写入、转换等多种操作,且不依赖任何本地Excel组件。
下面是一段完整的转换代码,涵盖加载、样式调整和导出三个核心步骤:
from spire.xls import *from spire.xls.common import *# 创建 Workbook 对象workbook = Workbook()# 加载 CSV 文件(参数:文件路径, 分隔符, 起始行, 起始列)workbook.LoadFromFile("sample.csv", ",", 1, 1)# 设置页面缩放,确保内容适配一页workbook.ConverterSetting.SheetFitToPage = True# 获取第一个工作表sheet = workbook.Worksheets[0]# 自动调整每一列的列宽,避免内容被截断i = 1while i < sheet.Columns.Length: sheet.AutoFitColumn(i) i += 1# 导出为 PDFworkbook.SaveToFile("CSVToPDF.pdf", FileFormat.PDF)workbook.Dispose()加载CSV文件:Workbook 是操作的核心类。LoadFromFile 方法除了传入文件路径外,还支持指定分隔符、起始读取行和起始读取列。例如 ",", 1, 1 表示以逗号为分隔符,从第一行第一列开始读取。如果你的CSV文件使用制表符或分号分隔,只需替换为 "t" 或 ";" 即可。
一页完整显示:workbook.ConverterSetting.SheetFitToPage = True 是一个容易被忽略却至关重要的设置。如果不开启此项,当表格列数较多时,导出的PDF可能会将内容拆分到多页,阅读时需要来回翻页,非常不便。开启后,PDF页面会自动缩放,保证所有列在一页内完整呈现。
自动调整列宽:通过循环调用 sheet.AutoFitColumn(i),让每一列的宽度根据该列最长文本内容自动调整。这样既能避免文字重叠或显示为"####",也能让表格看起来更加整洁专业。
导出为PDF:最后调用 SaveToFile 并指定 FileFormat.PDF,即可生成PDF文件。Dispose 方法用于释放资源,养成良好习惯。
上面的示例已经能满足基本需求,但如果你希望PDF的样式更加精致,Spire.XLS 还提供了更多定制选项。例如,设置字体、字号、对齐方式,或调整页面方向:
# 设置全局字体和字号sheet.AllocatedRange.Style.Font.FontName = "Arial"sheet.AllocatedRange.Style.Font.Size = 14# 设置水平居中对齐sheet.AllocatedRange.Style.HorizontalAlignment = HorizontalAlignType.Center# 将页面方向调整为横向sheet.PageSetup.Orientation = PageOrientationType.Landscape
这些设置能让导出的PDF更加符合正式文档的要求。
这一方案尤其适合以下场景:
方法一:使用 Pandas + Matplotlib(将表格转为图片 PDF)
这种方法将数据框绘制为 Matplotlib 表格,然后保存为 PDF(本质是图片)。优点是代码简单,缺点是生成的 PDF 不可选择文本,且缩放可能模糊。
import pandas as pdimport matplotlib.pyplot as pltfrom matplotlib.table import Tabledef csv_to_pdf_matplotlib(csv_path, pdf_path, title='数据报表'): """ 将 CSV 文件转为 PDF(表格图片形式) """ df = pd.read_csv(csv_path) fig, ax = plt.subplots(figsize=(12, len(df) * 0.4 + 2)) ax.axis('off') ax.set_title(title, fontsize=16, pad=20) # 创建表格 tb = Table(ax, bbox=[0, 0, 1, 1]) nrows, ncols = df.shape col_width = 1.0 / ncols row_height = 1.0 / (nrows + 1) # 添加表头(背景色浅蓝) for j, col_name in enumerate(df.columns): tb.add_cell(0, j, col_width, row_height, text=col_name, loc='center', facecolor='#4472C4', text_props=dict(color='white', weight='bold')) # 添加数据行 for i, row in df.iterrows(): for j, val in enumerate(row): tb.add_cell(i + 1, j, col_width, row_height, text=str(val), loc='center') ax.add_table(tb) plt.savefig(pdf_path, dpi=300, bbox_inches='tight') plt.close() print(f'✅ PDF 已保存至: {pdf_path}')# 使用示例csv_to_pdf_matplotlib('trades.csv', 'trades_report.pdf')方法二:使用 ReportLab(生成真正的 PDF 表格,可复制文本)
ReportLab 是 Python 生成 PDF 的专业库,能产生矢量文本,样式可控性强,适合需要高质量打印或正式报告的场景。
import pandas as pdfrom reportlab.lib.pagesizes import A4, landscapefrom reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacerfrom reportlab.lib import colorsfrom reportlab.lib.styles import getSampleStyleSheet, ParagraphStylefrom reportlab.lib.enums import TA_CENTERfrom reportlab.pdfbase import pdfmetricsfrom reportlab.pdfbase.ttfonts import TTFont # 用于中文def csv_to_pdf_reportlab(csv_path, pdf_path, title='交易记录报表'): """ 使用 ReportLab 将 CSV 转为可复制文本的 PDF """ # 注册中文字体(如果需要) try: pdfmetrics.registerFont(TTFont('SimHei', 'SimHei.ttf')) # 请确保字体文件存在 cn_font = 'SimHei' except: cn_font = 'Helvetica' # 回退,中文可能显示为方框 df = pd.read_csv(csv_path) # 创建 PDF 文档(横向 A4) doc = SimpleDocTemplate(pdf_path, pagesize=landscape(A4), rightMargin=30, leftMargin=30, topMargin=30, bottomMargin=30) # 构建内容列表 elements = [] # 标题样式 styles = getSampleStyleSheet() title_style = ParagraphStyle( 'CustomTitle', parent=styles['Heading1'], fontName=cn_font, fontSize=18, alignment=TA_CENTER, spaceAfter=20 ) elements.append(Paragraph(title, title_style)) elements.append(Spacer(1, 12)) # 准备表格数据:将 DataFrame 转为列表,并插入表头 data = [df.columns.tolist()] + df.values.tolist() # 创建表格(样式) table = Table(data, repeatRows=1) # 表头在每页重复 # 设置表格样式 style = TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.HexColor('#4472C4')), ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke), ('ALIGN', (0, 0), (-1, -1), 'CENTER'), ('FONTNAME', (0, 0), (-1, 0), cn_font), ('FONTSIZE', (0, 0), (-1, 0), 10), ('FONTNAME', (0, 1), (-1, -1), cn_font), ('FONTSIZE', (0, 1), (-1, -1), 8), ('BOTTOMPADDING', (0, 0), (-1, 0), 8), ('TOPPADDING', (0, 0), (-1, 0), 8), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'), ('BACKGROUND', (0, 1), (-1, -1), colors.beige), ('ROWBACKGROUNDS', (0, 1), (-1, -1), [colors.whitesmoke, colors.lightgrey]), ]) table.setStyle(style) # 如果数据量很大,可启用分页 elements.append(table) doc.build(elements) print(f'✅ PDF 已保存至: {pdf_path}')# 使用示例csv_to_pdf_reportlab('trades.csv', 'trades_report.pdf')注意:如果需要显示中文,请确保系统中有中文字体文件(如 SimHei.ttf),并放置在可访问路径,或者直接指定系统字体路径(如 /System/Library/Fonts/PingFang.ttc)。
利用 Spire.XLS for Python,只需十几行代码即可完成CSV到PDF的转换,同时还能对表格样式进行灵活控制。SheetFitToPage 与 AutoFitColumn 的组合使用,是保证输出页面整洁美观的关键。如果你正被CSV的"素颜"困扰,不妨试试这个方案。