【问题标题】:How to upload an html string as pdf file to Google Cloud Storage ? (Python)如何将 html 字符串作为 pdf 文件上传到 Google Cloud Storage? (Python)
【发布时间】:2020-08-28 17:43:33
【问题描述】:

我正在尝试从我的 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 文件从前端上传到 GCS 存储桶?
  • @JAHDZP 文件大小不会太大。小于 10 MB(通常本身小于 1 MB,但有时大小会更大)。文件的数量也可以从大约 5 到
  • @JAHDZP,另外,我正在尝试从后端上传文件。

标签: django python-3.x google-cloud-platform google-cloud-storage pdfkit


【解决方案1】:

您可以使用临时文件在磁盘上写入您的 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
  • 在后端创建一个 HTML 文件,其中包含所有信息和 使用 base 64 嵌入的图像
  • 我使用 celery 创建任务队列,创建 pdf 需要 30 秒 因为每份报告都有 500 - 1K 页

我在这个github file中找到了类似的方法

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 

【讨论】:

  • 这不会将文件写为 HTML 而不是 PDF 吗?我不必使用pdfkit 之类的东西将 HTML 字符串写为 PDF 文件吗? (使用 pdfkit,我什至尝试将其写入本地文件,但转换导致了一个或另一个格式问题)
  • 如果你能提供任何代码参考,关于使用你提到的pdfkit,那就太好了。
猜你喜欢
  • 1970-01-01
  • 2019-01-11
  • 2023-03-13
  • 2016-08-28
  • 2014-01-05
  • 1970-01-01
  • 2020-01-16
  • 2018-12-23
  • 1970-01-01
相关资源
最近更新 更多