发布于 

HTML页面转换成PDF

方法一:

用到的库 参考:http://kaito-kidd.com/2015/03/12/python-html2pdf/
import pdfkit
用法:

pdfkit.url('http://www.baidu.com', 'path/out.pdf')  # 读取url转PDF

pdfkit.html('path/test.html', 'path/out.pdf') # html页面转PDF

pdfkit.string('hello!', 'path/out.pdf') . # 字符串转PDF

实例代码:

html = render_template('path.html', items=items)
# 页面用到的css文件
css = [current_app.root_path + url_for('static', filename='path.css'),
current_app.root_path + url_for('static', filename='path.js')]

# 一些API
# 导出的PDF页面参数的设置
options = {
'page-size': 'Letter',
'margin-top': '0.25in',
'margin-right': '0.2in',
'margin-bottom': '0.25in',
'margin-left': '0.2in'
}

filename = 'path/filename.pdf'
pdfkit.from_string(html, filename, css=css, options=options)

这个方法比较缺点是,页面渲染很难调,页面样式不兼容,中文乱码等问题。解决中文乱码
不建议在生产环境中使用,有坑。生产环境X server问题

方法二、

xhtml2pdf
官方文档

示例代码:

from xhtml2pdf import pisa

# Define your data
sourceHtml = "<html><body><p>To PDF or not to PDF</p></body></html>"
outputFilename = "test.pdf"

# Utility function
def convertHtmlToPdf(sourceHtml, outputFilename):
# open output file for writing (truncated binary)
resultFile = open(outputFilename, "w+b")

# convert HTML to PDF
pisaStatus = pisa.CreatePDF(
sourceHtml, # the HTML to convert
dest=resultFile) # file handle to recieve result

# close output file
resultFile.close() # close output file

# return True on success and False on errors
return pisaStatus.err

# Main program
if __name__ == "__main__":
pisa.showLogging()
convertHtmlToPdf(sourceHtml, outputFilename)

也可以生成PDF文件不存在本地,直接响应PDF文件,声明application/pdf文件类型

# 渲染页面 这里用到的是flask框架
html = render_template('path/report_detail.html',
data=data, # 页面要渲染的数据
font_path='path/msyh.ttf', # 因为是PDF文件的中文编码问题,所以要指定兼容中文的字体文件
logo='path/assets/images/logo/dianyi_logo.jpg') # 静态文件都要用这种方式传过去

# 因为css,和js 在生成的PDF文件里样式并不一定生效,所以干脆不传样式文件了。(所以只能生成一下简单一点的PDF文件了)

filename = 'report.pdf'
result = BytesIO() # 打开字节流
# 生成pdf
pdf = pisa.CreatePDF(BytesIO(html.encode('utf-8')), result, encoding='utf-8') # 生成PDF文件
resp = make_response(result.getvalue()) # 生成http-Response 响应的就是PDF文件的值
result.close()
resp.headers["Content-Disposition"] = (f"inline; filename='{filename}'") # inline 是在浏览器预览,attachment 是直接下载
resp.headers['Content-Type'] = 'application/pdf'
resp.headers['verify'] = 'false'
return resp

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 @nnocase 创建,使用 Stellar 作为主题,您可以在 GitHub 找到本站源码。