查看原文
其他

使用WeasyPrint自动生成pdf报告文件

大邓 大邓和他的Python 2022-07-09

Pandas非常善于处理大规模数据,支持将结果导出到CSV,Excel,HTML,json等文件中。如果您想将 多种信息(excel、图片等)组合 到一个文档中,那么事情变得更加困难。例如,如果要在一个Excel工作表上放置两个DataFrame,则需要使用相应的Excel库才能输出。这当然是OK的,但走起来真不简单。本文将介绍一种方法,将多种 信息(excel、图片等)组合 成一个 HTML模板 ,然后使用Jinja模板和WeasyPrint 再将其转换为独立的PDF文档。

操作流程

使用Pandas将数据输出到Excel文件中的多个工作表或者用DataFrames创建多个Excel文件非常方便。但是,如果您想将 多种信息(excel、图片等)组合 输出到一个文件中,那么直接从Pandas进行操作的方法并不多。幸运的是,万能的python大法有很多选项可以帮助我们。

在本文中,我将采用以下流程来创建多页PDF文档。


工具

我决定使用HTML作为模板语言,因为它可能是生成结构化数据最便捷的方法,支持各种格式数据(如图片、excel表)。我也认为每个人都知道(或可以弄清楚)足够的HTML知识来生成一个简单的报告。

这个工作流程中最困难的部分是弄清楚如何将HTML呈现为PDF。我觉得还没有最佳的解决方案,但我选择了 WeasyPrint ,因为它仍然在积极维护,我发现我可以相对容易地使它工作。作为替代方案,我过去使用过xhtml2pdf,它的效果也很好,遗憾的是该库缺乏文档说明,但它已存在一段时间,并且确实可以从HTML生成PDF。


数据

如上所述,我们将使用之前文章中的相同数据集。为了使这一切成为一个独立的文章,下面是我如何导入数据,做描述性统计,及并生成关于CPU和软件销售的 数据透视表

导入模块,并读入销售渠道信息。

import pandas as pd
import numpy as np

df = pd.read_excel('salesfunnel.xlsx')
df.head()

对数据做透视表

sales_report = pd.pivot_table(df, index=["Manager""Rep""Product"], 
                              values=["Price""Quantity"],
                              aggfunc=[np.sum, np.mean], 
                              fill_value=0)
sales_report.head()


模板

DataFrame拥有to_html()的方法,可以将dataframe数据转化为含有HTML格式的字符串。

但是随着您的报告变得越来越复杂或您选择将Jinja模板用于您的网络应用,jinja的这些功能将为您提供良好的服务。Jinja的另一个不错的功能是它包含多个内置过滤器,这些过滤器允许我们以Pandas中难以做到的方式格式化我们的一些数据。

为了在我们的应用程序中使用Jinja,我们需要做三件事:

1. 创建一个模板
2. 将变量添加到模板上下文中
3. 将模板渲染为HTML

这是一个非常简单的模板,我们称之为myreport.html:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>{{ title }}</title>
</head>
<body>
    <h2>Sales Funnel Report - National</h2>
     {{ national_pivot_table }}
</body>
</html>

上面html代码中拥有 {{title}} 和 {{national_pivot_table }} 这两个关键词。这两个关键词用来接收需要渲染的数据,比如图片对象、dataframe对象等。

要填充这些变量,我们需要创建一个Jinja环境并获取我们的模板对象:

from jinja2 import Environment, FileSystemLoader
env = Environment(loader=FileSystemLoader('.'))
template = env.get_template('myreport.html')

在上面的示例中,我假设模板位于当前目录中,但您可以将完整路径放到模板位置。

另一个关键组件是 env 的创建。这个变量是我们将数据(或对象)填充给模板的方式。我们创建了一个名为 template_var 的字典,其中包含我们想要传递给模板的所有变量。

请注意变量的名称如何与我们的模板匹配。即名称要与myreport.html中的{{}}夹住的关键词一样。

template_vars = {"title" : "Sales Funnel Report - National",
                 "national_pivot_table": sales_report.to_html()}

最后一步是将 template_vars 渲染到html模板中,并输出为html字符串,最终我们将使用该html字符串来生成pdf报告。

html_out = template.render(template_vars)

为简洁起见,我不会显示完整的HTML,但您应该明白这一点。


生成pdf

pdf报告的生成部分相当简单,这里用到weasyprint库

from weasyprint import HTML
HTML(string=html_out).write_pdf("report.pdf")

但是打开的pdf样式很简单,白底黑字并不美观。之所以这样是因为我们没有使用自定义样式表css,但是咱们不熟悉css,有一种简单的办法就是用成熟的css,这里我用的typography.css 作为填充表格时的样式表。这个css的优点有:

1. 相对较小且易于理解
2. 可以在PDF引擎中运行而不会抛出错误和警告
3. 能让表格表格看起来很美观

让我们尝试使用我们更新的样式表重新渲染它:

HTML(string=html_out).write_pdf('beautiful_report.pdf', stylesheets=["typography.css"])

添加了一个stylesheets参数就让输出结果瞬间变得高端大气上档次。


更多

如果想更加丰富的输出pdf报告,大家回去需要查阅jinja文档,找一些css样式表。

下载代码

https://hidadeng.github.io/blog/weasyprint_auto_report/weasyprint_auto_report.zip

感兴趣的也可以收藏我的博客站点https://hidadeng.github.io



近期文章

视频专栏课 | Python网络爬虫与文本分析

读完本文你就了解什么是文本分析

综述:文本分析在市场营销研究中的应用

营销研究中文本分析应用概述(含案例及代码)

Pandas库 | 高速读取csv文件的方法

如何在DataFrame中使用If-Else条件语句创建新列

BERTopic 主题建模库 | 建议收藏

Top2Vec | 主题建模和语义搜索库

案例实战 | 企业信息数据采集

使用文本相似度可以识别变化的时间点

PNAS | 文本网络分析&文化桥梁Python代码实现

tomotopy | 速度最快的LDA主题模型

dvt | 视觉文化分析的Python工具包

Stargazer库 | 创建漂亮可发表的多元回归表

人文社科类Python免费教程列表

量化历史语言学-贝叶斯语言谱系分析

Python与文化分析入门

Backtrader库 | 均线买入卖出策略实现

在会计研究中使用Python进行文本分析

文本分析方法在《管理世界》(2021.5)中的应用

hiResearch 定义自己的科研首页

SciencePlots | 科研样式绘图库

Wow~70G上市公司定期报告数据集

漂亮~pandas可以无缝衔接Bokeh  

YelpDaset: 酒店管理类数据集10+G

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存