私はpdf
自分のウェブサイトのウェブページの印刷可能なバージョンを作成しようとしています。express.render()
ページを次のようにレンダリングするだけのようなものpdf
誰かがそれを行うノードモジュールを知っていますか?
そうでない場合は、どのように実装しますか?のようなヘッドレスブラウザの使用について話している方法を見たことがありますphantom.js
が、フローはわかりません。
私はpdf
自分のウェブサイトのウェブページの印刷可能なバージョンを作成しようとしています。express.render()
ページを次のようにレンダリングするだけのようなものpdf
誰かがそれを行うノードモジュールを知っていますか?
そうでない場合は、どのように実装しますか?のようなヘッドレスブラウザの使用について話している方法を見たことがありますphantom.js
が、フローはわかりません。
ムスタファの答えを拡張します。
A) http://phantomjs.org/をインストールしてから
B)ファントムノードモジュールhttps://github.com/amir20/phantomjs-nodeをインストールします
C)これはPDFをレンダリングする例です
var phantom = require('phantom');
phantom.create().then(function(ph) {
ph.createPage().then(function(page) {
page.open("http://www.google.com").then(function(status) {
page.render('google.pdf').then(function() {
console.log('Page Rendered');
ph.exit();
});
});
});
});
PDFの出力:
編集: そのPDFのサイレント印刷
java -jar pdfbox-app-2.0.2.jar PrintPDF -silentPrint C:\print_mypdf.pdf
Phantom.jsはヘッドレスWebkitサーバーであり、任意のWebページをロードしてメモリにレンダリングします。表示されない場合もありますが、現在のビューをPNG、PDFとしてエクスポートできるスクリーンキャプチャ機能があります。 、JPEGおよびGIF。phantom.jsのドキュメントからこの例を見てください
HTMLをPDFにエクスポートする場合。多くのオプションがあります。ノードなしでも
オプション1:window.print()関数を呼び出すボタンをHTMLページに配置します。ブラウザのネイティブhtmlからpdfを使用します。メディアクエリを使用して、HTMLページをPDFで見栄えよくします。また、印刷前と後のイベントを印刷して、印刷前にページに変更を加えることができます。
オプション2。htmltocanvasまたはrasterizeHTML。HTMLをcanvasに変換してから、canvasオブジェクトでtoDataURL()を呼び出して画像を取得します。jsPDFなどのJavaScriptライブラリを使用して、その画像をPDFファイルに追加します。このアプローチの欠点は、PDFが編集可能にならないことです。PDFからデータを抽出する場合は、さまざまな方法があります。
オプション3。@Jozzhardの回答
Puppeteerを使用してHTMLからPDFを作成してみてください
私が見つけた最良の解決策はhtml-pdfです。シンプルで大きなHTMLで動作します。
https://www.npmjs.com/package/html-pdf
それと同じくらい簡単です:
pdf.create(htm, options).toFile('./pdfname.pdf', function(err, res) {
if (err) {
console.log(err);
}
});
パッケージ
html-pdfを使用しました
使いやすく、PDFをファイルとして保存できるだけでなく、PDFコンテンツをWriteStreamにパイプすることもできます(そのため、レポートを保存するためにGoogleストレージに直接ストリーミングできます)。
css+画像の使用
cssが考慮されます。私が直面した唯一の問題-それは私の画像を無視しました。私が見つけた解決策は、src
属性値のurlをbase64に置き換えることでした。
<img src="data:image/png;base64,iVBOR...kSuQmCC">
コードを使用するか、https ://www.base64-image.de/などのオンラインコンバーターの1つを使用して実行できます。
htmlフラグメント+cssから有効なhtmlコードをコンパイルします
html
(jQueryセレクターに.html()メソッドを適用しただけです)。css
次に、関連するファイルの内容を読みました。この2つの値を使用して(変数html
に格納され、それに応じて)テンプレート文字列css
を使用して有効なhtmlコードをコンパイルしました
var htmlContent = `
<!DOCTYPE html>
<html>
<head>
<style>
${css}
</style>
</head>
<body id=direct-sellers-bill>
${html}
</body>
</html>`
そしてそれをhtml-pdfcreate
のメソッドに渡しました。
サーバーにChrome/Firefoxのインスタンスと一緒にPhantomJSをインストールしたくない場合、またはPhantomJSプロジェクトが現在中断されているために、別の方法があります。
APIへの変換を外部化して仕事をすることができます。多くが存在し、さまざまですが、最新の機能を備えた信頼性の高いサービスを利用できます(CSS3、Webフォント、SVG、Canvas互換だと思います)。
たとえば、PDFShift(免責事項、私は創設者です)を使用すると、request
パッケージを使用するだけでこれを行うことができます。
const request = require('request')
request.post(
'https://api.pdfshift.io/v2/convert/',
{
'auth': {'user': 'your_api_key'},
'json': {'source': 'https://www.google.com'},
'encoding': null
},
(error, response, body) => {
if (response === undefined) {
return reject({'message': 'Invalid response from the server.', 'code': 0, 'response': response})
}
if (response.statusCode == 200) {
// Do what you want with `body`, that contains the binary PDF
// Like returning it to the client - or saving it as a file locally or on AWS S3
return True
}
// Handle any errors that might have occured
}
);
外部URLからPDFを作成する
これは、を利用するだけでなく、外部URLで機能するようにhtml-pdf
組み合わせた、以前の回答の適応です。requestify
依存関係をインストールします
npm i -S html-pdf requestify
次に、スクリプトを作成します。
//MakePDF.js
var pdf = require('html-pdf');
var requestify = require('requestify');
var externalURL= 'http://www.google.com';
requestify.get(externalURL).then(function (response) {
// Get the raw HTML response body
var html = response.body;
var config = {format: 'A4'}; // or format: 'letter' - see https://github.com/marcbachmann/node-html-pdf#options
// Create the PDF
pdf.create(html, config).toFile('pathtooutput/generated.pdf', function (err, res) {
if (err) return console.log(err);
console.log(res); // { filename: '/pathtooutput/generated.pdf' }
});
});
次に、コマンドラインから実行します。
node MakePDF.js
あなたの美しいピクセルの完璧なPDFがあなたのために作成されるのを見てください(無料です!)
私の見解では、これを行う最良の方法はAPIを使用することです。これにより、頻繁に更新する必要があるアンマネージコードを実行するアプリに大きくて複雑な依存関係を追加しないようにします。
これを行う簡単な方法は次のとおりです。これは、月額800リクエストで無料です。
var CloudmersiveConvertApiClient = require('cloudmersive-convert-api-client');
var defaultClient = CloudmersiveConvertApiClient.ApiClient.instance;
// Configure API key authorization: Apikey
var Apikey = defaultClient.authentications['Apikey'];
Apikey.apiKey = 'YOUR API KEY';
var apiInstance = new CloudmersiveConvertApiClient.ConvertWebApi();
var input = new CloudmersiveConvertApiClient.HtmlToPdfRequest(); // HtmlToPdfRequest | HTML to PDF request parameters
input.Html = "<b>Hello, world!</b>";
var callback = function(error, data, response) {
if (error) {
console.error(error);
} else {
console.log('API called successfully. Returned data: ' + data);
}
};
apiInstance.convertWebHtmlToPdf(input, callback);
上記のアプローチでは、必要に応じて、APIをオンプレミスまたは独自のインフラストラクチャにインストールすることもできます。
html-pdfを使用する
var fs = require('fs');
var pdf = require('html-pdf');
var html = fs.readFileSync('./test/businesscard.html', 'utf8');
var options = { format: 'Letter' };
pdf.create(html, options).toFile('./businesscard.pdf', function(err, res) {
if (err) return console.log(err);
console.log(res); // { filename: '/app/businesscard.pdf' }
});
ExpressのビューテンプレートからPDFを作成する方法を探してここに到着した場合、同僚と私はexpress-template-to-pdfを作成しました
これにより、Expressで使用しているテンプレート(パグ、ナンジャックなど)からPDFを生成できます。
これはhtml-pdfに依存し、res.renderを使用するのと同じようにルートで使用するように記述されています。
const pdfRenderer = require('@ministryofjustice/express-template-to-pdf')
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'pug')
app.use(pdfRenderer())
res.renderを使用したことがある場合、それを使用することは明白に見えるはずです。
app.use('/pdf', (req, res) => {
res.renderPDF('helloWorld', { message: 'Hello World!' });
})
オプションをhtml-pdfに渡して、PDFドキュメントのページサイズなどを制御できます。
他の人の優れた仕事に基づいて構築するだけです。
@Jozzhart Answerに加えて、ローカルhtmlを作成できます。エクスプレスで提供します。ファントムを使用してそこからPDFを作成します。このようなもの:
const exp = require('express');
const app = exp();
const pth = require("path");
const phantom = require('phantom');
const ip = require("ip");
const PORT = 3000;
const PDF_SOURCE = "index"; //index.html
const PDF_OUTPUT = "out"; //out.pdf
const source = pth.join(__dirname, "", `${PDF_SOURCE}.html`);
const output = pth.join(__dirname, "", `${PDF_OUTPUT}.pdf`);
app.use("/" + PDF_SOURCE, exp.static(source));
app.use("/" + PDF_OUTPUT, exp.static(output));
app.listen(PORT);
let makePDF = async (fn) => {
let local = `http://${ip.address()}:${PORT}/${PDF_SOURCE}`;
phantom.create().then((ph) => {
ph.createPage().then((page) => {
page.open(local).then(() =>
page.render(output).then(() => { ph.exit(); fn() })
);
});
});
}
makePDF(() => {
console.log("PDF Created From Local File");
console.log("PDF is downloadable from link:");
console.log(`http://${ip.address()}:${PORT}/${PDF_OUTPUT}`);
});
index.htmlは何でもかまいません:
<h1>PDF HEAD</h1>
<a href="#">LINK</a>
結果:
const fs = require('fs')
const path = require('path')
const utils = require('util')
const puppeteer = require('puppeteer')
const hb = require('handlebars')
const readFile = utils.promisify(fs.readFile)
async function getTemplateHtml() {
console.log("Loading template file in memory")
try {
const invoicePath = path.resolve("./invoice.html");
return await readFile(invoicePath, 'utf8');
} catch (err) {
return Promise.reject("Could not load html template");
}
}
async function generatePdf() {
let data = {};
getTemplateHtml()
.then(async (res) => {
// Now we have the html code of our template in res object
// you can check by logging it on console
// console.log(res)
console.log("Compiing the template with handlebars")
const template = hb.compile(res, { strict: true });
// we have compile our code with handlebars
const result = template(data);
// We can use this to add dyamic data to our handlebas template at run time from database or API as per need. you can read the official doc to learn more https://handlebarsjs.com/
const html = result;
// we are using headless mode
const browser = await puppeteer.launch();
const page = await browser.newPage()
// We set the page content as the generated html by handlebars
await page.setContent(html)
// we Use pdf function to generate the pdf in the same folder as this file.
await page.pdf({ path: 'invoice.pdf', format: 'A4' })
await browser.close();
console.log("PDF Generated")
})
.catch(err => {
console.error(err)
});
}
generatePdf();
https://www.npmjs.com/package/dynamic-html-pdf
私はdynamic-html-pdfを使用しています。これは単純で、動的変数をhtmlに渡すこともできます。
var html = fs.readFileSync('./uploads/your-html-tpl.html', 'utf8');
var options = {
format: "A4",
orientation: "portrait"
// border: "10mm"
};
var document = {
type: 'file', // 'file' or 'buffer'
template: html,
context: {
'your_key':'your_values'
},
path: '/pdf/1.pdf' // pdf save path
};
pdf.create(document, options)
.then(res => {
console.log(res)
}).catch(error => {
console.error(error)
});
HTMLでは、{{your_key}}を使用できます
PDFノードクリエーターパッケージも使用できます