Insert page-break after content for A4 page (example in practice.js)master
| @@ -0,0 +1,86 @@ | |||
| import $ from 'jquery' | |||
| const practice = () => { | |||
| const v = $('div.fade'); | |||
| // const v = $(':eq(0)'); // za root element | |||
| const va = $('div.fade').children().toArray(); // gledamo div-fade kao root | |||
| let i = 1, temp = 0; | |||
| const divRootElement = document.createElement('div'); | |||
| divRootElement.className = 'hello'; | |||
| const divElementPageBreak = document.createElement('div'); | |||
| divElementPageBreak.style.pageBreakBefore = "always"; | |||
| va.forEach(element => { | |||
| // 59.338582677165356 is sum of default top and bottom print margins | |||
| // 842 is height in pixels for A4 format | |||
| const razlika = element.clientHeight + temp - (i * 842 - 59.338582677165356); | |||
| if (razlika < 0) { | |||
| temp += element.clientHeight; | |||
| divRootElement.append(element); | |||
| } | |||
| else if (razlika === 0) { | |||
| i++; | |||
| temp = 0; | |||
| divRootElement.append(divElementPageBreak); | |||
| } | |||
| else { | |||
| if (element.hasChildNodes && element.childNodes.length === 1) { | |||
| const node = element.childNodes[0]; | |||
| if (node.hasChildNodes && node.childNodes.length === 1) { | |||
| const subNode = node.childNodes[0]; | |||
| if (subNode.hasChildNodes) { | |||
| const nodes = subNode.childNodes; | |||
| for (let j = 0; j < nodes.length; j++) { | |||
| const razlikaNodes = nodes[j].clientHeight + temp - (i * 842 - 59.338582677165356); | |||
| if (razlikaNodes < 0) { | |||
| temp += nodes[j].clientHeight; | |||
| } | |||
| else if (razlikaNodes === 0) { | |||
| i++; | |||
| temp = 0; | |||
| divRootElement.append(nodes[j]); | |||
| } | |||
| else { | |||
| if (nodes[j].hasChildNodes && nodes[j].childNodes.length > 1) { | |||
| const subNodes = nodes[j].childNodes; | |||
| for (let k = 0; k < subNodes.length; k++) { | |||
| const razlikaSubNodes = subNodes[k].clientHeight + temp - (i * 842 - 59.338582677165356); | |||
| if (razlikaSubNodes < 0) { | |||
| temp += subNodes[k].clientHeight; | |||
| divRootElement.append(subNodes[k]); | |||
| } | |||
| else { | |||
| i++; | |||
| temp = 0; | |||
| divRootElement.append(divElementPageBreak); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| else if (element.hasChildNodes && element.childNodes.length > 1) { | |||
| const nodes = element.childNodes; | |||
| for (let i = 0; i < nodes.length; i++) { | |||
| if (nodes[i].clientHeight + temp < (i * 842 - 59.338582677165356)) { | |||
| temp += nodes[i].clientHeight; | |||
| divElement.append(nodes[i]); | |||
| } | |||
| else { | |||
| i++; | |||
| temp = 0; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| $('div.fade').empty(); | |||
| $('div.fade').append(divRootElement); | |||
| // $('root').append(divRootElement); | |||
| } | |||
| export default practice; | |||
| @@ -9,7 +9,6 @@ | |||
| z-index: 9999; | |||
| left:0; | |||
| top: 0; | |||
| margin-bottom: 300px; | |||
| } | |||
| table { page-break-after:auto } | |||
| tr { page-break-inside:avoid; page-break-after:auto } | |||
| @@ -1,7 +1,35 @@ | |||
| @media print | |||
| { | |||
| table{ | |||
| display: block; | |||
| } | |||
| /* demo */ | |||
| .demo { | |||
| height: 100vh; | |||
| position: relative; | |||
| } | |||
| .demo::after { | |||
| content: attr(title); | |||
| position: absolute; | |||
| left: 0; | |||
| top: 0; | |||
| padding: .25em .5em; | |||
| background-color: rgba(255, 255, 255, .8); | |||
| } | |||
| .table-landscape | |||
| { | |||
| transform: rotate(90deg); | |||
| max-width: 100vh; | |||
| max-height: 100vw; | |||
| transform: translatex(calc(50vw - 50%)) translatey(calc(50vh - 50%)) rotate(90deg); | |||
| /* transform: rotate(90deg); */ | |||
| /* break-before: always; */ | |||
| /* page-break-before: always; */ | |||
| page-break-before: auto; | |||
| } | |||
| .demo { page-break-before:always } | |||
| /* .demo table { page-break-inside:avoid; page-break-after:auto } */ | |||
| .demo table { page-break-inside: always; } | |||
| } | |||
| @@ -0,0 +1,63 @@ | |||
| const url = ('https://localhost:7285/api/PDFGenerator/http%3A%2F%2Flocalhost%3A3000%2F%23%2Fdashboard'); | |||
| async function modifyPdf(existingPdfBytes) { | |||
| // const url = 'https://pdf-lib.js.org/assets/with_update_sections.pdf' | |||
| // const existingPdfBytes = await fetch(url).then(res => res.arrayBuffer()) | |||
| const pdfDoc = await PDFDocument.load(existingPdfBytes) | |||
| const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica) | |||
| const pages = pdfDoc.getPages() | |||
| const firstPage = pages[0] | |||
| const { width, height } = firstPage.getSize() | |||
| firstPage.drawText('This text was added with JavaScript!', { | |||
| x: 5, | |||
| y: height / 2 + 300, | |||
| size: 50, | |||
| font: helveticaFont, | |||
| color: rgb(0.95, 0.1, 0.1), | |||
| rotate: degrees(-45), | |||
| }) | |||
| const pdfBytes = await pdfDoc.save() | |||
| console.log(pdfBytes); | |||
| } | |||
| // modifyPdf(); | |||
| let headers = new Headers(); | |||
| headers.append('Content-Type', 'application/pdf'); | |||
| fetch(url, { | |||
| method: 'GET', | |||
| headers: headers | |||
| }) | |||
| .then(async res => ({ | |||
| filename: "donwload.pdf", | |||
| blob: await res.blob() | |||
| })) | |||
| .then(resObj => { | |||
| // It is necessary to create a new blob object with mime-type explicitly set for all browsers except Chrome, but it works for Chrome too. | |||
| const newBlob = new Blob([resObj.blob], { type: 'application/pdf' }); | |||
| const bytes = new Uint8Array(newBlob); | |||
| //console.log(bytes); | |||
| modifyPdf(bytes); | |||
| // MS Edge and IE don't allow using a blob object directly as link href, instead it is necessary to use msSaveOrOpenBlob | |||
| if (window.navigator && window.navigator.msSaveOrOpenBlob) { | |||
| window.navigator.msSaveOrOpenBlob(newBlob); | |||
| } else { | |||
| // For other browsers: create a link pointing to the ObjectURL containing the blob. | |||
| const objUrl = window.URL.createObjectURL(newBlob); | |||
| let link = document.createElement('a'); | |||
| link.href = objUrl; | |||
| link.download = resObj.filename; | |||
| link.click(); | |||
| // For Firefox it is necessary to delay revoking the ObjectURL. | |||
| setTimeout(() => { window.URL.revokeObjectURL(objUrl); }, 250); | |||
| } | |||
| }) | |||
| .catch((error) => { | |||
| console.log('DOWNLOAD ERROR', error); | |||
| }); | |||