Google Apps Script - 将带有样式的 HTML 转换为 PDF 并附加到电子邮件 - 从 HTML 创建 PDF blob [英] Google Apps Script - Convert HTML with styling to PDF and attach to an email - Create a PDF blob from HTML

查看:19
本文介绍了Google Apps Script - 将带有样式的 HTML 转换为 PDF 并附加到电子邮件 - 从 HTML 创建 PDF blob的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望 Google Apps 脚本表单中的 HTML 获得两种不同的样式,一种用于电子邮件正文,另一种用于 PDF 文件.

当前代码:

function doGet(request) {返回 HtmlService.createTemplateFromFile('index').evaluate();//不是全部大写,但它必须与文件名匹配,但它不匹配 - 更改为 PAGE}功能包括(文件名){返回 HtmlService.createHtmlOutputFromFile(filename).getContent();}/****** 床单 ****/功能用户点击(用户信息){var url = "https://docs.google.com/spreadsheets/your-sheet-ID";var ss = SpreadsheetApp.openByUrl(url);var ws = ss.getSheetByName("数据");ws.appendRow([userInfo.name, userInfo.email, userInfo.comment, new Date()]);}函数提交数据(表单){var 主题='新反馈';var body=Utilities.formatString('name: %s <br/>email: %s<br/>Comment: %s', form.name,form.email,form.comment);/*** 对于 HTML 电子邮件 **/var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");htmlTemplate.name = form.name;htmlTemplate.email = form.email;var htmlBody = htmlTemplate.evaluate().getContent();/*** 创建 PDF ***/var folderId = "你的文件夹 ID";//请设置文件夹 ID.//添加var blob = Utilities.newBlob(htmlBody, MimeType.HTML, form.name).getAs(MimeType.PDF);//添加 - 来自 html 电子邮件的 PDF - 用于从文档模板提供 PDF 的注释行var file = DriveApp.getFolderById(folderId).createFile(blob);//添加//****电子邮件****//var aliases = GmailApp.getAliases()Logger.log(别名);//返回你拥有的别名列表Logger.log(别名[0]);//返回位于别名数组位置 0 的别名GmailApp.sendEmail('your-email@email.email','新注册来自:','object', {'from': aliases[0],subject: subject, htmlBody: body, attachments: [blob]});//修改的return Utilities.formatString('name: %s <br/>Email: %s<br/>Comment: %s<br/>PDF: <a target="_blank" href="%s">查看您的 PDF 文件</a>', form.name,form.email,form.comment,file.getUrl());}

有关应用程序的更完整视图,请参阅我的另一篇文章:

<小时>

附件中的pdf文件

<小时>

现在我还有一个问题,我看不到 PDF 文件中的徽标"图像.如果你想在这方面帮助我,我可以.提前致谢.

解决方案

  • 您想使用 HTML 中的图像和 CSS 创建 PDF 文件.
  • 用于发送电子邮件的 HTML 已经完成.

我可以像上面一样理解你的目标.如果我的理解是正确的,这个答案怎么样?请将此视为几种可能的答案之一.

修改点:

  • 为了将图像放入PDF文件,需要将图像作为base64数据放入.参考
    • 在您的脚本中,cid:image 用于 PDF-page.html.在这种情况下,无法将图像放入 PDF 文件.

修改后的脚本:

当您的脚本被修改时,请进行如下修改.

Google Apps 脚本方面:

从:

/*** FOR HTML PDF **/var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");htmlTemplate.name = form.name;htmlTemplate.email = form.email;var pdf_html = htmlTemplate.evaluate().getContent();/*** 创建 PDF ***/var folderId = "你的文件夹 ID";//请设置文件夹IDvar blob = Utilities.newBlob(pdf_html, MimeType.HTML, form.name).getAs(MimeType.PDF);var file = DriveApp.getFolderById(folderId).createFile(blob);

到:

/*** FOR HTML PDF **/var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");htmlTemplate.name = form.name;htmlTemplate.email = form.email;var fileIdOfImageFile = "MY-IMAGE-ID";//新增:请设置图片文件的文件ID.var imageBlob = DriveApp.getFileById(fileIdOfImageFile).getBlob();//添加htmlTemplate.imageData = imageBlob.getContentType() + ';base64,' + Utilities.base64Encode(imageBlob.getBytes());//添加var pdf_html = htmlTemplate.evaluate().getContent();/*** 创建 PDF ***/var folderId = "你的文件夹 ID";var blob = Utilities.newBlob(pdf_html, MimeType.HTML, form.name).getAs(MimeType.PDF);var file = DriveApp.getFolderById(folderId).createFile(blob);

HTML 端:PDF-page.html

从:

<p class="image-logo"><img src='cid:image' width="150" height="56"></p>

到:

<p class="image-logo"><img src="data:<?= imageData ?>"width="150" height="56"/></p>

注意:

  • 您的 css-pdf.html 中的 text-pdf 似乎没有在 PDF-page.html 中使用.从您的底部图像,<p class="email-simply">PDF-page.html<p class="text-pdf">?
  • 顺便说一下,我不确定是否所有 CSS 样式都可以用于这种情况.对此我深表歉意.

参考:

I would like the HTML from a Google Apps Script form, to get two different styles, one for the body of the email and another for the PDF file.

Current code:

function doGet(request) {
  return HtmlService.createTemplateFromFile('index')
      .evaluate();//not all caps but it has to match the name of the file and it doesn't - Change to PAGE
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}


/****** SHEET ****/
function userClicked(userInfo){
    var url = "https://docs.google.com/spreadsheets/your-sheet-ID";
    var ss = SpreadsheetApp.openByUrl(url);
    var ws = ss.getSheetByName("Data");
    ws.appendRow([userInfo.name, userInfo.email, userInfo.comment, new Date()]);

}


function submitData(form) {
  var subject='New Feedback';
  var body=Utilities.formatString('name: %s <br />email: %s<br />Comment: %s', form.name,form.email,form.comment);
  
/*** FOR HTML EMAIL **/

    var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var htmlBody = htmlTemplate.evaluate().getContent();

/*** CREATE PDF ***/
  
  var folderId = "your-folder-ID"; // Please set the folder ID.  // Added
  var blob = Utilities.newBlob(htmlBody, MimeType.HTML, form.name).getAs(MimeType.PDF);  // Added - PDF from html email - coment line for serve PDF from document template 
  var file = DriveApp.getFolderById(folderId).createFile(blob);  // Added

//****email****//  
  var aliases = GmailApp.getAliases()
   Logger.log(aliases); //returns the list of aliases you own
   Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array

  GmailApp.sendEmail('your-email@email.email','New registration from:', 'object', {'from': aliases[0],subject: subject, htmlBody: body, attachments: [blob]});  // Modified
  
  
  return Utilities.formatString('name: %s <br />Email: %s<br />Comment: %s<br />PDF: <a target="_blank" href="%s">see your PDF file</a>', form.name,form.email,form.comment,file.getUrl());
}

For a more complete view of the application, refer to this other post of mine:

Google App Script setTimeout Function problem


In the to two sections following

it returns the Gmail basic style, through var = body

  • Showing the fields edited in the form:

    name: example name

    email: example email

    comment: example comment

var body=Utilities.formatString('name: %s <br />email: %s<br />Comment: %s', form.name,form.email,form.comment);

/****************************************************************************/

GmailApp.sendEmail('your-email@email.email','New registration from:', 'object', {'from': aliases[0],subject: subject, htmlBody: body, attachments: [blob]});

while in the section following

var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var htmlBody = htmlTemplate.evaluate().getContent();

/*** CREATE PDF ***/
  
  var folderId = "your-folder-ID"; // Please set the folder ID.  // Added

  var blob = Utilities.newBlob(htmlBody, MimeType.HTML, form.name).getAs(MimeType.PDF);

and this file PDF-page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top"> 
  </head>
  <body>
    <p>Dear <?= name ?> <?= email ?>,</p>
    <p>Thanks for your interest, we'll get back to you shortly</p>
    <p>Kind Regards,<br>Web App</p>

  </body>
</html>

it returns the page style from the page "PDF-page.html", through var = htmlBody

  • Showing the fields edited in the form:

    Dear example name example email

    Thanks for your interest, we'll get back to you shortly

    Kind Regards

    Web App

I know I edit the script like this:

from:

GmailApp.sendEmail('your-email@email.email','New registration from:', 'object', {'from': aliases[0],subject: subject, htmlBody: body, attachments: [blob]});

to:

GmailApp.sendEmail('your-email@email.email','New registration from:', 'object', {'from': aliases[0],subject: subject, htmlBody: HtmlBody, attachments: [blob]});

and enable the script to make the PDF file from the templates document as follows:

//  PDF FROM DOCUMENT TEMPLATE //  
  var templateDocumentId = "your-document-ID"; // Please set the file ID of the template Google Document
  var docId = DriveApp.getFileById(templateDocumentId).makeCopy("temp").getId();
  var doc = DocumentApp.openById(docId);
  doc.getBody().replaceText("{{name}}", form.name).replaceText("{{email}}", form.email).replaceText("{{comment}}", form.comment); // Modified
  doc.saveAndClose();
  var blob = doc.getBlob().setName(form.name);
  DriveApp.getFileById(docId).setTrashed(true);


//  var blob = Utilities.newBlob(htmlBody, MimeType.HTML, form.name).getAs(MimeType.PDF);

I get the result.

That is, I get separate control for building and formatting email / PDF

QUESTION:

So I wish I could control the style, formatting, and function separately

GmailApp.sendEmail

as an example: email-page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top"> 
  </head>
  <body>
    <p>Name: <?= name ?> <?= email ?>,</p>
    <p>Email. <?= email ?>,</p>
    <p>Comment<?= comment ?>,</p>
    <p>This is email page</p>


  </body>
</html>

that for

PDF-page.html (that I already have)

<!DOCTYPE html>
<html>
  <head>
    <base target="_top"> 
  </head>
  <body>
    <p>Dear <?= name ?> <?= email ?>,</p>
    <p>Thanks for your interest, we'll get back to you shortly</p>
    <p>Kind Regards,<br>Web App</p>

  </body>
</html>

I hope I have clearly explained my problem, please ask me for further clarification.

Thanks in advance for your attention.


Solution!

Well I found the solution to my problem and thought I'd share it below. In order to serve two different Html files, one to create the emal file in Html and the other the Html PDF file, I used 2 HtmlServices, rewritten my script as follows:

function doGet(request) {
  return HtmlService.createTemplateFromFile('index')
      .evaluate();//not all caps but it has to match the name of the file and it doesn't - Change to PAGE
}

function include(filename) {
  return HtmlService.createHtmlOutputFromFile(filename)
      .getContent();
}



function userClicked(userInfo){
    var url = "https://docs.google.com/spreadsheets/d/your-spreadsheet-ID";
    var ss = SpreadsheetApp.openByUrl(url);
    var ws = ss.getSheetByName("Data");
    ws.appendRow([userInfo.name, userInfo.email, userInfo.comment, new Date()]);

}


function submitData(form) {
  var subject='New Feedback';
  var body = Utilities.formatString('name: %s <br />Email: %s<br />Comment: %s', form.name,form.email,form.comment);

/*** FOR HTML PDF **/
  var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var pdf_html = htmlTemplate.evaluate().getContent();

/*** FOR HTML EMAIL **/ 
  //image logo in email html from my google drive acount
  var ImageBlob = DriveApp
                      .getFileById('your-image-ID') //change from your image-ID google drive acount
                      .getBlob()
                      .setName("ImageBlob");    
  var htmlTemplate = HtmlService.createTemplateFromFile("EMAIL-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var email_html = htmlTemplate.evaluate().getContent();


/*** CREATE PDF ***/

  var folderId = "your-folder-ID"; // Please set the folder ID
  var blob = Utilities.newBlob(pdf_html, MimeType.HTML, form.name).getAs(MimeType.PDF); 
  var file = DriveApp.getFolderById(folderId).createFile(blob);

//**** send email ****//  
  var aliases = GmailApp.getAliases()
   Logger.log(aliases); //returns the list of aliases you own
   Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array
   var userName = form.name;
  GmailApp.sendEmail('my-email@email.email','New Registration from:  ' +userName, '', {'from': aliases[0], htmlBody: email_html, inlineImages: {image: ImageBlob}, attachments: [blob]});


  return Utilities.formatString('name: %s <br />Email: %s<br />Comment: %s<br />PDF: <a target="_blank" href="%s">see your PDF file</a>', form.name,form.email,form.comment,file.getUrl());
}

to serve the two distinct Html pages I changed the script as follows:

FROM

/*** FOR HTML EMAIL **/

    var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var htmlBody = htmlTemplate.evaluate().getContent();

TO

/*** FOR HTML PDF **/
  var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var pdf_html = htmlTemplate.evaluate().getContent();

/*** FOR HTML EMAIL **/ 
  //image logo in email html from my google drive acount
  var ImageBlob = DriveApp
                      .getFileById('your-image-ID') //change from your image-ID google drive acount
                      .getBlob()
                      .setName("ImageBlob");    
  var htmlTemplate = HtmlService.createTemplateFromFile("EMAIL-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var email_html = htmlTemplate.evaluate().getContent();

FROM

//**** send email ****//  
  var aliases = GmailApp.getAliases()
   Logger.log(aliases); //returns the list of aliases you own
   Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array
   var userName = form.name;
GmailApp.sendEmail('your-email@email.email','New registration from:', 'object', {'from': aliases[0],subject: subject, htmlBody: body, attachments: [blob]});  // Modified

TO

//**** send email ****//  
  var aliases = GmailApp.getAliases()
   Logger.log(aliases); //returns the list of aliases you own
   Logger.log(aliases[0]); //returns the alias located at position 0 of the aliases array
   var userName = form.name;
  GmailApp.sendEmail('my-email@email.email','New Registration from:  ' +userName, '', {'from': aliases[0], htmlBody: email_html, inlineImages: {image: ImageBlob}, attachments: [blob]});

how to create the new HTML pages with their respective CSS style pages, here they are:

file EMAIL-Page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
<?!= include("css-email");?>
  </head>
  <body>
<p class="image-logo"><img src='cid:image' width="150" height="56"></p>
   <h2 class="title-email">EMAIL Template HTML,</h2>
    <p class="text-email">Dear <?= name ?> <?= email ?>,</p>
    <p class="text-email">Thanks for your interest, we'll get back to you shortly</p>
    <p class="text-email">Kind Regards,<br>Web App</p>

  </body>
</html>

file css-email-html

<style>

.title-email {
  text-left: center;
  margin-right: 550px;
  background-color: aliceblue;

}


.text-email {
  color: #3b9f04;
}

file PDF-page.html

<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
<?!= include("css-pdf");?>
  </head>
  <body>
  <p class="image-logo"><img src='cid:image' width="150" height="56"></p>
  <h2 class="title-pdf">PDF Template HTML,</h2>
    <p class="text-pdf">Name: <?= name ?></p>
    <p class="text-pdf">Email: <?= email ?>,</p>
<table>
  <tr>
    <th>Table not inclued in EMAIL Html file</th>
  </tr>
  <tr>
    <td>Field not inclued in EMAIL Html file</td>
  </tr>
</table>

  </body>
</html>

file css-pdf.html

<style>

.title-pdf {
  text-align: center;
  margin-right: 50px;
  background-color: antiquewhite;

}


.text-pdf {
  color: red;
}

table {
  border-collapse: collapse;
  padding: 5px
}

table, th, td {
  border: 1px solid black;
  padding: 8px;
}


</style>

and this is the result:

sending email


the attached pdf file


Now I still have a problem, I can't see the "logo" image in the PDF file. If you want to help me in this, I will be able to. Thanks in advance.

解决方案

  • You want to create a PDF file with the images and CSS from HTML.
  • HTML for sending email has already been done.

I could understand your goal like above. If my understanding is correct, how about this answer? Please think of this as just one of several possible answers.

Modification points:

  • In order to put the image to the PDF file, the image is required to be put as the base64 data. Ref
    • In your script, cid:image is used in PDF-page.html. In this case, the image cannot be put to the PDF file.

Modified script:

When your script is modified, please modify as follows.

Google Apps Script side:

From:

/*** FOR HTML PDF **/
  var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");
    htmlTemplate.name = form.name;
    htmlTemplate.email = form.email;
    var pdf_html = htmlTemplate.evaluate().getContent();

/*** CREATE PDF ***/

  var folderId = "your-folder-ID"; // Please set the folder ID
  var blob = Utilities.newBlob(pdf_html, MimeType.HTML, form.name).getAs(MimeType.PDF); 
  var file = DriveApp.getFolderById(folderId).createFile(blob);

To:

/*** FOR HTML PDF **/
var htmlTemplate = HtmlService.createTemplateFromFile("PDF-page.html");
htmlTemplate.name = form.name;
htmlTemplate.email = form.email;
var fileIdOfImageFile = "MY-IMAGE-ID";  // Added: Please set the file ID of the image file.
var imageBlob = DriveApp.getFileById(fileIdOfImageFile).getBlob();  // Added
htmlTemplate.imageData = imageBlob.getContentType() + ';base64,' + Utilities.base64Encode(imageBlob.getBytes());  // Added
var pdf_html = htmlTemplate.evaluate().getContent();

/*** CREATE PDF ***/
var folderId = "your-folder-ID";
var blob = Utilities.newBlob(pdf_html, MimeType.HTML, form.name).getAs(MimeType.PDF);
var file = DriveApp.getFolderById(folderId).createFile(blob);

HTML side: PDF-page.html

From:

<p class="image-logo"><img src='cid:image' width="150" height="56"></p>

To:

<p class="image-logo"><img src="data:<?= imageData ?>" width="150" height="56" /></p>

Note:

  • It seems that text-pdf in your css-pdf.html is not used in PDF-page.html. From your bottom image, <p class="email-simply"> in PDF-page.html is <p class="text-pdf">?
  • By the way, I'm not sure whether all CSS styles can be used for this situation. I apologize for this.

References:

这篇关于Google Apps Script - 将带有样式的 HTML 转换为 PDF 并附加到电子邮件 - 从 HTML 创建 PDF blob的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆