typescriptspfx-extension

Why is this creating a blank page?


I'm in the midst of trying to create an spfx web part that will merge selected documents into one. I am using the pdf-lib and @pnp/sp libraries. Here is my code:

const mergedFile = await PDFDocument.create();

// Loop through each selected item
this.context.listView.selectedRows.forEach(async (row: RowAccessor) => {
   // Get the file array buffer
   const file = sp.web.getFileByServerRelativePath(row.getValueByName('FileRef'));
   const fileBytes: ArrayBuffer = await file.getBuffer();
   const fileToMerge = await PDFDocument.load(fileBytes);

   const copyPages = await mergedFile.copyPages(fileToMerge, fileToMerge.getPageIndices());
   copyPages.forEach((page) => {
     mergedFile.addPage(page);
   });
});


const savedMergedFile = await Promise.resolve(mergedFile.save());
const newFileAsBlob = new Blob([savedMergedFile]);
const newFile = await sp.web.getFolderByServerRelativePath(path).files.addChunked(encodeURI("newFile.pdf"), newFileAsBlob,  undefined, true);

I used this and this as reference to create my web part, but the problem is, when I run and test it, the resulting document is just a blank page. Could anyone shed light on why this is the result?


Solution

  • Ok, it took me a while, but I figured out that it wasn't actually the 'typecasting' to blob that was the issue. The issue was that the for loop was executing asynchronously from the rest of the function. This meant that the mergedFile.save() would execute before the for loop was able to copy the pages to the PDFDocument. Here is the answer in case anyone might ever need it.

    const savedMergedFile = await this.createByteArray();
    const fileAsBlob = new Blob([savedMergedFile])
    const newFile = await sp.web.getFolderByServerRelativePath(path).files.addChunked(encodeURI(fileName), fileAsBlob, undefined, true)
    
    private async createByteArray(): Promise<Uint8Array> {
        const mergedFile = await PDFDocument.create();
    
        for(const row of this.context.listView.selectedRows){
          const file = sp.web.getFileByServerRelativePath(row.getValueByName('FileRef'));
          const fileBytes: ArrayBuffer = await file.getBuffer();
          const fileToMerge = await PDFDocument.load(fileBytes);
    
          const copyPages = await mergedFile.copyPages(fileToMerge, fileToMerge.getPageIndices());
          copyPages.forEach((page) => {
            mergedFile.addPage(page);
          });
        }
        return mergedFile.save();
    }