Interleaving different page formats and margins



  • Hi, i have a data structure like this:

    {
       parentPortraitMarginItems: [
          {
             text: 'Section 1 - Really long text that spans lots of pages so need the margins',
             landscapeNoMarginItems: [
                {
                   imageUrl: 'pic1.jpg'
                },
                {
                   imageUrl: 'pic2.jpg'
                }
             ]
          },
          {
             text: 'Section 2 - more rambling text',
             landscapeNoMarginItems: [
                {
                   imageUrl: 'pic3.jpg'
                },
                {
                   imageUrl: 'pic4.jpg'
                },
                {
                   imageUrl: 'pic5.jpg'
                }
             ]
          }
       ]
    }
    

    The number of parentPortraitMarginItem items is dynamic as well as the number of landscapeNoMarginItem children. What i want to happen is to:

    • for each parentPortraitMarginItem write out a portrait page with the margins that I already have on the template (sweet, easy as)

      • for each landscapeNoMarginItem in each parentPortraitMarginItem, write out a single landscape page with the image (full-paged cartographic map in this case) taking up a single full page.

    So this would look like (from my demo data):

    • portrait pages
    • landscape page
    • landscape page
    • portrait pages
    • landscape page
    • landscape page
    • landscape page

    Completing the full page images are fine, when in a standalone template that is simply appended or prepended to the body document and I can make that template landscape and 0 margins.

    What I need to happen is to interleave them all together and switch between portrait/margin pages and landscape/no-margin pages. Do i have to do some complex merge work, store page numbers and then somehow substitute the landscape images into placeholder portrait pages? Sorry but I can't see any examples of how to do this, or if it is even possible.

    I also have a ToC so I can't just have a bogus map page stuffing up my numbering if we insert it after render.



  • Sorry for the late response, still struggling with it?

    Yes, this is complicated. What you probably need to do is use pdf utils extension to dynamically concat pdf parts and implement this in a custom script.
    Something like this, just writing from the top of my head..

    const jsreport = require('jsreport-proxy')
    async function afterRender(req, res) {
      for (let item of req.data.parentPortraitMarginItems) {
        const itemRes = await reporter.render({ template: { name: 'templatefortext' } , data: item } })
        res.content = await jsreport.pdfUtils.append(res.content, itemRes.content)
        const imagesRes = await reporter.render({ template: { name: 'templateforimages' } , data: item } })
        res.content = await jsreport.pdfUtils.append(res.content, imagesRes.content)
      }
    }
    

    https://jsreport.net/learn/pdf-utils#usage-in-script



  • Thanks Jan, that poses problems for some other fancy stuff I am doing line report line numbering and resetting of that numbering between the part-reports (this is for environmental reports so has this random requirement which surprisingly works well considering we are working with html). What would be ideal functionality is a substitute function in pdf-utils where we could have some placeholders and go through and substitute sections / pages in place of existing sections / pages.



  • Okay, I've implemented with your approach which did most of the work for me. One thing that I need to be able to do is track some information between the various template renders. As I mentioned I am using line numbering using css counters. I need to be able to set the number that the css counter reached in the last section, to pass that onto the next section so the css counter knows to continue the counting rather than start at 1 again. I am able to simply obtain this number from a jquery count of a class. Once I get this number I don't know how to communicate this back to a jsreport variable that I would store in @root I presume.

    Can I somehow initially render the pdf as html then in afterRender() i get the html string, parse it with jquery, and do my class count to set my root variable, then pass on the html to a chrome-pdf renderer?



  • I might have found a solution using the Buffer.from() method here to parse the rendered html to a string

    https://forum.jsreport.net/topic/1368/html-report-with-chrome-image-report-as-child/4



  • How about this approach?
    https://playground.jsreport.net/w/jan_blaha/9vlmg6~7

    You use javascript and write at the end of the document some information you need.
    In a "hidden" form so user cant sees it in the output pdf.
    Then you parse the value in the script and delegate it to the next renders.



  • Genius Jan - that seems like a more reasonable approach than me parsing the whole rendered html and getting the count of a class later on back in afterRender() through jquery or regex. With my method, I would have then needed to re-render the html to a pdf


Log in to reply
 

Looks like your connection to jsreport forum was lost, please wait while we try to reconnect.