I have a code that converts range from the spreadsheet into a image and send it as a repot. It works well but the quality of the image is low. The PDF I am getting is in really good quality but the inline image gets bad. Is there any way to improve quality of the image?
By now I have tried just to make fonts in the spreadsheet bigger. The fonts are now 36 size and the quality got better but it is still not the best so I would like to know if there is a way to solve the problem within the code.
async function convertPDFToPNG_(blob) {
// Convert PDF to PNG images.
const cdnjs = "https://cdn.jsdelivr.net/npm/pdf-lib/dist/pdf-lib.min.js";
eval(UrlFetchApp.fetch(cdnjs).getContentText()); // Load pdf-lib
const setTimeout = function (f, t) { // Overwrite setTimeout with Google Apps Script.
Utilities.sleep(t);
return f();
}
const data = new Uint8Array(blob.getBytes());
const pdfData = await PDFLib.PDFDocument.load(data);
const pageLength = pdfData.getPageCount();
console.log(`Total pages: ${pageLength}`);
const obj = { imageBlobs: [], fileIds: [] };
for (let i = 0; i < pageLength; i++) {
console.log(`Processing page: ${i + 1}`);
const pdfDoc = await PDFLib.PDFDocument.create();
const [page] = await pdfDoc.copyPages(pdfData, [i]);
pdfDoc.addPage(page);
const bytes = await pdfDoc.save();
const blob = Utilities.newBlob([...new Int8Array(bytes)], MimeType.PDF, `sample${i + 1}.pdf`);
const id = DriveApp.createFile(blob).getId();
Utilities.sleep(4000); // This is used for preparing the thumbnail of the created file.
const link = Drive.Files.get(id, { fields: "thumbnailLink" }).thumbnailLink;
if (!link) {
throw new Error("In this case, please increase the value of 3000 in Utilities.sleep(3000), and test it again.");
}
const imageBlob = UrlFetchApp.fetch(link.replace(/\=s\d*/, "=s1000")).getBlob().setName(`page${i + 1}.png`);
obj.imageBlobs.push(imageBlob);
obj.fileIds.push(id);
}
obj.fileIds.forEach(id => DriveApp.getFileById(id).setTrashed(true));
return obj.imageBlobs;
}
// Please run this function.
async function sendReport() {
// Retrieve Spreadsheet and Sheet objects.
const ss = SpreadsheetApp.openById("IDIDIDIDIDID");
const sheet = ss.getSheetByName("SheetName");
// Retrieve PDF blob.
const url = `https://docs.google.com/spreadsheets/d/${ss.getId()}/export?format=pdf&range=B2:S52&gid=${sheet.getSheetId()}&size=6&portrait=false&`;
const pdfBlob = UrlFetchApp.fetch(url, { headers: { authorization: "Bearer " + ScriptApp.getOAuthToken() } }).getBlob();
const SOURCE_TEMPLATE = pdfBlob;
const TARGET_FOLDER = "FOLDER-IDIDIDIDID";
// Use a method for converting all pages in a PDF file to PNG images.
const blob = pdfBlob
const imageBlobs = await convertPDFToPNG_(blob);
// As a sample, create PNG images as PNG files.
const folder = DriveApp.getFolderById(TARGET_FOLDER);
//imageBlobs.forEach(b => folder.createFile(b));
const reportDate = sheet.getRange(84, 6).getValue();
const month = reportDate.getMonth() + 1;
const day = reportDate.getDate();
const sender = sheet.getRange(84, 7).getValue();
// I modified the below script.
const htmlBody = `
<html>
<body>
<p>TEST</p>
<p>${month}${day}REPORT</p>
<img src="cid:inlineImage" />
<p>${sender}</p>
</body>
</html>
`;
const inlineImage = imageBlobs[0].setName("inlineImage");
const rangeTo = sheet.getRange(84, 4, ss.getLastRow(),1).getValues();
const emailTo = rangeTo.reduce(function(prev, next) {
return prev.concat(next);
});
const rangeCC = sheet.getRange(84, 5, ss.getLastRow(),1).getValues();
const emailCC = rangeCC.reduce(function(prev, next) {
return prev.concat(next);
});
MailApp.sendEmail({
to: emailTo.join(","),
cc: emailCC.join(",") || null,
bcc: "" || null,
subject: "REPORT "+month+"/"+day+,
//body: "TEST",
htmlBody: htmlBody,
inlineImages: { inlineImage: inlineImage },
attachments: [pdfBlob]
});
}