PDF generation and saving to AWS bucket not working

Hi,

I'm using retool now for two months and really love it!

I want to create price labels in retool and save that label as a pdf in aws bucket.
Saving images and so on to aws works, but i'm stuck on saving the generated pdf.

Goal= to generate a pdf file and to save the pdf file to aws

I have a javascript query that is generating the blob file of the pdf

// Create a canvas element for the barcode
var canvas = document.createElement('canvas');
var barcodeValue = 'A-'; // Replace with your barcode value
JsBarcode(canvas, barcodeValue, { format: "CODE128", displayValue: false });
var barcodeDataUrl = canvas.toDataURL("image/png");

// Create a new jsPDF document
var doc = new jspdf.jsPDF({
  orientation: 'l', // Landscape
  unit: 'mm',
  format: [40, 60] // 40mm height and 60mm width
});

// Set font to bold for the product name (replace 'productName' with actual product name)
var productName = 'Product Name'; // Example product name
doc.setFont("helvetica", "normal");
doc.setFontSize(15);
doc.text(productName, 2, 6);

// Measure text width to underline and add underline for the product name
var textWidth = doc.getTextWidth(productName);
doc.setLineWidth(0.5); // Line width for underline
doc.line(2, 7, 2 + textWidth, 7); // Drawing the underline

// Reset font to normal for other texts
doc.setFont("helvetica", "normal");

// Add Unit and Volume (replace 'unit' and 'volume' with actual values)
var unit = 'Unit'; // Example unit
var volume = 'Volume'; // Example volume
doc.setFontSize(12);
doc.text(unit + ' ' + volume, 2, 14);

// Add Barcode image to PDF
doc.addImage(barcodeDataUrl, 'PNG', 2, 20, 30, 8); // Adjust size and position as needed

// Add Supplier (replace 'supplierName' with actual supplier name)
var supplierName = 'Supplier'; // Example supplier name
doc.setFontSize(12);
doc.text(supplierName, 2, 34);

// Save the PDF
// Convert the PDF directly to a Blob (no Promise involved)
var blob = doc.output('blob');
console.log("Blob size:", blob.size);

// Define the filename
var filename = 'price_label.pdf';

// Create a File from the Blob
var file = new File([blob], filename, { type: 'application/pdf' });
console.log("File object:", file);
console.log("File name:", file.name);
console.log("File size:", file.size);
console.log("File type:", file.type);


console.log("Triggering upload_to_s3 script");

// Use the Retool AWS S3 upload feature
upload_to_s3.trigger({
  additionalScope: {
    file: file, // The File object you created
    filename: filename // The filename for the PDF
  },  

  onSuccess: function(data) {
    // Handle success - you can add your own logic here
    console.log("File uploaded successfully.");
  },
  onFailure: function(error) {
    // Handle failure - you can add your own logic here
    console.log("Error uploading file:", error);
  }
});

And i have a aws upload data GUI:

The console log of the javascript query confirms that the blob has a certain size, but the object is empty


Blob size:

1. 68375

File object:

1. {}

File name:price_label.pdf

File size:

1. 68375

File type:application/pdf

File object:

1. {}

Filename:price_label.pdf

Triggering upload_to_s3 script

Can someone help me solve this issue?

Hi @corneel_martens

Are you using a custom component to do that? (since I don't know how to do in alternative ways because you're using jsPDF)
In this case the payload of a File object cannot be passed without proper conversion, such as base64.

Best

Hi,

No, i'm not using a custom component.
Saving the pdf file to my computer works, but not to AWS.
So I should convert the pdf file to base64? But AWS is not accepting that format I experienced

You are right.

I've tested quickly your script and it looks like the upload_to_s3 query handles correctly the additionalScope params, I'm passing type and name from the first query.
The data field instead is not populated properly.
Also, it seems that the upload_to_s3 query returns a signedUrl that is usually used to upload the file with a further fetch.

I'm not sure how to workaround this issue without using the built-in S3 button component.

Hi,

thx for the effort of helping me!
In retool mobile there is no custom s3 button component, only in desktopversion.
It's a bit strange that retool is not supporting an easy way to generate and save pdf files.

I tried converting it to base64, then upload it to retool storage, but that is not working neither. It's giving corrupt pdf files.

Finaly I've found the issue.
Apparentely I didn't set a CORS in AWS, that was the reason it couldn't be fetched.

Then i had to upload the pure base64 date, without the Data URL prefix

1 Like