JavaScript 또는 jquery를 사용하여 HTML 페이지를 PDF로 저장할 수 있습니까?


84

JavaScript 또는 jquery를 사용하여 HTML 페이지를 PDF로 저장할 수 있습니까?

상세히:

테이블이 포함 된 HTML 페이지를 생성했습니다. 'PDF로 저장'버튼이 하나 있습니다. 사용자가 해당 버튼을 클릭하면 해당 HTML 페이지가 PDF 파일로 변환되어야합니다.

JavaScript 또는 jquery를 사용할 수 있습니까?


3
내가 아는 한 Javascript는 pdf 문서를 만들 수 없습니다.
Khoa Le

1
요즘 많은 사람들이 PDF로 인쇄 할 수 있습니다. 따라서 그 기능은 틀림없이 필요하지 않습니다.
Eric

4
PDF는 텍스트 기반 언어입니다. 생성 할 수없는 프로그래밍 언어를 찾기가 어려울 것입니다.
Quentin

1
여기에 가능한 대답 : stackoverflow.com/questions/12108806/…
colin

답변:


28

, jspdf 를 사용하여 pdf 파일을 만듭니다.

그런 다음이를 데이터 URI로 변환하고 다운로드 링크를 DOM에 삽입 할 수 있습니다.

그러나 HTML에서 pdf 로의 변환을 직접 작성해야합니다.

페이지의 인쇄용 버전을 사용하고 사용자가 페이지를 인쇄 할 방법을 선택하도록합니다.

편집 : 분명히 최소한의 지원이 있습니다

따라서 대답은 자신의 PDF 작성기를 작성하거나 기존 PDF 작성기를 사용하여 서버에서 수행하는 것입니다.


jspdf는 흥미로워 보이지만 Firefox 5.0이나 IE에서는 데모가 작동하지 않습니다!
Tim Büthe

jspdf는 기능을 최소한으로 지원하며 그래픽도 지원하지 않습니다. 하지만 스타일 시스템과 렌더링이 없다면 기본적으로 작은 노트에 유용합니다. 그렇지 않으면 JS로 전체 HTML 렌더러를 작성해야합니다 (또는 firefox에서 지원되는 drawElement와 함께 캔버스를 속여 사용하고 기억하는 것 같습니다). 나에게 물어 보면 Javascript는 실제로이 코딩 라인에 적합하지 않습니다. 아마도 외부 웹 서비스를 호출하는 것이 가장 쉬운 방법 일 것입니다.
Jon Lennart Aasenden

JavaScript (언어로서)는 전적으로 그것에 달려 있습니다. 브라우저 보안 모델 및 API의 제한으로 실행되는 JavaScript는 덜 그렇습니다.
Quentin

4
누군가가 성냥이나 이쑤시개로 집을 지을 수 있다고 확신하지만, 결국 스티칭, 그래픽, 글꼴 임베딩, 스타일 및 완전한 기능의 조회 테이블을 지원하는 완전히 날아간 pdf 컴파일러는 의문의 여지가 없습니다. jspdf의 소스를 살펴보십시오. 가장 간단한 태그 만 지원하고 조회 사전은 지원하지 않습니다. 완전히 날아간 pdf 컴파일러는 C ++ 또는 Delphi에서 수행하기 어렵지만 순수한 JS 구현은 자살 할 수 있습니다. pdf 컴파일러 만 판매하는 회사가 있습니다 (예를 들어 gnostice 참조). 이것은 "원 라이너"가 아닙니다.
Jon Lennart Aasenden

@JonLennartAasenden 예, 최소한의 지원이 있습니다. 원한다면 js로 PDF 라이터를 작성할 수 있습니다. 그러나 그것은 쉬운 일이 아닙니다. 순수한 JS 구현은 C ++ 또는 Delphi와 마찬가지로 자살 적입니다. JS가 2 등 시민 인 척하지 마십시오.
Raynos

15

야 자바 스크립트로 매우 쉽습니다. 이 코드가 유용하기를 바랍니다.

JSpdf 라이브러리 가 필요합니다 .

<div id="content">
     <h3>Hello, this is a H3 tag</h3>

    <p>a pararaph</p>
</div>
<div id="editor"></div>
<button id="cmd">Generate PDF</button>

<script>
    var doc = new jsPDF();
    var specialElementHandlers = {
        '#editor': function (element, renderer) {
            return true;
        }
    };

    $('#cmd').click(function () {
        doc.fromHTML($('#content').html(), 15, 15, {
            'width': 170,
                'elementHandlers': specialElementHandlers
        });
        doc.save('sample-file.pdf');
    });

    // This code is collected but useful, click below to jsfiddle link.
</script>

여기에 jsfiddle 링크


1
이미지가 pdf로 인쇄되지 않음 :( 당신은 해결책이 있습니까 ??
Maestro Vladimir

2
다중 페이지 또는 CSS 스타일을 제대로 지원하지 않습니다.
Dynamic

1
테이블을 지원하지 않습니다 :( 접근 방식을 좋아했습니다
FutoRicky

3
404 페이지에 JSFiddle 링크 리드
오스카 챔버


7

Phantomjs를 사용할 수 있습니다. 여기에서 다운로드 하고 다음 예제를 사용하여 html-> pdf 변환 기능 https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js 를 테스트 하십시오.

예제 코드 :

phantomjs.exe examples/rasterize.js http://www.w3.org/Style/CSS/Test/CSS3/Selectors/current/xhtml/index.html sample.pdf

명령 줄 유틸리티 대신 javascript와 함께 사용할 수 있습니까?
Dynamic

@Dynamic 아니요, 자바 스크립트를 통해 제어 할 수있는 헤드리스 브라우저입니다. 자바 스크립트를 통해 웹 페이지를 PDF로 인쇄하도록 지시 할 수 있지만 구현은 자바 스크립트가 아닙니다. 그러나 인쇄 할 페이지 대기열을 소비하는 앱으로 래핑하여이 정확한 시나리오에 사용했으며, 저는 javascript를 사용하여 대기열에 항목을 추가합니다. 마찬가지로 서비스로 포장 할 수 있습니다. 크롬 인쇄와 동일한 제한 (예 : 인쇄 친화적
Shane

7

내가 사용 jsPDF하고 dom-to-image도서관 PDF로 수출 HTML에.

나는 누구의 관심사에 대한 언급으로 여기에 게시합니다.

$('#downloadPDF').click(function () {
    domtoimage.toPng(document.getElementById('content2'))
      .then(function (blob) {
          var pdf = new jsPDF('l', 'pt', [$('#content2').width(), $('#content2').height()]);
          pdf.addImage(blob, 'PNG', 0, 0, $('#content2').width(), $('#content2').height());
          pdf.save("test.pdf");
      });
});

데모 : https://jsfiddle.net/viethien/md03wb21/27/


반응 형 모드로 가서 pdf를 다운로드하면 pdf 페이지가 제대로 나오지 않습니다. 반응 형 모드를 사용하여 다운로드 할 때 데스크탑 모드와 동일한 결과를 얻을 수있는 방법이 있습니까?
Nancy

6

내가 어떻게 할 것인지는 방탄 디자인이 아닌 아이디어입니다. 수정해야합니다.

  • 사용자가 PDF로 저장 버튼을 클릭합니다.
  • 서버는 ajax를 사용하여 호출을 보냅니다.
  • 서버는 HTML을 사용하여 생성 된 PDF의 URL로 응답하며 Apache FOP를 매우 성공적으로 사용했습니다.
  • ajax 응답을 처리하는 js는 location.href를 수행하여 JS에서 보낸 URL을 가리키고 해당 URL이로드되는 즉시 콘텐츠 처리 헤더를 첨부 파일로 사용하여 사용자가 파일을 다운로드하도록합니다.

2

html을 pdf 서버 측으로 변환하는 것이 훨씬 쉽고 안정적입니다. Google Puppeteer를 사용하고 있습니다. 선택한 서버 측 언어에 대한 래퍼로 잘 관리됩니다. Puppeteer는 헤드리스 Chrome을 사용하여 스크린 샷 및 / 또는 PDF 파일을 생성합니다. 특히 표, 이미지, 그래프, 여러 페이지 등으로 복잡한 PDF 파일을 생성해야하는 경우 많은 골칫거리를 절약 할 수 있습니다.

https://developers.google.com/web/tools/puppeteer/


2

JavaScript를 사용하여 HTML을 PDf로 변환하는 또 다른 명백한 방법이 있습니다.이를 위해 온라인 API를 사용하십시오. 사용자가 오프라인 일 때 변환을 수행 할 필요가 없으면 제대로 작동합니다.

PdfMage 는 멋진 API가 있고 무료 계정을 제공하는 옵션 중 하나입니다. 많은 대안을 찾을 수 있다고 확신합니다 (예 : 여기 )

PdfMage API의 경우 다음과 같습니다.

 $.ajax({
    url: "https://pdfmage.org/pdf-api/v1/process",
    type: "POST",
    crossDomain: true,
    data: { Html:"<html><body>Hi there!</body></html>" },
    dataType: "json",
    headers: {
        "X-Api-Key": "your-key-here" // not very secure, but a valid option for non-public domains/intranet
    },
    success: function (response) {
        window.location = response.Data.DownloadUrl;
    },
    error: function (xhr, status) {
        alert("error");
    }
});

3
Freehtmltopdf.com 더 이상 위로 될 것 같지 않습니다
자크 Saucier에게

1
PDFMage는 더 이상 무료가 아닙니다.
Prometheus

1

예. 예를 들어 https://grabz.it 의 솔루션을 사용할 수 있습니다 .

스크린 샷을 잡고 조작하기 위해 다양한 방법으로 사용할 수있는 Javascript API가 있습니다. 앱에서 사용하려면 먼저 앱 키와 시크릿을 받고 무료 Javascript SDK를 다운로드해야 합니다.

따라서 사용에 대한 간단한 예를 살펴 보겠습니다.

//first include the grabzit.min.js library in the web page
<script src="grabzit.min.js"></script>
//include the code below to add the screenshot to the body tag    
<script>
//use secret key to sign in. replace the url.
GrabzIt("Sign in to view your Application Key").ConvertURL("http://www.google.com").Create();
</script>

그런 다음 잠시 기다리면 페이지를 다시로드 할 필요없이 이미지가 페이지 하단에 자동으로 나타납니다.

그것은 가장 간단한 것입니다. 이미지 조작, 요소에 스크린 샷 첨부 등의 더 많은 예제는 문서를 확인하세요 .


1

$('#cmd2').click(function() {
  	var options = {
		//'width': 800,
  	};
  	var pdf = new jsPDF('p', 'pt', 'a4');
  	pdf.addHTML($("#content2"), -1, 220, options, function() {
    	pdf.save('admit_card.pdf');
  	});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>

<div id="content2" style="background: #fff;border-bottom: 1px solid #ffffff;">
                    	<div class="tokenDet" style="padding: 15px;border: 1px solid #000;width: 80%;margin: 0 auto;position: relative;overflow: hidden;">
                        	<div class="title" style="text-align: center;border-bottom: 1px solid #000;margin-bottom: 15px;">
                            	<h2>Entrance Exam Hall Ticket</h2>
                            </div>
                            <div class="parentdiv" style="display: inline-block;width: 100%;position: relative;">
                            	<div class="innerdiv" style="width: 80%;float: left;">
                            		<div class="restDet">
                                        <div class="div">
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Name</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>Santanu Patra</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>D.O.B.</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>17th April, 1995</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Address</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>P.S. Srijan Corporate Park, Saltlake, Sector 5, Kolkata-91</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Contact Number</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>9874563210</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Email Id</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>santanu@macallied.com</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Parent(s) Name</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>S. Patra</span><br /><span>7896541230</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Exam Center</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>Institute of Engineering & Management</span>
                                            </div>
                                            <div class="label" style="width: 30%;float: left;">
                                                <strong>Hall Number</strong>
                                            </div>
                                            <div class="data" style="width: 70%;display: inline-block;">
                                                <span>COM-32</span>
                                            </div>
                                        </div>
                                    </div>
                            	</div>
                                <div class="sideDiv" style="width: 20%;float: left;">
                                	<div class="atts" style="float: left;width: 100%;">
                                    	<div class="photo" style="width: 115px;height: 150px;float: right;">
                                        	<img src="images/candidateImg.gif" style="width: 100%;"/>
                                        </div>
                                        <div class="sign" style="position: absolute;bottom: 0;right: 0;border-top: 1px dashed #000;left: 80%;text-align: right;">
                                        	<small>Self Attested</small>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>
                    <button class="btn btn-info" id="cmd2">Download Token</button>


위의 코드는 내가 테스트 한 어떤 브라우저에서도 작동하지 않습니다. "Download Token"버튼을 클릭해도 아무 일도 일어나지 않으며 오류가 기록되지 않습니다. 확인해 주시겠습니까?
Almeister9

0

요컨대 : 아니요. 첫 번째 문제는 대부분의 브라우저에서 보안상의 이유로 기본적으로 no로 설정되어있는 파일 시스템에 대한 액세스입니다. 최신 브라우저는 때때로 데이터베이스 형태로 최소한의 스토리지를 지원하거나 사용자에게 파일 액세스를 활성화하도록 요청할 수 있습니다.

파일 시스템에 액세스 할 수 있다면 HTML로 저장하는 것은 그리 어렵지 않습니다 (JS 문서의 파일 객체 참조).하지만 PDF는 그렇게 쉽지 않습니다. PDF는 Javascript에 실제로 적합하지 않은 고급 파일 형식입니다. Javascript에서 직접 지원하지 않는 데이터 유형 (예 : 단어 및 쿼드)으로 정보를 작성해야합니다. 또한 파일에 저장해야하는 사전 조회 시스템을 미리 정의해야합니다. 누군가가 그것을 작동시킬 수 있다고 확신하지만, 관련된 노력과 시간은 C ++ 또는 Delphi를 배우는 데 더 낫습니다.

그러나 사용자가 제한되지 않은 액세스 권한을 부여하면 HTML 내보내기가 가능해야합니다.


2
왜 C ++ 및 델파이는 inheritantly 더 나은 PDF 작가를 만드는에서?
Raynos

2
그 언어는 고급 소프트웨어를 만들기 위해 만들어 졌기 때문입니다. 자바 스크립트는 그렇지 않았습니다. 자바 스크립트는 완성되지 않았고, 이것이 프로토 타입 시스템이 매달려있는 이유입니다. 저자는 실제 클래스와 더 많은 데이터 유형을 사용하여 HL을 추가 할 계획 이었지만 시간이 없었습니다. 그래서 그것은 "있는 그대로"출판되었습니다. 포인터를 지원하지 않고, 원시 메모리 할당이 고통스럽고, 다른 언어에서 찾은 일부 네이티브 데이터 유형을 지원하지 않으며, 패킹 된 구조 (C의 구조체, 파스칼의 레코드)를 지원하지 않습니다. 목록은 끝이 없습니다. 저는 JS를 좋아하지만 실제 언어가 아닌 브라우저 장난감입니다.
Jon Lennart Aasenden

일부 Java 기반 작성자가 있으며 소스 코드의 크기를 살펴보면 Javascript에서 더 길어질 것이라는 것이 상당히 자명하지만 중요한 점은 IO 형식 및 조회 테이블입니다. . 누군가가 할 수 있다고 확신합니다. 그러나 그것은 매우 느리고 기본적으로 시간 낭비입니다. 글꼴 데이터를 어떻게 삽입 하시겠습니까? OS에서 파일을 가져 와서 (그 자체로 전체 라이브러리 인) 변환하고 포함 할 수도 없습니다. 평범한 집을 지을 수 있는데 왜 성냥의 집을 지 을까요?
Jon Lennart Aasenden

2
"하지만 실제 언어가 아닌 브라우저 장난감입니다." 그것은 Scheme이 실제 언어가 아니라고 말하는 것과 같습니다. "Javascrip 하에서 더 오래 지속될 것이라는 것은 상당히 자명해야합니다." Java는 JavaScript보다 훨씬 더 장황합니다. Java 버전보다 약 2/3 더 짧아야합니다. "그러나 그것은 기본적으로 매우 느리고 기본적으로"매우 느리다는 것은 C ++보다 3/4 배 느리다는 것을 의미합니까? js를 2 등 시민으로 취급하는 것을 그만 둘 수 있을까요? 감사.
Raynos

11
귀하의 개인적인 의견에 관계없이 Jon, "Javascript는 실제 언어가 아닙니다."라는 주장을 그만두겠습니까? 그것이 BS이기 때문입니다. Javascript는 C 또는 C ++와 같은 저수준 컴파일 언어와 다른 목적에 최적화 된 매우 강력한 언어입니다. C 나 C ++로는 할 수없는 JS로 할 수있는 일이 있지만, 이것이 C와 C ++가 "진짜"언어가 아니라는 것을 의미합니까? 아니, 단지 그것들이 다른 것을 의미한다는 것입니다. JS는 다른 튜링 완성 언어와 마찬가지로 실제 프로그래밍 언어입니다.
등시성 '
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.