vue-2-img
Version:
An easy way to convert HTML sections and charts to JPG, PNG or PDF files
150 lines (128 loc) • 4.54 kB
JavaScript
import $ from 'jquery'
import { jsPDF as JsPDF } from 'jsPDF'
import { canvasExport, svgToCanvas, imgTo64 } from './helpers'
import { getDate } from '../utils'
export const convertPdf = async (_options) => {
const _defaults = {
target: 'body',
pageTarget: '.pageTarget',
captureHiddenClass: 'vti__hidden',
captureShowClass: 'vti__show',
captureActiveClass: 'vti__active',
title: 'pdfCapture',
author: 'html-image-capture-service',
maxItems: 50,
fileNameSuffix: getDate(),
pageWrapper: '.row',
padding: 5,
devStyle: false,
pageHeight: null,
pageWidth: null,
pageUnits: 'pt',
returnAction: 'download'
}
// Merge defaults and options, without modifying defaults
const _settings = $.extend({}, _defaults, _options)
// var _targetObject = $(_settings.target)[0]
const heightList = []
const widthList = []
const pdfPageTarget = _settings.target + ' ' + _settings.pageTarget
let counterI = 0
const listOfPages = $(pdfPageTarget)
const nRendered = listOfPages.length
const fileName = _settings.title + _settings.fileNameSuffix + '.pdf'
let pageWidth = _settings.pageWidth
let pageHeight = _settings.pageHeight
let pageOrientation = 'p'
const padding = _settings.padding
_settings.returnAction = '' + _settings.returnAction.toLowerCase().trim()
// For cors bugs and rendering issues
// images are base64 encoded and replaced
// after image rendering
var srcList = []
const imgList = (src) => {
srcList.push(src)
}
// Page layout configuration
if (_settings.pageHeight === null || _settings.pageWidth === null) {
listOfPages.each(getPageSizes)
pageHeight = pageHeight + (padding * 2)
pageWidth = pageWidth + (padding * 2)
}
function getPageSizes () {
pageHeight = $(this).height() > pageHeight ? $(this).height() : pageHeight
heightList.push($(this).height())
pageWidth = $(this).width() > pageWidth ? $(this).width() : pageWidth
widthList.push($(this).width())
}
if (pageHeight < pageWidth) {
pageOrientation = 'l'
}
const pdfConfig = {
orientation: pageOrientation,
unit: _settings.pageUnits,
format: [pageWidth, pageHeight],
putOnlyUsedFonts: true,
floatPrecision: 16
}
const pdf = new JsPDF(pdfConfig).compatAPI()
pdf.setDocumentProperties({
title: _settings.title,
author: _settings.author
})
const setUp = () => {
$('body').addClass(_settings.captureActiveClass)
$('body').append('<div class="vti__progressCapture"><div class="vti__progressBar"></div></div>')
}
const cleanUp = () => {
const container = document.querySelector(_settings.target)
container.querySelectorAll('img').forEach((imageNode, index) => {
imageNode = srcList[index]
})
$(_settings.target).find('.screenShotTempCanvas').remove()
$(_settings.target).find('.tempHide').show().removeClass('tempHide')
$('body').removeClass(_settings.captureActiveClass)
$('.vti__progressCapture').remove
$('body').removeClass(_settings.captureActiveClass)
}
function assemblePdfPages (canvasObj) {
const maxW = (widthList[counterI] + padding)
const maxH = (heightList[counterI] + padding)
pdf.addImage(canvasObj.toDataURL('image/jpeg'), 'JPEG', (padding / 2), (padding / 2), (maxW), (maxH))
counterI++
$('.vti__progressBar').width(100 - ((counterI / nRendered) * 100) + '%')
if (counterI < nRendered) {
pdf.addPage([pageWidth, pageHeight], pageOrientation)
} else {
cleanUp()
}
}
// Start Routine
setUp()
svgToCanvas(_settings.target)
imgTo64(_settings.target, imgList)
console.log(listOfPages.length)
for (let index = 0; index < listOfPages.length; index++) {
const page = listOfPages[index]
await canvasExport(page, assemblePdfPages)
console.log('await')
}
cleanUp()
if (_settings.returnAction === 'download') {
pdf.save(fileName)
return pdf.output('datauristring')
} else if (_settings.returnAction === 'base64') {
return pdf.output('datauristring')
} else if (_settings.returnAction === 'newwindow') {
return pdf.output('dataurlnewwindow')
} else if (_settings.returnAction === 'blob') {
return pdf.output('blob')
} else if (_settings.returnAction === 'clipboard') {
const blobObj = pdf.output('blob')
// eslint-disable-next-line no-undef
const item = new ClipboardItem({ 'image/png': blobObj })
navigator.clipboard.write([item])
return blobObj
}
return pdf.output('dataurlstring')
}