RE: How to combine multiple pdf’s into a single pdf file?

I have written a map reduce script to generate and combine multiple pdf’s into a single pdf. My script is generating multiple pdfs properly, but it shows only last pdf in a combined pdf. please help!

 

/**
 * @NApiVersion 2.0
 * @NScriptType MapReduceScript
 */
define([‘N/search’, ‘N/record’, ‘N/runtime’,’N/render’,’N/file’,’N/url’,’N/xml’],
function(search, record, runtime,render,file,url,xml)
{
  function getInputData() {
      try{
        var soIdArray=[];
          // var waveId = runtime.getCurrentScript().getParameter({name: ‘custscriptstandard_wave_id’});
          // log.debug(“waveId”,waveId);
         var waveRecord = record.load({
          type:record.Type.WAVE,
          id: 131830,
          isDynamic: true,
      });
      log.debug(“waveRecord”,waveRecord);
      var totalLines = waveRecord.getLineCount({
          sublistId: ‘waveorders’
      });
      log.debug(“totalLines”,totalLines);
      for(var s=0;s<totalLines;s++)
      {
          var soId= waveRecord.getSublistValue({
              sublistId: ‘waveorders’,
              fieldId: ‘ordernumberid’,
              line: s
          });
          log.debug(“soId–> “,soId);
          soIdArray.push(soId);
        }
        log.debug(“soIdArray”,soIdArray);
           return soIdArray;
            }
      catch(e)
      {
          log.debug(“error in getinput”,e);
      }
  }
 var n=0;
 var pdfFileIds = [];
 function map(context) {
    try {
      log.debug(“map stage executing”);
      log.debug(“context”,context);
      var searchResult = JSON.parse(context.value);
      log.debug(“searchResult”, searchResult);
      var result = {
        internalid: searchResult,
        };
      log.debug(“result”, result);
      var fileId=renderBolPdf (result)
      n += 1;
      // Emit the key-value pair to trigger the reduce function
      context.write({
        key: searchResult, // Use the file ID as the key
        value: fileId,
      });
    } catch (er) {
      log.debug(“error in map”, er);
    }
  }
  function reduce(context) {
    try {
      log.debug(“Reduce stage executing”,context);
       log.debug(‘context.values’,context.values)
       log.debug(‘context.key’,context.key)
       var reduceObj=context.values
     var pdfFile= renderSet (reduceObj,context.key);
     log.debug(‘pdfFile’,pdfFile)
    } catch (er) {
      log.debug(“error in reduce”, er);
    }
  }
  function renderBolPdf (jsonData) {
   log.debug(“json data2–>”,jsonData);
    try {
      var renderer = render.create()
      renderer.setTemplateByScriptId(‘CUSTTMPL_MAP_REDUCE_TEST’);
    log.debug(‘294’,jsonData);
      renderer.addCustomDataSource({
        format: render.DataSource.OBJECT,
        alias: ‘JSON’,
        data: { record: jsonData }
      })
      renderer.addRecord({
        templateName: ‘record’,
        record: record.load({
          type: ‘salesorder’,
          id: jsonData.internalid
        })
      });
     log.debug(‘299′,’299’);
      var bol = renderer.renderAsPdf()
      log.debug(‘302′,’302’);
      log.debug(‘jsonData.internalid–>’,jsonData.internalid);
      bol.folder = 1797
      bol.name = ‘PDF’+jsonData.internalid;
      log.debug(“bol.name”,bol.name);
      bol.isOnline = true
     log.debug(“bol”, bol);
      var fileid = bol.save()
      log.debug(“fileid single”,fileid);
      return fileid
    } catch (error) {
      log.debug(‘error in renderBolPdf’, error)
    }
  }
  function renderSet (opts,jsonData) {
    try {
      //10 x files + 30 + 10(search) –> 95 files combine per custom record
      log.debug(‘inside RenderSet’,opts)
      log.debug(‘inside i_IFInternalId’,jsonData)
      var tpl = [‘<?xml version=”1.0″?>’, ‘<pdfset>’]
      var output = url.resolveDomain({
        hostType: url.HostType.APPLICATION
      })
      opts.forEach(function (id, idx) {
        id = parseInt(id)
        const partFile = file.load({ id: id }) //10 per file
        var pdf_fileURL = xml.escape({ xmlText: partFile.url })
        tpl.push(“<pdf src='” + pdf_fileURL + “‘/>”)
      })
      tpl.push(‘</pdfset>’)
      pdfFinal = render.xmlToPdf({
        xmlString: tpl.join(‘\n’)
      })
      pdfFinal.name = ‘Traveler_PRINT’ + ‘_’+ ‘.pdf’
      pdfFinal.isOnline = true
      pdfFinal.folder = 1797
      var fileId = pdfFinal.save() //20
      log.debug(“fileId”,fileId)
  //     record.submitFields({
  //      type:’itemfulfillment’,
  //      id:parseInt(i_IFInternalId) ,
  //      values: {
  //         custbody_carton_pdf_url:fileId//fileObj.url
  //      }
  //  })
    log.debug(‘fileId renderset’, fileId)
      return fileId
      log.debug(‘fileId renderset’, fileId)
       //10
       pdfFinal = file.load(fileId)
      output = ‘https://’ + output + pdfFinal.url
      return output
    } catch (error) {
      log.debug({
        title: ‘error in renderSet’,
        details: error
      })
    }
  }
       return {
        getInputData: getInputData,
        map: map,
        reduce: reduce
        //summarize: summarize
    };
});
Maira S Beginner Asked on November 6, 2023 in SuiteScript.
Add Comment
5 Answers

Hi,

You want the key here to be something that connects the files together:

context.write({
  key: searchResult, // Use the file ID as the key
  value: fileId,
});

Unless the values are the same, they will end up in separate instances of reduce.

Thanks,

Chris

Intermediate Answered on November 7, 2023.
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.