简体   繁体   English

使用 Google Drive API 在 Apps Script 中将 Google Docs 文件转换为 PDF

[英]Converting a Google Docs file to PDF in Apps Script using Google Drive API

I'm trying to convert a Docs file to PDF in GAS, using Drive API.我正在尝试使用驱动器 API 将文档文件转换为 GAS 中的 PDF。

Based on what I found, basically the steps are:根据我的发现,基本上步骤是:

  1. Get the Docs file获取文档文件
  2. Convert to PDF转换为 PDF
  3. Upload to Drive上传到云端硬盘

What I did was use the 'export' function to get the Docs and convert it to PDF, then 'create' function to upload.我所做的是使用“导出”function 获取文档并将其转换为 PDF,然后“创建”function 进行上传。 My code below:我的代码如下:

function test(){
  let service = getOAuthService();
  service.reset();

  // Get the Docs file
  let url = encodeURI("https://www.googleapis.com/drive/v3/files/<id of file>/export?mimeType=application/pdf&supportsAllDrives=true");

  let docFile = getGoogleAPI(url);

  var fileName = "my-test-file.pdf";
  var fileContent = docFile.getBlob();

  var fileMetadata = {
    name: fileName,
    parents: ["<id of parent folder>"],
    mimeType: "application/pdf"
  };

  url = "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart&supportsAllDrives=true";

  var header = {
    "Authorization": "Bearer " +  service.getAccessToken(),
    "Content-Type": "multipart/related; boundary=<BOUNDARY_STRING>"
  };

  var body = "--<BOUNDARY_STRING>\r\n" +
             "Content-Type: application/json; charset=UTF-8\r\n\r\n" +
             JSON.stringify(fileMetadata) + "\r\n" +
             "--<BOUNDARY_STRING>\r\n" +
             "Content-Type: application/pdf\r\n\r\n" +
             fileContent + "\r\n" +
             "--<BOUNDARY_STRING>--";

  let response = UrlFetchApp.fetch(url, {
    method: "post",
    headers: header,
    payload: body,
    muteHttpExceptions: true
  });

  var responseJson = JSON.parse(response.getContentText());

  if (response.getResponseCode() == 200) {
    Logger.log("File uploaded successfully with ID: " + responseJson.id);
  } else {
    Logger.log("Error uploading file: " + responseJson.error.message);
  }
}

However the generate PDF file is either empty or not in the correct PDF format (cannot preview).然而,生成的 PDF 文件要么是空的,要么不是正确的 PDF 格式(无法预览)。

I think the first part (getting the Docs file using export) works, but it's the uploading that has the problem.我认为第一部分(使用导出获取 Docs 文件)有效,但上传有问题。 Maybe an incorrect encoding?也许编码不正确?

Does anyone know where I am wrong on this?有谁知道我错在哪里?

Thanks in advance!提前致谢!

In your script, fileContent is Blob.在您的脚本中, fileContent是 Blob。 Unfortunately, Blob cannot be directly used in this request body.不幸的是,Blob 不能直接用于此请求正文中。 I think that this is the reason for your current issue.我认为这就是您当前问题的原因。 In this case, how about the following modification?在这种情况下,如何进行以下修改?

Pattern 1:模式 1:

When your request body is modified, please modify it as follows.当您的请求正文被修改时,请修改如下。

From:从:

"Content-Type: application/pdf\r\n\r\n" +
fileContent + "\r\n" +

To:到:

"Content-Transfer-Encoding: base64\r\n\r\n" +
Utilities.base64Encode(fileContent.getBytes()) + "\r\n" +
  • In your script, you are using text data as the request body.在您的脚本中,您使用文本数据作为请求正文。 So, I used the above modification.所以,我使用了上面的修改。

Pattern 2:模式 2:

As another pattern, when your fileContent of Blob is directly used in the request body, please modify it as follows.作为另一种模式,当你的 Blob 的fileContent直接在请求体中使用时,请修改如下。

From:从:

var header = {
  "Authorization": "Bearer " +  service.getAccessToken(),
  "Content-Type": "multipart/related; boundary=<BOUNDARY_STRING>"
};

var body = "--<BOUNDARY_STRING>\r\n" +
           "Content-Type: application/json; charset=UTF-8\r\n\r\n" +
           JSON.stringify(fileMetadata) + "\r\n" +
           "--<BOUNDARY_STRING>\r\n" +
           "Content-Type: application/pdf\r\n\r\n" +
           fileContent + "\r\n" +
           "--<BOUNDARY_STRING>--";

let response = UrlFetchApp.fetch(url, {
  method: "post",
  headers: header,
  payload: body,
  muteHttpExceptions: true
});

To:到:

let response = UrlFetchApp.fetch(url, {
  payload: {
    metadata: Utilities.newBlob(JSON.stringify(fileMetadata), "application/json"),
    file: fileContent,
  },
  headers: { authorization: "Bearer " + service.getAccessToken() },
  muteHttpExceptions: true
});
  • In this case, the structure of multipart/form-data is automatically created on the internal server side.在这种情况下, multipart/form-data的结构是在内部服务器端自动创建的。
  • This modification can obtain the same result as the above one.这种修改可以得到与上述相同的结果。

Note:笔记:

  • In this modification, it supposes that your value of fileContent is the correct blob, and also, it supposes that your access token of "Bearer " + service.getAccessToken() can be used for uploading the file to Google Drive.在此修改中,它假定您的fileContent值是正确的 blob,并且还假定您的访问令牌"Bearer " + service.getAccessToken()可用于将文件上传到 Google 云端硬盘。 Please be careful about this.请注意这一点。

Reference:参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM