/**
* @module server/generatePresentation
*/
const getPngDimensions = require('./utils/getPngDimensions')
const elementToImageAsync = require('./utils/elementToImage')
const getThemeFunc = require('./themesManager').getThemeFunc
/**
* generates a document presentation
* @param documentMeta document meta object returned by {@link getDocumentAsync}
* @returns {Promise} pptx file encoded to base64 string
*/
module.exports = function generatePresentationAsync (documentMeta) {
return new Promise((resolve, reject) => {
// hack to fix a bug in pptxGenJs lib that prevents multiple presentations in node
delete require.cache[require.resolve('pptxgenjs')]
let pptx = require('pptxgenjs')
pptx.setLayout({name: 'NIELSEN_PAGE_SIZE', width: 10, height: 5.6})
let allPagesPromises = documentMeta.pages.map(
Page => handlePageAsync(pptx.addNewSlide(), documentMeta.data, Page)
)
Promise.all(allPagesPromises)
.then(
() => {
pptx.save('http', data => {
let pptxAsBase64 = Buffer.from(data, 'binary').toString('base64')
resolve(pptxAsBase64)
})
}
)
.catch(err => reject(err))
})
}
/**
* handle specific page creation
* @param pptx presentation instance
* @param data data required for the document
* @param page {Page} page class to create
* @returns {Promise.<T>} Promise would be resolved when page creation is completed
*/
function handlePageAsync (slide, data, Page) {
return new Promise((resolve, reject) => {
try {
let page = new Page(data)
let {pageOptions} = page
if (pageOptions.title) {
slide.addText(pageOptions.title, {
x: 0.7,
y: 0.6,
font_size: 30,
font_face: 'Arial (Headings)',
color: '000000',
bold: true
})
}
if (pageOptions.bodyText) {
slide.addText(pageOptions.bodyText, {
x: 0.7,
y: 1.1,
font_size: 18,
font_face: 'Arial (Headings)',
color: '000000'
})
}
if (!pageOptions.skipPageNumber) {
slide.slideNumber({x: '95%', y: '94%', fontFace: 'Courier', fontSize: 10, color: '000000'})
}
let themeFunc = getThemeFunc(pageOptions.theme)
themeFunc(slide)
if (page.getCustomContent) { page.getCustomContent(slide) }
if (page.getMainContent) {
let contentElement = page.getMainContent()
elementToImageAsync(contentElement)
.then(contentAsBase64Image => {
let dimensions = getPngDimensions(contentAsBase64Image)
slide.addImage({
x: 2,
y: 1.5,
w: dimensions.width,
h: dimensions.height,
data: `image/png;base64,${contentAsBase64Image}`
})
resolve()
})
} else {
resolve()
}
} catch (err) {
console.error(err)
reject(err)
}
})
}