【问题标题】:Upload a pdf file to Google Cloud Storage with Node.js使用 Node.js 将 pdf 文件上传到 Google Cloud Storage
【发布时间】:2023-03-13 08:32:01
【问题描述】:

我是上传到 Google Cloud Buckets 的新手,在将 pdf 文档上传到 Google Cloud Bucket 时遇到问题。目的是使用 PDFKit 创建一个 pdf 文档,将其发送到 Bucket,然后以文件的 url 响应,然后可以在客户端使用该文件下载文件。

当前,一个文件正在上传到存储桶,但在尝试打开它时说它已损坏,从前端下载的文件也是如此。

这是我目前拥有的创建方法:

const PDFDocument = require('pdfkit');
const storage = require('./storage');

async function create(req, res) {
  const doc_name = `invoice_${req.body.id}.pdf`;
  const doc = new PDFDocument({
    compress: false,
  });
  doc.fontSize(12);
  doc.text('PDFKit is simple', 10, 30, {
    align: 'center',
    width: 200,
  });
  doc.end();
  const fileId = await storage.upload(doc, req.account.id);
  const url = await storage.getSignedURL(fileId, doc_name);

  res.send(JSON.stringify({ doc: { url: url[0], name: doc_name } }));
}

module.exports = create;

这是使用以下方式上传文件:

const { Storage } = require('@google-cloud/storage');
const moment = require('moment');
const stream = require('stream');
const uuidv4 = require('uuid/v4');

const storage = new Storage();
const bucket = storage.bucket(process.env.GOOGLE_STORAGE_BUCKET);
const fileSuffix = 'pdf';

const getBucketFile = fileName => bucket.file(`${fileName}.${fileSuffix}`);
const getSignedURL = (fileName, name) => {
  const file = getBucketFile(fileName);
  const config = {
    action: 'read',
    expires: moment()
      .add(6, 'd')
      .format('MM-DD-YYYY'),
    responseDisposition: `inline; filename=${name}`,
  };
  return file.getSignedUrl(config);
};

const upload = (data, prefix) => new Promise((resolve, reject) => {
  const uuid = `${prefix}/${uuidv4()}`;
  const stream = require('stream');
  const bufferStream = new stream.PassThrough();
  bufferStream.end(Buffer.from(data.toString(), 'base64'));
  const file = getBucketFile(uuid);
  bufferStream
    .pipe(file.createWriteStream())
    .on('error', err => reject(err))
    .on('finish', () => resolve(uuid));
});

module.exports = {
  getSignedURL,
  upload,
};

我见过其他人使用 firebase,但我正在努力翻译到谷歌云。任何帮助将不胜感激!

【问题讨论】:

  • 添加HTTP头“content-type: application/pdf”iana.org/assignments/media-types/media-types.xhtml
  • 嗨@JohnHanley,感谢您的回复。我添加了 setHeader('Content-Type', 'application/pdf');以及 create 方法中 res.send 之前的内容处置标头,但它仍然说文件已损坏或损坏。
  • @ThomasAllen 你找到解决方法了吗?我遇到了同样的问题。上传到 Google 的文件为零字节,无法加载。我也在使用 PDFKit 生成文件。谢谢
  • 我在等待 2 秒后最终工作了......我认为问题在于,我试图上传 PDFKit 文件,但它还没有在磁盘上准备好。

标签: javascript node.js pdf google-cloud-storage response


【解决方案1】:

我已修改您上传到适合我的版本:

const { Storage } = require("@google-cloud/storage");
const { v4: uuidv4 } = require("uuid");
const bucketName = require("../config/endpoints").BUCKETNAME;

const storage = new Storage();

const bucket = storage.bucket(bucketName);
const fileSuffix = "pdf";

const getBucketFile = fileName => 
   bucket.file(`${fileName}.${fileSuffix}`);
const getSignedURL = async fileName => {
  let validTime = new Date();
  validTime.setHours(validTime.getHours() + 1);
  const config = {
    version: "v4",
    action: "read",
    expires: validTime
  };

  const signedUrl = await storage
     .bucket(bucketName)
     .file(fileName)
     .getSignedUrl(config);
  return signedUrl;
};

const upload = (data) =>
   new Promise((resolve, reject) => {
   const uuid = `pdf/${uuidv4()}`;
   const file = getBucketFile(uuid);
   const stream = file.createWriteStream({
     metadata: {
       "Content-Type": "application/pdf",
       "content-Disposition": `attachment; filename=${uuid}.pdf`
     },
     resumable: false
   });
   stream.on("error", err => {
      reject(error);
   }); 

   stream.on("finish", () => {
     resolve(uuid);
   });

   stream.end(Buffer.from(data.toString(), "binary"));
 });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-04-10
    • 2018-10-31
    • 1970-01-01
    • 1970-01-01
    • 2021-01-05
    • 2018-12-23
    • 1970-01-01
    • 2017-04-02
    相关资源
    最近更新 更多