Adding attachment programatically in node, problem with size and date and buffer

Product: Apryse SDK

Product Version: Latest

Please give a brief summary of your issue:
No size and date when adding attachment to a PDF with the SDK

Hello
I’m trying to add attachments to a PDF with the SDK.
I managed to find a way using a temporarily file, heres the code

    const doc = await PDFNet.PDFDoc.createFromBuffer(mainFileBuffer);

    const fs = require('fs').promises;
    const path = require('path');
    const os = require('os');
    
    const attachmentPromises = attachmentKeys.map(async (key) => {
      try {
        const docObj = JSON.parse(req.body[key]);
        const encodedDocumentId = encodeURIComponent(docObj.documentId);
        const encodedFileName = encodeURIComponent(docObj.fileName);
        const url = `${env.basic.RENDER_URL}${encodedDocumentId}/${encodedFileName}`;
        console.log(`Downloading attachment from ${url}`);
    
        const response = await axios.get(url, { responseType: 'arraybuffer' });
        const attachmentBuffer = Buffer.from(response.data);
    
        // Create temp dir and file
        const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'pdf-attachments-'));
        const tempFilePath = path.join(tempDir, docObj.fileName);
        await fs.writeFile(tempFilePath, attachmentBuffer);
    
        // File spec creation
        const filespec = await PDFNet.FileSpec.create(doc, tempFilePath, true);
        filespec.setDesc(docObj.fileName);
        // adding to pdf
        obj = await filespec.getSDFObj();
        await obj.putText("F", docObj.fileName);
        await obj.putText("UF", docObj.fileName);
   
        await doc.addFileAttachment(docObj.fileName, filespec);

        console.log(`Attached ${docObj.fileName}`);
    
        // Supprimer le fichier temporaire
        await fs.unlink(tempFilePath);
        await fs.rmdir(tempDir);
    
      } catch (error) {
        console.error(`Error processing attachment ${key}:`, error);
        throw error;
      }
    });

    await Promise.all(attachmentPromises);

    // Save new pdf
    const outputBuffer = await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_linearized);
    console.log('PDF saved with attachments');

    // send pdf
    res.contentType('application/pdf').send(Buffer.from(outputBuffer));

Two problems :
1 - The date and size are unknown in the pdf, see screenshot :
image

I tried this but it doesnt work :
await obj.putNumber('Size', attachmentBuffer.byteLength); await obj.putString('CreationDate', new Date().toISOString()); await obj.putString('ModDate', new Date().toISOString());

2 - I would like to avoid having to store the document and work with the stream directly. I haven’t found a way to do it yet
I tried to follow this Attach file (based on byte[] / MemoryStream) into .pdf without roundtrip to temporary file? but createIndirectStream only works with filters and I cannot wrap my head around how it works. Any idea how to manage this?

Cheers

I may have an alternative for you. I see you are downloaded the file you are embedding and then using FileSpec.create to create the FileSpec. FileSpec has createURL which allows you to create a FileSpec directly from the URL:
PDFTron pdfnet-node Class: FileSpec

I also see that you are adding the attachments under the ‘F’ key under the embedded files, they belong under a 'Params" key as seen here.


We have an online version of our CosEdit tool that allows you to review PDF internals here: https://cosedit.com/.

Can you give this a try and let us know how it works for you?