使用 Python 将 Pandas DataFrame 导出为 PDF 文件

Posted

技术标签:

【中文标题】使用 Python 将 Pandas DataFrame 导出为 PDF 文件【英文标题】:Export Pandas DataFrame into a PDF file using Python 【发布时间】:2021-11-05 15:17:18 【问题描述】:

在 Pandas 中为数据框生成 PDF 的有效方法是什么?

【问题讨论】:

【参考方案1】:

第一个带有matplotlib 的绘图表然后生成pdf

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

df = pd.DataFrame(np.random.random((10,3)), columns = ("col 1", "col 2", "col 3"))

#https://***.com/questions/32137396/how-do-i-plot-only-a-table-in-matplotlib
fig, ax =plt.subplots(figsize=(12,4))
ax.axis('tight')
ax.axis('off')
the_table = ax.table(cellText=df.values,colLabels=df.columns,loc='center')

#https://***.com/questions/4042192/reduce-left-and-right-margins-in-matplotlib-plot
pp = PdfPages("foo.pdf")
pp.savefig(fig, bbox_inches='tight')
pp.close()

参考:

How do I plot only a table in Matplotlib?

Reduce left and right margins in matplotlib plot

【讨论】:

与 LaTeX 或 troff 相比,这些通过 matplotlib 生成的表格看起来不太好。 @Merlin,df.to_latex 可以输出 pdf 文件吗?流程/要求是什么?【参考方案2】:

这是我使用 sqlite3、pandas 和 pdfkit 从 sqlite 数据库中执行此操作的方法

import pandas as pd
import pdfkit as pdf
import sqlite3

con=sqlite3.connect("baza.db")

df=pd.read_sql_query("select * from dobit", con)
df.to_html('/home/linux/izvestaj.html')
nazivFajla='/home/linux/pdfPrintOut.pdf'
pdf.from_file('/home/linux/izvestaj.html', nazivFajla)

【讨论】:

pdfkit 不适用于 windows64 效果很好!在 Mac 上安装 Pdfkit:pip install pdfkit && brew install Caskroom/cask/wkhtmltopdf【参考方案3】:

一种方法是使用降价。您可以使用df.to_html()。这会将数据框转换为 html 表。从那里您可以将生成的 html 放入降价文件 (.md)(请参阅 http://daringfireball.net/projects/markdown/basics)。从那里,有一些实用程序可以将 markdown 转换为 pdf (https://www.npmjs.com/package/markdown-pdf)。

此方法的一个多合一工具是使用 Atom 文本编辑器 (https://atom.io/)。在那里您可以使用扩展程序,搜索“markdown to pdf”,这将为您进行转换。

注意:最近使用to_html() 时,出于某种原因,我不得不删除多余的“\n”字符。我选择使用Atom -> Find -> '\n' -> Replace ""

总的来说,这应该可以解决问题!

【讨论】:

我认为将中间步骤转换为 HTML,然后 Markdown(甚至没有标准规范),然后转换为 pdf 的解决方案不是一个好方法。 您现在可以使用.to_markdown() 来完全避免使用 HTML。【参考方案4】:

这是一个带有中间 pdf 文件的解决方案。

这个表格用一些最小的 css 打印得很漂亮。

pdf 转换是用 weasyprint 完成的。你需要pip install weasyprint

# Create a pandas dataframe with demo data:
import pandas as pd
demodata_csv = 'https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv'
df = pd.read_csv(demodata_csv)

# Pretty print the dataframe as an html table to a file
intermediate_html = '/tmp/intermediate.html'
to_html_pretty(df,intermediate_html,'Iris Data')
# if you do not want pretty printing, just use pandas:
# df.to_html(intermediate_html)

# Convert the html file to a pdf file using weasyprint
import weasyprint
out_pdf= '/tmp/demo.pdf'
weasyprint.HTML(intermediate_html).write_pdf(out_pdf)

# This is the table pretty printer used above:

def to_html_pretty(df, filename='/tmp/out.html', title=''):
    '''
    Write an entire dataframe to an HTML file
    with nice formatting.
    Thanks to @***user2010 for the
    pretty printer see https://***.com/a/47723330/362951
    '''
    ht = ''
    if title != '':
        ht += '<h2> %s </h2>\n' % title
    ht += df.to_html(classes='wide', escape=False)

    with open(filename, 'w') as f:
         f.write(HTML_TEMPLATE1 + ht + HTML_TEMPLATE2)

HTML_TEMPLATE1 = '''
<html>
<head>
<style>
  h2 
    text-align: center;
    font-family: Helvetica, Arial, sans-serif;
  
  table  
    margin-left: auto;
    margin-right: auto;
  
  table, th, td 
    border: 1px solid black;
    border-collapse: collapse;
  
  th, td 
    padding: 5px;
    text-align: center;
    font-family: Helvetica, Arial, sans-serif;
    font-size: 90%;
  
  table tbody tr:hover 
    background-color: #dddddd;
  
  .wide 
    width: 90%; 
  
</style>
</head>
<body>
'''

HTML_TEMPLATE2 = '''
</body>
</html>
'''

感谢@***user2010 提供漂亮的打印机,请参阅***user2010 的回答https://***.com/a/47723330/362951

我没有使用 pdfkit,因为我在无头机器上遇到了一些问题。但是 weasyprint 很棒。

【讨论】:

你知道如何强制分页吗?假设我有一个 pandas 数据框的几个表切片,我希望每个表都从一个新页面开始。这可能吗?我应该在什么时候编辑 html 代码? 谢谢!如何使其以横向/不同的页面大小打印?【参考方案5】:

参考这两个我觉得有用的例子:

Apply CSS class to Pandas DataFrame using to_html https://pbpython.com/pdf-reports.html

简单的 CSS 代码保存在与 ipynb 相同的文件夹中:

/* includes alternating gray and white with on-hover color */

.mystyle 
    font-size: 11pt; 
    font-family: Arial;
    border-collapse: collapse; 
    border: 1px solid silver;



.mystyle td, th 
    padding: 5px;


.mystyle tr:nth-child(even) 
    background: #E0E0E0;


.mystyle tr:hover 
    background: silver;
    cursor: pointer;

python代码:

pdf_filepath = os.path.join(folder,file_pdf)
demo_df = pd.DataFrame(np.random.random((10,3)), columns = ("col 1", "col 2", "col 3"))

table=demo_df.to_html(classes='mystyle')

html_string = f'''
<html>
  <head><title>HTML Pandas Dataframe with CSS</title></head>
  <link rel="stylesheet" type="text/css" href="df_style.css"/>
  <body>
    table
  </body>
</html>
'''

HTML(string=html_string).write_pdf(pdf_filepath, stylesheets=["df_style.css"])

【讨论】:

最后一行的 HTML 是什么? HTML 在 python 代码中生成为字符串。我不是 100% 确定你的问题是什么意思? HTML 是从 python 的 'weasyprint' 模块导入的 - pypi.org/project/weasyprint 另外请注意,如果您的系统没有足够新的libpango 版本,您可以固定weasyprint==52.5,它不依赖于libpango&gt;=1.44.0

以上是关于使用 Python 将 Pandas DataFrame 导出为 PDF 文件的主要内容,如果未能解决你的问题,请参考以下文章

Python/Pandas 遍历列

如何在python pandas中附加两个数据框[重复]

将 CSV 读入 Pandas 后 MultiLabelBinarizer() 的格式问题

Pandas文摘:Applying Operations Over pandas Dataframes

python-pandas基础数据结构(DataFrame)

如何将时间范围绘制为 Pandas 或 MatPlotLib 中的值