如何将 html 字符串作为 pdf 文件上传到谷歌云存储?(蟒蛇)



我正在尝试从我的 Django 应用程序将一个HTML字符串作为PDF文件上传到 GCS。

import google, os
from google.cloud import storage

class GcpHelper:
def __init__(self, bucket_name):
self.service_account_json_path = 'google_auth.json'
storage_client = storage.Client.from_service_account_json(self.service_account_json_path)
try:
self.__bucket_name = bucket_name
self.bucket = storage_client.get_bucket(bucket_name)
except Exception as err:
logger.error("Error {} while connecting to bucket {}!".format(str(err), bucket_name))

def put_data_in_bucket(self, file_name, data, content_type="application/pdf"):
"""Uploads data to gcp bucket"""
try:
blob = self.bucket.blob(file_name)
blob.upload_from_string(data, content_type=content_type)
return True
except Exception as err:
logger.error("Unable to upload file {} due to {}".format(file_name, str(err)))
raise Exception("Write to gcp failed!")

gcp_helper = GcpHelper('bucket_name')
voucher_html = open('voucher_test.html').read()
#some operations on voucher_html string here
gcp_helper.put_data_in_bucket("booking/voucher.pdf", voucher_html)

我试图以某种方式直接上传字符串,而不是将其另存为 PDF 文件然后上传文件。(如果没有任何效果,那么将不得不这样做(

但是,当然这不起作用,因为上传的PDF文件已损坏。我希望blob.upload_from_string能够处理所需的任何格式/编码。但看起来并非如此。;)

您可以使用临时文件在磁盘上写入您的 PDF,然后将文件上传到云存储

import os
from tempfile import NamedTemporaryFile

with NamedTemporaryFile(mode='w+b') as temp:
#data msut be the file that came from the request
temp.write(data)
temp.close()
with open(temp.name, 'rb') as pdf:
blob.upload_from_file(pdf)

GCS永远不会将您的HTML转换为PDF文件

将HTML转换为PDF始终是一项艰巨的任务,但是没有办法使用Cloud Storage自动执行此操作。

要使用pdfkit并避免任何格式问题,我建议:

  • 使用纯HTML5+CSS,减少JS的使用
  • 使用图像而不是JS图形
  • 仅使用香草 JS
  • 加载图像
  • 的最快方法是将图像加载为 base64 字符串

在过去的项目中,使用过这种策略:

  • 使用幻影创建我的图像,因为我有很多美丽的 图表,但使用 JS
  • 在后端创建一个包含所有信息和 使用 Base 64 嵌入的图像
  • 我用芹菜创建了一个任务队列,pdf 的创建花了我 30 秒 因为每个报告都有 500 - 1K 页

我在这个 github 文件中发现了类似的方法

def to_pdf(self):
template = get_template('{template}/{template}.html'.format(template=self.html_template))
invoice = template.render({
'site': Site.objects.get_current(),
'invoice': self,
'users': (
('provider', self.provider),
('client', self.client),
),
'line_items': self.aggregate_line_items(),
'currency': self.hourly_rate.hourly_rate_currency
})
self.pdf_path = os.path.join(settings.INVOICE_PDF_PATH, '{}.pdf'.format(uuid.uuid4()))
pdf_configuration = pdfkit.configuration(wkhtmltopdf=settings.HTML_TO_PDF_BINARY_PATH)
pdfkit.from_string(invoice, self.pdf_path, configuration=pdf_configuration, options=self.PDF_OPTIONS)
return self.pdf_path 

最新更新