[javascript] Javascript를 사용하여 div의 HTML에서 pdf 생성

다음 HTML 코드가 있습니다.

<!DOCTYPE html>
<html>
    <body>
        <p>don't print this to pdf</p>
        <div id="pdf">
            <p><font size="3" color="red">print this to pdf</font></p>
        </div>
    </body>
</html>

내가하고 싶은 것은 ID가 “pdf”인 div에있는 모든 것을 pdf로 인쇄하는 것입니다. JavaScript를 사용하여 수행해야합니다. “pdf”문서는 “foobar.pdf”라는 파일 이름으로 자동 다운로드되어야합니다.

이 작업을 수행하기 위해 jspdf를 사용했지만 문자열 기능 만 허용하는 “text”기능 만 있습니다. 텍스트가 아닌 jspdf에 HTML을 제출하고 싶습니다.



답변

jsPDF는 플러그인을 사용할 수 있습니다. HTML을 인쇄하려면 특정 플러그인을 포함해야하므로 다음을 수행해야합니다.

  1. https://github.com/MrRio/jsPDF로 이동 하여 최신 버전을 다운로드하십시오.
  2. 프로젝트에 다음 스크립트를 포함하십시오.
    • jspdf.js
    • jspdf.plugin.from_html.js
    • jspdf.plugin.split_text_to_size.js
    • jspdf.plugin.standard_fonts_metrics.js

특정 요소를 무시하려면 jsPDF의 특수 요소 처리기에서이를 무시할 수있는 ID로 표시해야합니다. 따라서 HTML은 다음과 같아야합니다.

<!DOCTYPE html>
<html>
  <body>
    <p id="ignorePDF">don't print this to pdf</p>
    <div>
      <p><font size="3" color="red">print this to pdf</font></p>
    </div>
  </body>
</html>

그런 다음 다음 JavaScript 코드를 사용하여 작성된 PDF를 팝업으로여십시오.

var doc = new jsPDF();
var elementHandler = {
  '#ignorePDF': function (element, renderer) {
    return true;
  }
};
var source = window.document.getElementsByTagName("body")[0];
doc.fromHTML(
    source,
    15,
    15,
    {
      'width': 180,'elementHandlers': elementHandler
    });

doc.output("dataurlnewwindow");

나를 위해 이것은 ‘pdf로 인쇄’행만 포함하는 멋지고 깔끔한 PDF를 만들었습니다.

특수 요소 핸들러는 현재 버전의 ID 만 처리하며 GitHub Issue에 명시되어 있습니다 . 상태는 다음과 같습니다.

노드 트리의 모든 요소에 대해 일치하기 때문에 가능한 한 빨리 만들려고했습니다. 이 경우 “요소 ID 만 일치 함”을 의미합니다. 요소 ID는 여전히 jQuery 스타일 “#id”로 수행되지만 모든 jQuery 선택기가 지원되는 것은 아닙니다.

따라서 ‘#ignorePDF’를 ‘.ignorePDF’와 같은 클래스 선택기로 바꾸면 나에게 도움이되지 않습니다. 대신 각 요소마다 동일한 핸들러를 추가해야합니다.

var elementHandler = {
  '#ignoreElement': function (element, renderer) {
    return true;
  },
  '#anotherIdToBeIgnored': function (element, renderer) {
    return true;
  }
};

에서 ‘a’또는 ‘li’와 같은 태그를 선택할 수 있다고 언급되어 있습니다. 그래도 대부분의 유스 케이스에는 제한이 없을 수 있습니다.

특수 요소 처리기를 지원합니다. ID 또는 노드 이름에 대해 jQuery 스타일 ID 선택기로 등록하십시오. ( “#iAmID”, “div”, “span”등) 현재 다른 유형의 선택기 (클래스, 컴파운드)는 지원하지 않습니다.

추가해야 할 중요한 사항 중 하나는 모든 스타일 정보 (CSS)를 잃어버린다는 것입니다. 운 좋게도 jsPDF는 h1, h2, h3 등을 멋지게 형식화 할 수있어 내 목적에 충분했습니다. 또한 텍스트 노드 내에서만 텍스트를 인쇄하므로 텍스트 영역 등의 값을 인쇄하지 않습니다. 예:

<body>
  <ul>
    <!-- This is printed as the element contains a textnode -->
    <li>Print me!</li>
  </ul>
  <div>
    <!-- This is not printed because jsPDF doesn't deal with the value attribute -->
    <input type="textarea" value="Please print me, too!">
  </div>
</body>


답변

이것은 간단한 해결책입니다. 자바 스크립트 인쇄 개념을 사용하고 이것을 pdf로 간단히 저장할 수 있습니다.

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
    <script type="text/javascript">
        $("#btnPrint").live("click", function () {
            var divContents = $("#dvContainer").html();
            var printWindow = window.open('', '', 'height=400,width=800');
            printWindow.document.write('<html><head><title>DIV Contents</title>');
            printWindow.document.write('</head><body >');
            printWindow.document.write(divContents);
            printWindow.document.write('</body></html>');
            printWindow.document.close();
            printWindow.print();
        });
    </script>
</head>
<body>
    <form id="form1">
    <div id="dvContainer">
        This content needs to be printed.
    </div>
    <input type="button" value="Print Div Contents" id="btnPrint" />
    </form>
</body>
</html>


답변

autoPrint ()를 사용하고 다음과 같이 출력을 ‘dataurlnewwindow’로 설정할 수 있습니다.

function printPDF() {
    var printDoc = new jsPDF();
    printDoc.fromHTML($('#pdf').get(0), 10, 10, {'width': 180});
    printDoc.autoPrint();
    printDoc.output("dataurlnewwindow"); // this opens a new popup,  after this the PDF opens the print window view but there are browser inconsistencies with how this is handled
}


답변

특정 페이지의 PDF를 다운로드 해야하는 경우 다음과 같은 버튼을 추가하십시오.

<h4 onclick="window.print();"> Print </h4>

div뿐만 아니라 모든 페이지를 인쇄하려면 window.print () 사용


답변

언급 한대로 jsPDFhtml2canvas 를 사용해야합니다 . 또한 pdf를 여러 페이지 ( 소스 ) 로 자동 분할하는 jsPDF 문제 내부의 기능을 발견했습니다.

function makePDF() {

    var quotes = document.getElementById('container-fluid');

    html2canvas(quotes, {
        onrendered: function(canvas) {

        //! MAKE YOUR PDF
        var pdf = new jsPDF('p', 'pt', 'letter');

        for (var i = 0; i <= quotes.clientHeight/980; i++) {
            //! This is all just html2canvas stuff
            var srcImg  = canvas;
            var sX      = 0;
            var sY      = 980*i; // start 980 pixels down for every new page
            var sWidth  = 900;
            var sHeight = 980;
            var dX      = 0;
            var dY      = 0;
            var dWidth  = 900;
            var dHeight = 980;

            window.onePageCanvas = document.createElement("canvas");
            onePageCanvas.setAttribute('width', 900);
            onePageCanvas.setAttribute('height', 980);
            var ctx = onePageCanvas.getContext('2d');
            // details on this usage of this function: 
            // https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Using_images#Slicing
            ctx.drawImage(srcImg,sX,sY,sWidth,sHeight,dX,dY,dWidth,dHeight);

            // document.body.appendChild(canvas);
            var canvasDataURL = onePageCanvas.toDataURL("image/png", 1.0);

            var width         = onePageCanvas.width;
            var height        = onePageCanvas.clientHeight;

            //! If we're on anything other than the first page,
            // add another page
            if (i > 0) {
                pdf.addPage(612, 791); //8.5" x 11" in pts (in*72)
            }
            //! now we declare that we're working on that page
            pdf.setPage(i+1);
            //! now we add content to that page!
            pdf.addImage(canvasDataURL, 'PNG', 20, 40, (width*.62), (height*.62));

        }
        //! after the for loop is finished running, we save the pdf.
        pdf.save('test.pdf');
    }
  });
}


답변

한 가지 방법은 window.print () 함수를 사용하는 것입니다. 어떤 라이브러리가 필요하지 않습니다

찬성

1. 외부 라이브러리가 필요하지 않습니다.

2. 우리는 본문의 선택된 부분 만 인쇄 할 수 있습니다.

3. CSS 충돌 및 JS 문제가 없습니다.

4. 핵심 html / js 기능

— 간단히 아래 코드를 추가

CSS

@media print {
        body * {
            visibility: hidden; // part to hide at the time of print
            -webkit-print-color-adjust: exact !important; // not necessary use         
               if colors not visible
        }

        #printBtn {
            visibility: hidden !important; // To hide 
        }

        #page-wrapper * {
            visibility: visible; // Print only required part
            text-align: left;
            -webkit-print-color-adjust: exact !important;
        }
    }

JS 코드 -BTN 클릭시 다음 함수 호출

$scope.printWindow = function () {
  window.print()
}

참고 : 모든 CSS 객체에서! important를 사용하십시오.

예 –

.legend  {
  background: #9DD2E2 !important;
}


답변

CSS 렌더링에 jspdfhtml2canvas 를 사용 하고 특정 코드의 내용을 내 코드로 내 보냅니다.

$(document).ready(function () {
    let btn=$('#c-oreder-preview');
    btn.text('download');
    btn.on('click',()=> {

        $('#c-invoice').modal('show');
        setTimeout(function () {
            html2canvas(document.querySelector("#c-print")).then(canvas => {
                //$("#previewBeforeDownload").html(canvas);
                var imgData = canvas.toDataURL("image/jpeg",1);
                var pdf = new jsPDF("p", "mm", "a4");
                var pageWidth = pdf.internal.pageSize.getWidth();
                var pageHeight = pdf.internal.pageSize.getHeight();
                var imageWidth = canvas.width;
                var imageHeight = canvas.height;

                var ratio = imageWidth/imageHeight >= pageWidth/pageHeight ? pageWidth/imageWidth : pageHeight/imageHeight;
                //pdf = new jsPDF(this.state.orientation, undefined, format);
                pdf.addImage(imgData, 'JPEG', 0, 0, imageWidth * ratio, imageHeight * ratio);
                pdf.save("invoice.pdf");
                //$("#previewBeforeDownload").hide();
                $('#c-invoice').modal('hide');
            });
        },500);

        });
});