Чи можна зберегти HTML-сторінку як PDF за допомогою JavaScript або jquery?


84

Чи можна зберегти HTML-сторінку як PDF за допомогою JavaScript або jquery?

Детально:

Я створив одну HTML-сторінку, яка містить таблицю. У ньому є одна кнопка "зберегти як PDF". Якщо користувач натискає цю кнопку, тоді ця сторінка HTML повинна перетворити у файл PDF.

Чи можна за допомогою JavaScript або jquery?


3
Наскільки я знаю, Javascript не може створювати PDF-документи.
Khoa Le

1
Сьогодні багато людей можуть друкувати в PDF-файлах. Тож ця функціональність, можливо, не потрібна.
Ерік

4
PDF - це текстова мова. Вам важко буде знайти мову програмування, з якої ви не змогли б її створити.
Квентін

1
можлива відповідь тут: stackoverflow.com/questions/12108806/…
colin

Відповіді:


28

Так , використовуйте jspdf для створення PDF-файлу.

Потім ви можете перетворити його на URI даних та вставити посилання для завантаження в DOM

Однак вам доведеться написати перетворення HTML у pdf самостійно.

Просто використовуйте друковані версії вашої сторінки, і дозвольте користувачеві вибрати, як він хоче друкувати сторінку.

Редагувати: очевидно, він має мінімальну підтримку

Отже, відповідь полягає в тому, щоб написати свій власний PDF-редактор або домогтися існуючого PDF-писача, який зробить це за вас (на сервері).


jspdf виглядають цікаво, але демонстраційні версії не працюють ні у Firefox 5.0, ні в IE!
Тім Бюте

jspdf має мінімальну підтримку функцій, він навіть не підтримує графіку. Але якщо не існує системи стилів та рендерингу - це в основному просто корисно для невеликих нотаток. В іншому випадку вам доведеться написати цілий HTML-візуаліст також у JS (або обдурити та використовувати канву з drawElement, який якраз підтримується у Firefox, я, схоже, пам’ятаю). Якщо ви запитаєте мене, Javascript насправді не підходить для цього рядка кодування. Можливо, зателефонувати зовнішній веб-службі - це найпростіший спосіб.
Джон Леннарт Аасенден,

JavaScript (як мова) повністю залежить від нього. JavaScript працює з обмеженнями моделей безпеки браузера та API.
Квентін

4
Я впевнений, що хтось міг побудувати будинок із сірників чи зубочисток, але зрештою - про повномасштабний компілятор pdf із підтримкою зшивання, графіки, вбудовування шрифтів, стилів та повністю функціональних таблиць пошуку не може бути й мови. Подивіться на джерело для jspdf - воно підтримує лише найпростіші теги та відсутні словники пошуку. Повністю продунутий компілятор PDF важко зробити навіть у C ++ або Delphi, чиста реалізація JS була б самогубною. Є компанії, які роками працюють, продаючи лише свої PDF-компілятори (див., Наприклад, gnostice). Це не "один лайнер".
Джон Леннарт Аасенден,

@JonLennartAasenden Так, він має мінімальну підтримку. Ви все ще можете написати PDF-редактор у js, якщо хочете. Однак це непросте завдання. Чиста реалізація JS така ж самогубна, як C ++ або Delphi. Не вдавайте, що JS є громадянином другого сорту.
Raynos

15

Я це дуже легко зробити за допомогою JavaScript. Сподіваюся, цей код вам стане в нагоді.

Вам знадобиться бібліотека 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 :( у вас є рішення ??
Маестро Володимир

2
Він не підтримує багатосторінкові сторінки та стилі css належним чином.
Динамічний

1
Не підтримує таблиці :( Полюбив підхід
FutoRicky

3
Посилання JSFiddle веде на сторінку 404
Оскар Чемберс

13

Це може бути пізня відповідь, але це найкраще: https://github.com/eKoopmans/html2pdf

Чиста реалізація JavaScript. Дозволяє вказати лише один елемент за ідентифікатором та перетворити його.


1
Жодна відповідь не запізнюється :). Дякую
Калян Чавалі

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 ні, це безголовий браузер, яким ви можете керувати за допомогою javascript. Ви можете сказати йому надрукувати веб-сторінку у форматі PDF через javascript, але реалізація не є javascript. Однак використовував його для цього точного сценарію, обертаючи його в програму, яка займає чергу друку сторінок, і я використовую javascript для додавання записів до черги. Подібним чином ви можете обернути це в службі. Для контролю над тим, як друкуються речі, хоча ви маєте ті самі обмеження, що й хромована друк (наприклад, css та js для створення друкованого подання)
Шейн,

7

Я використовував jsPDFта dom-to-imageбібліотеку для експорту HTML у PDF.

Я розміщую тут як посилання на кого стосуються.

$('#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 не надходить належним чином, чи є спосіб досягти того самого результату, що і режим робочого столу, коли я завантажую в адаптивному режимі.
Ненсі

6

Ось як я це міг би зробити, це ідея не куленепробивного дизайну, вам потрібно її змінити

  • Користувач натискає кнопку зберегти як PDF
  • Серверу надсилається дзвінок за допомогою ajax
  • Сервер відповідає URL-адресою для PDF, згенерованого за допомогою HTML, я дуже успішно використовував Apache FOP
  • JS, що обробляє відповідь ajax, робить location.href для вказівки URL-адреси, надісланої JS, і як тільки ця URL-адреса завантажується, вона відправляє файл із використанням заголовка розміщення вмісту як вкладення, що змушує користувача завантажувати файл.

2

Набагато простіше і надійніше перетворити html на pdf-сервер. Ми використовуємо Google Puppeteer. Він добре підтримується обгортками для будь-якої вибраної мови на стороні сервера. Puppeteer використовує безголовий Chrome для створення знімків екрану та / або PDF-файлів. Це позбавить вас БАГАТО головного болю, особливо якщо вам потрібно створити складні файли PDF із таблицями, зображеннями, графіками, кількома сторінками тощо

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


2

Існує ще один дуже очевидний спосіб перетворення HTML у PDf за допомогою JavaScript: використовуйте для цього онлайн-API. Це буде добре працювати, якщо вам не потрібно робити перетворення, коли користувач перебуває в автономному режимі.

PdfMage - це один із варіантів, який має приємний API та пропонує безкоштовні облікові записи. Я впевнений, що ви можете знайти безліч альтернатив (наприклад, тут )

Для API PdfMage у вас буде щось подібне:

 $.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, схоже, більше не працює
Зак Сосьє

1
На жаль, PDFMage вже не безкоштовний.
Прометей

1

Так. Наприклад, ви можете використовувати рішення за адресою https://grabz.it .

У нього є API Javascript, який можна використовувати по-різному для захоплення знімка екрана та керування ним. Для того, щоб використовувати його у вашому додатку, вам потрібно буде спочатку отримати ключ та секрет програми та завантажити безкоштовний 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>


Наведений вище код не працює в жодному перевіреному мною браузері. Нічого не відбувається, коли ви натискаєте кнопку «Завантажити маркер», і помилок не реєструється. Будь ласка, перевірте.
Almeister9

0

Коротше: ні. Перша проблема полягає у доступі до файлової системи, для якої в більшості браузерів за замовчуванням встановлено значення no з міркувань безпеки. Сучасні браузери іноді підтримують мінімалістичне сховище у формі бази даних, або ви можете попросити користувача увімкнути доступ до файлів.

Якщо у вас є доступ до файлової системи, тоді зберегти як HTML не так складно (див. Об'єкт файлу в документації до JS) - але PDF не так просто. PDF - це досить вдосконалений формат файлу, який насправді погано підходить для Javascript. Це вимагає від вас запису інформації в типи даних, які безпосередньо не підтримуються Javascript, такі як слова та квадри. Вам також потрібно заздалегідь визначити систему пошуку словника, яку потрібно зберегти у файлі. Я впевнений, що хтось може змусити це працювати, але затрачені зусилля та час краще витратити на вивчення C ++ або Delphi.

Однак експорт HTML повинен бути можливим, якщо користувач надає вам доступ без обмежень


2
Чому C ++ та Delphi успадково краще створюють PDF-програвач?
Raynos

2
Тому що ці мови були побудовані для створення вдосконаленого програмного забезпечення. Javascript не був. Javascript так і не був закінчений, саме тому система прототипів зависає. Автор планував додати до нього HL із реальними класами та іншими типами даних - але він не встиг. Тож він був опублікований "як є". Він не підтримує покажчики, розподіл необробленої пам'яті є болючим, він не підтримує деякі власні типи даних, які ви знайдете іншими мовами, він не підтримує упаковані структури (структура на C, запис на паскалі) ... список нескінченний. Я люблю JS, але це іграшка для браузера, а не справжня мова.
Джон Леннарт Аасенден

Є декілька авторів, заснованих на Java, і якщо ви подивитесь на розмір вихідного коду, повинно бути досить зрозуміло, що це було б навіть довше під Javascript - але вирішальним моментом є: форматування IO та таблиці пошуку. . Я впевнений, що хтось міг це зробити - але це було б надзвичайно повільно і, в основному, марною тратою часу. І як ви будете вставляти дані шрифтів? Ви навіть не можете отримати файл з ОС, не кажучи вже про те, щоб перетворити його (а це ціла бібліотека сама по собі) та вбудувати. Навіщо будувати будинок сірників, коли ви можете просто, побудувати звичайний будинок?
Джон Леннарт Аасенден

2
"але це іграшка для браузера, а не справжня мова". Це як сказати, що схема не є справжньою мовою. "повинно бути досить очевидно, що це було б ще довше за Javascrip", ні. Java є значно більш багатослівною, ніж JavaScript. Він повинен бути приблизно на 2/3 коротший за версію Java. "але це було б надзвичайно повільно і в основному," Під надзвичайно повільним ви розумієте в 3/4 рази повільніше за C ++? Чи можемо ми припинити поводитися з js як з громадянином другого класу. Дякую.
Raynos

11
Незалежно від вашої особистої думки, Джон, не могли б ви перестати твердити, що "Javascript - це не справжня мова", бо це BS. Javascript - надзвичайно потужна мова, яка оптимізована для різних цілей, ніж компільована мова низького рівня, така як C або C ++. У JS є те, що ви не можете робити на C або C ++, але чи означає це, що C і C ++ не є "справжніми" мовами? Ні, просто вони призначені для різних речей. JS є настільки ж реальною мовою програмування, як і будь-яка інша повна Тьюрінга мова.
Ізохронний
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.