PptxGenJS icon indicating copy to clipboard operation
PptxGenJS copied to clipboard

How to fill out placeholder on slide generated from autoPage

Open blrobin2 opened this issue 6 years ago • 4 comments

I have a master slide that contains a table and a placeholder, with the table set to autoPage when the table extends a certain number of rows. I am able to fill out the initial placeholder because the initial slide is available to me. But when addTable makes new slides, it's reference is created in the closure passed to getSlidesForTableRows's forEach and then thrown away

Ideally, addTable could return the references to these new pages so that any placeholders could be filled out, but I understand how that would break the fluid interface. Alternatively, if there were a way to access the slides array in gObjPptx, through a getSlideByPageNumber or whichever interface you feel properly encapsulates the details

Right now, my workaround is to set the text on the master directly, but this isn't ideal

Let me know if you need any clarification or whatever I can do to help

blrobin2 avatar Dec 09 '19 18:12 blrobin2

same

zhaoyuhang1033 avatar May 22 '20 02:05 zhaoyuhang1033

Same issue I am facing

jsvishal45 avatar Jun 20 '20 08:06 jsvishal45

Here is an alternative approach I've been using that allows me to utilize masters and have tables that overflow multiple slides. You'll need to adjust the magic numbers to your use case, but hopefully, it helps until a canonical solution comes along:

const ROW_HEIGHT = 0.25;
const ROWS_PER_PAGE = 12;
const SLIDE_HEIGHT = 7;
const TITLE_HEIGHT = 0.625;
const SUBTITLED_HEIGHT = 0.54;

function chunkTableData(data, rowsPerPage = ROWS_PER_PAGE) {
  const chunk_arr = [];
  for (let i = 0; i < data.length; i++) {
    const last = chunk_arr[chunk_arr.length - 1];
    if (! last || last.length === rowsPerPage) {
      chunk_arr.push([data[i]]);
    } else {
      last.push(data[i]);
    }
  }

  return chunk_arr;
}

function calculateInitialY(data, { rowsPerPage = ROWS_PER_PAGE, titleHeight = TITLE_HEIGHT, subtitleHeight = SUBTITLE_HEIGHT, slideHeight = SLIDE_HEIGHT }) {
  const tableHeight = data.length >= rowsPerPage ?
    (rowsPerPage + 1) * rowHeight :
    data.length * rowHeight;

  const availableHeight = (slideHeight - titleHeight - subtitleHeight - tableHeight) / 2;

  return (titleHeight + subtitleHeight + availableHeight);
}

pptx.defineSlideMaster({
  title: 'TABLE_SLIDE_MASTER',
  objects: [
    {
      placeholder: {
        text: ' ',
        options: {
          name: 'title',
          x: 1,
          y: 1
        }
      }
    }
  ]
});

// In case I need to access any of these slides later
const slides = [];

chunk_table_data(myData).forEach(dataSet => {
  const slide = pptx.addNewSlide(TABLE_SLIDE_MASTER');

  slide.addText('Special Title', {
    placeholder: 'title'
  });

  slide.addTable(dataSet, {
    rowH: ROW_HEIGHT,
    x: 1,
    y: calculateInitialY(dataSet),
    w: '85%'
  });

  slides.push(slide);
});

blrobin2 avatar Jun 22 '20 16:06 blrobin2

I solve it differently. After generating table we can access created slides by pptx.slides array.

const lastSlide = pptx.slides[pptx.slides.length - 1];
lastSlide. addText('Last update Today by Me', { placeholder: 'footer' })

So you can change placeholders on any filtered slides.

bizonKiller avatar Oct 20 '21 11:10 bizonKiller