добавить несколько страниц в формате PDF, используя html2canvas и jspdf - PullRequest
1 голос
/ 17 апреля 2019

мой код ниже работает нормально, но я хочу, чтобы все страницы в одном PDF. У меня есть 2 объекта JSON. Когда я нажимаю кнопку «Открыть» на вкладке «2» с другим результатом, я хочу, чтобы она открывалась на одной вкладке в формате PDF и добавляла несколько записей на нескольких страницах в одном файле PDF. Вы можете помочь мне в этом.

for (let i = 0;i  <= this.reportVGWM.length; i++){
          html2canvas(document.querySelector('#myTable' + i)).then(canvas => {
            var imgWidth = 180;
            var pageHeight = 280;
            var imgHeight = canvas.height * imgWidth / canvas.width;
            var heightLeft = imgHeight;
            var imgData = canvas.toDataURL("image/jpeg");
            var heightLeft = imgHeight;
            var pdf = new jsPDF('p', 'mm', 'a4');
            var position = 20;
            var font: { 'padding-bottom: 40%; padding-top:30%' };
            pdf.addImage(imgData, 'PNG', 10, position, imgWidth, imgHeight);
            pdf.addPage();                 
            pdf.output('dataurlnewwindow');

          });
        }
        }, 1);
      });

1 Ответ

1 голос
/ 17 апреля 2019

вы можете использовать pdfMake, еще одну удивительную библиотеку js. Я получил эту информацию в этом вопросе: Создание PDF-файлов с помощью JavaScript

printDocument() {
  const divs = document.getElementsByClassName('example');
  const newList = [].slice.call(inputs);
  var contentArray = []
  var docDefinition = {
            pageSize: {width: 800, height: 1173},
            content: [
                {
                    text: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Confectum ponit legam, perferendis nomine miserum, animi. Moveat nesciunt triari naturam.'
                }
            ]

        }

  Promise.map(newList, async (element, index) => {
            let canvas = await html2canvas(element);
            const imgData = await canvas.toDataURL('image/png');
            // console.log("imgData URL => ", imgData)
            // margin horizontal -40 = removing white spaces
            return contentArray[`${index}`] = [{ image: imgData, width: canvas.width, height: canvas.height, margin: [-40, 0] }, {
                text: ` ${index} - Lorem ipsum dolor sit amet, consectetur adipisicing elit. Confectum ponit legam, perferendis nomine miserum, animi.`
}];

        }).then(
            () => ( docDefinition.content.push(contentArray))
        ).then(
            () => {
                console.log("... starting download ...")
                pdfMake.createPdf(docDefinition).download('examplePdf.pdf')
            } 
        )
}

// In your react's component constructor ... 

constructor(props) {
        super(props);
        this.printDocument = this.printDocument.bind(this)
}

// the imports below ...
import Promise from 'bluebird';
import html2canvas from 'html2canvas';
import pdfMake from 'pdfmake/build/pdfmake.js';
import pdfFonts from "pdfmake/build/vfs_fonts.js";
pdfMake.vfs = pdfFonts.pdfMake.vfs;

// i'm using these middlewares
import promise from 'redux-promise'
import multi from 'redux-multi'
import thunk from 'redux-thunk'





<div>
  The approach here is: a div it's not a page. Because if the image generated by the canvas element it's bigger than the page vertical size, we'll need to control the pagination by ourselves. So, we broke our content in small elements to the pdf generator handle the pagination to us. This way we garantee that the pagination will occurs without cuts. 
  <div className="example" style={{ backgroundColor: '#ffffff', maxWidth: '800px', maxHeight: '1173px', borderStyle: 'groove', borderColor: 'red', margin: '0px' }} >

  // any content or component here, we need maxHeight to be sure that the div's height size it's not bigger than the your PDF doc's height dimension, else your div may never be rendered inside it.

  </div>
  <div className="example" style={{ backgroundColor: '#ffffff', maxWidth: '800px', maxHeight: '1173px', borderStyle: 'groove', borderColor: 'red', margin: '0px' }} >

  // any content or component here, we need maxHeight to be sure that the div's height size it's not bigger than the your PDF doc's height dimension, else your div may never be rendered inside it.

  </div>
  <div className="example" style={{ backgroundColor: '#ffffff', maxWidth: '800px', maxHeight: '1173px', borderStyle: 'groove', borderColor: 'red', margin: '0px' }} >

  // any content or component here, we need maxHeight to be sure that the div's height size it's not bigger than the your PDF doc's height dimension, else your div may never be rendered inside it.

  </div>

</div>

<div>
 <button onClick={this.printDocument}> print using PDFMake  </button>
</div>

Используя Promise.map by bluebird с ресурсами async / await, мы можем гарантировать, что мы дождемся окончания генерации всех изображений с холста. Этот процесс может занять некоторое время в зависимости от вашего изображения размер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...