PDF.js を使ったシンプルな PDF ビューワのメモ。
PDF.js
PDF.js を使うと Web ページに PDF を表示することができます。
PDF.js は以下からダウンロードできます。
https://mozilla.github.io/pdf.js/
シンプル PDF ビューワ
PDF.js で PDF を表示するには、ある程度プログラムする必要があるため、比較的単純に使えるようにライブラリ化してみました。
以下で Web サーバ上の path_to_pdf.pdf を表示します。
import * as pdfjsLib from './pdfjs/build/pdf.mjs';
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs/build/pdf.worker.mjs';
import { SimplePdfViewer } from './simple_pdf_viewer.mjs';
const pdf_viewer = new SimplePdfViewer(pdf_params);
pdf_viewer.render_url('path_to_pdf.pdf');
input type="file" でアップロードされたファイルも表示できます。
import * as pdfjsLib from './pdfjs/build/pdf.mjs';
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs/build/pdf.worker.mjs';
import { SimplePdfViewer } from './simple_pdf_viewer.mjs';
const pdf_viewer = new SimplePdfViewer(pdf_params);
pdf_viewer.render_file('id_file');
SimplePdfViewer のプログラムはこちら。
simple_pdf_viewer.mjs
// caller needs to import pdf.js
// import * as pdfjsLib from './pdfjs/build/pdf.mjs';
// pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs/build/pdf.worker.mjs';
export class SimplePdfViewer {
constructor(params) {
this.params = params;
this.pdf = null;
this.canvas = document.getElementById(this.params.id_canvas);
this.canvas_context = this.canvas.getContext('2d');
this.scale = params.scale ? params.scale : 1.0;
this.page_num = params.page_num ? params.page_num : 1;
this.page_num_pending = null;
this.id_button_prev = this.params.id_button_prev;
if (this.id_button_prev && document.getElementById(this.id_button_prev)) {
document.getElementById(this.id_button_prev).addEventListener('click', (e) => { this.to_prev_page(); });
}
this.id_button_next = this.params.id_button_next;
if (this.id_button_next && document.getElementById(this.id_button_next)) {
document.getElementById(this.id_button_next).addEventListener('click', (e) => { this.to_next_page(); });
}
this.id_text_page_num = this.params.id_text_page_num;
}
// render uploaded file
render_file(id_file) {
document.getElementById(id_file).addEventListener('change', (e) => {
const reader = new FileReader();
reader.onload = (e) => {
const content = new Uint8Array(e.target.result);
pdfjsLib.getDocument(content).promise.then((pdf) => {
this.pdf = pdf;
this.render_page(1);
})
};
const file = e.target.files[0];
reader.readAsArrayBuffer(file);
});
}
render_page(page_num) {
this.page_num = page_num;
this.pdf.getPage(page_num).then((page) => {
this.viewport = page.getViewport({scale: this.scale});
this.canvas.height = this.viewport.height;
this.canvas.width = this.viewport.width;
const render_context = {
canvasContext: this.canvas_context,
viewport: this.viewport
};
page.render(render_context);
});
if (this.id_text_page_num && document.getElementById(this.id_text_page_num))
document.getElementById(this.id_text_page_num).textContent = this.page_num;
}
to_prev_page() {
if (this.page_num <= 1) return;
this.render_page(this.page_num-1);
}
to_next_page() {
if (this.page_num >= this.pdf.numPages) return;
this.render_page(this.page_num+1);
}
}
html はこちら。
simple_pdf_viewer.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>simple pdf viewer</title>
</head>
<body>
<!-- ファイル選択 -->
<div>
<input id="id_pdf_file" type="file" accept="pdf" />
</div>
<!-- ページ移動 -->
<div style="display: flex;">
<input id="id_pdf_prev" type="button" value="<" />
<p id="id_pdf_page_num"> </p>
<input id="id_pdf_next" type="button" value=">" />
</div>
<!-- PDF 描画 -->
<div style="border: solid 1px;">
<canvas id="id_pdf_canvas"></canvas>
</div>
</body>
<script type="module">
import * as pdfjsLib from './pdfjs/build/pdf.mjs';
pdfjsLib.GlobalWorkerOptions.workerSrc = './pdfjs/build/pdf.worker.mjs';
import { SimplePdfViewer } from './simple_pdf_viewer.mjs';
function main() {
const pdf_params = {
id_canvas: 'id_pdf_canvas',
id_file: 'id_pdf_file',
id_button_prev: 'id_pdf_prev',
id_button_next: 'id_pdf_next',
id_text_page_num: 'id_pdf_page_num',
scale: 0.75,
};
const pdf_viewer = new SimplePdfViewer(pdf_params);
pdf_viewer.render_file(pdf_params.id_file);
//pdf_viewer.render_url('test1.pdf');
}
main();
</script>
</html>