![見出し画像](https://assets.st-note.com/production/uploads/images/157871402/rectangle_large_type_2_048385ef6f89284f787ff0b30fadf735.png?width=1200)
Google Apps ScriptとJavaScriptを使ってPDFを分割したり結合するwebページを作成する。
![](https://assets.st-note.com/img/1719414764431-t9Mngl64vK.png?width=1200)
必要な時に作成したコードを参照できるように、作成したコードを置いておくためのノートです。自分用に作成したものですが、参考にしていただければ幸いです。
機能としては、2つのみです。
PDFを2つに分割することができる。
2つのPDFを結合することができる。
GAS(Google Apps Script)を使って、簡単なWebページ・Webアプリを作成する際には、htmlにcssもjsも含めて1つのファイルにしてしまうことがオススメです。
GAS上では、GASのスクリプトファイルか、htmlファイルしか作成できないためです。
コード.gs
GAS(Google Apps Script)を使って、HTMLコンテンツを生成し表示させるコードです。
function doGet(e) {
const template = HtmlService.createTemplateFromFile('index');
const htmlOutput = template.evaluate();
return htmlOutput;
}
ChatGPTにコードを解説してもらった結果。
このコードはGoogle Apps Scriptで書かれており、特定のウェブアプリケーションでHTTP GETリクエストを処理するためのものです。以下に各部分の詳細な説明を示します。
doGet(e) 関数
doGet(e) はGoogle Apps Scriptで特定のURLに対してGETリクエストが送られたときに実行されるハンドラ関数です。引数 e にはリクエストの詳細情報が含まれます。
const template = HtmlService.createTemplateFromFile('index');
HtmlService はGoogle Apps Scriptのクラスで、HTMLコンテンツの生成や表示をサポートします。
createTemplateFromFile('index') は、プロジェクト内にある index.html という名前のファイルをテンプレートとして読み込みます。このテンプレートは、HTML形式で動的にコンテンツを生成するために使用されます。
template は index.html ファイルをテンプレートオブジェクトとして保持します。
const htmlOutput = template.evaluate();
template.evaluate() はテンプレートを実行し、最終的なHTMLコンテンツを生成します。
htmlOutput は生成されたHTMLコンテンツを含むオブジェクトです。このオブジェクトは後にHTTPレスポンスとして返されます。
return htmlOutput;
htmlOutput を関数の戻り値として返します。これにより、ウェブアプリケーションがHTTP GETリクエストに対して適切なHTMLレスポンスを返すことができます。
index.html
Gasを使う場合は、cssやjavascriptをhtmlの中に書き込んだ方が実装が簡単なので、全て盛り込みます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PDF Splitter and Merger</title>
</head>
<body>
<h1>PDF Splitter</h1>
<input type="file" id="pdf-upload" accept="application/pdf">
<input type="number" id="split-page" placeholder="Page number to split after">
<button id="split-button">Split PDF</button>
<a id="download-link" style="display: none;">Download Part 1</a>
<h1>PDF Merger</h1>
<input type="file" id="file1" accept="application/pdf">
<input type="file" id="file2" accept="application/pdf">
<button id="merge-button">Merge PDFs</button>
<a id="download-link-merge" style="display: none;">Download Merged PDF</a>
<!-- Include pdf-lib from CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf-lib/1.17.1/pdf-lib.min.js"></script>
<script>
document.getElementById('split-button').addEventListener('click', async () => {
const fileInput = document.getElementById('pdf-upload');
const splitPageInput = document.getElementById('split-page');
const downloadLink = document.getElementById('download-link');
if (fileInput.files.length === 0) {
alert('Please select a PDF file.');
return;
}
const file = fileInput.files[0];
const splitPage = parseInt(splitPageInput.value, 10);
if (isNaN(splitPage) || splitPage <= 0) {
alert('Please enter a valid page number.');
return;
}
const arrayBuffer = await file.arrayBuffer();
const pdfDoc = await PDFLib.PDFDocument.load(arrayBuffer);
const totalPages = pdfDoc.getPageCount();
if (splitPage >= totalPages) {
alert('The split page number must be less than the total number of pages.');
return;
}
const pdfDoc1 = await PDFLib.PDFDocument.create();
const pdfDoc2 = await PDFLib.PDFDocument.create();
for (let i = 0; i < splitPage; i++) {
const [copiedPage] = await pdfDoc1.copyPages(pdfDoc, [i]);
pdfDoc1.addPage(copiedPage);
}
for (let i = splitPage; i < totalPages; i++) {
const [copiedPage] = await pdfDoc2.copyPages(pdfDoc, [i]);
pdfDoc2.addPage(copiedPage);
}
const pdfBytes1 = await pdfDoc1.save();
const pdfBytes2 = await pdfDoc2.save();
const blob1 = new Blob([pdfBytes1], { type: 'application/pdf' });
const blob2 = new Blob([pdfBytes2], { type: 'application/pdf' });
const url1 = URL.createObjectURL(blob1);
const url2 = URL.createObjectURL(blob2);
downloadLink.href = url1;
downloadLink.download = 'part1.pdf';
downloadLink.textContent = 'Download Part 1';
downloadLink.style.display = 'block';
const downloadLink2 = document.createElement('a');
downloadLink2.href = url2;
downloadLink2.download = 'part2.pdf';
downloadLink2.textContent = 'Download Part 2';
downloadLink2.style.display = 'block';
downloadLink.insertAdjacentElement('afterend', downloadLink2);
});
document.getElementById('merge-button').addEventListener('click', async () => {
const file1 = document.getElementById('file1').files[0];
const file2 = document.getElementById('file2').files[0];
if (file1 && file2) {
const mergedPdf = await mergePdfs(file1, file2);
downloadPdf(mergedPdf);
} else {
alert('Please select two PDF files.');
}
});
async function mergePdfs(file1, file2) {
const pdf1Bytes = await file1.arrayBuffer();
const pdf2Bytes = await file2.arrayBuffer();
const pdfDoc1 = await PDFLib.PDFDocument.load(pdf1Bytes);
const pdfDoc2 = await PDFLib.PDFDocument.load(pdf2Bytes);
const mergedPdfDoc = await PDFLib.PDFDocument.create();
const copiedPages1 = await mergedPdfDoc.copyPages(pdfDoc1, pdfDoc1.getPageIndices());
copiedPages1.forEach((page) => mergedPdfDoc.addPage(page));
const copiedPages2 = await mergedPdfDoc.copyPages(pdfDoc2, pdfDoc2.getPageIndices());
copiedPages2.forEach((page) => mergedPdfDoc.addPage(page));
const mergedPdfBytes = await mergedPdfDoc.save();
return new Blob([mergedPdfBytes], { type: 'application/pdf' });
}
function downloadPdf(pdfBlob) {
const url = URL.createObjectURL(pdfBlob);
const downloadLink = document.getElementById('download-link-merge');
downloadLink.href = url;
downloadLink.download = 'merged.pdf';
downloadLink.style.display = 'block';
}
</script>
</body>
</html>
ChatGPTにコードの解説をしてもらった結果
このHTMLファイルは、PDFファイルを分割および結合するための簡単なウェブアプリケーションを実装しています。以下はこのファイルの各部分の説明です。
HTML構造
<!DOCTYPE html>
ドキュメントがHTML5であることを指定しています。
<html lang="ja">
HTMLのルート要素であり、言語を日本語(ja)に設定しています。
<head>
メタデータを含むセクション。
<meta charset="UTF-8">
ドキュメントの文字エンコーディングをUTF-8に設定します。
<meta name="viewport" content="width=device-width, initial-scale=1.0">
ビューポートの設定を行い、レスポンシブデザインをサポートします。
<title>PDF Splitter and Merger</title>
ウェブページのタイトルを設定します。
※ただし、GAS上では、htmlファイルのhead部分の内容がいくつか無視されるので、webアプリのタイトルとして表示されない。
<body>
ウェブページのコンテンツを含むセクション。
PDF分割部分
<h1>PDF Splitter</h1>
「PDF Splitter」という見出しを表示します。
<input type="file" id="pdf-upload" accept="application/pdf">
ユーザーがPDFファイルをアップロードするためのファイル入力フィールド。
<input type="number" id="split-page" placeholder="Page number to split after">
分割するページ番号を入力するための数値入力フィールド。
<button id="split-button">Split PDF</button>
PDF分割を開始するボタン。
<a id="download-link" style="display: none;">Download Part 1</a>
分割後のPDFファイルをダウンロードするためのリンク(初期状態では非表示)。
PDF結合部分
<h1>PDF Merger</h1>
「PDF Merger」という見出しを表示します。
<input type="file" id="file1" accept="application/pdf">
ユーザーが結合する最初のPDFファイルをアップロードするためのファイル入力フィールド。
<input type="file" id="file2" accept="application/pdf">
ユーザーが結合する二つ目のPDFファイルをアップロードするためのファイル入力フィールド。
<button id="merge-button">Merge PDFs</button>
PDF結合を開始するボタン。
<a id="download-link-merge" style="display: none;">Download Merged PDF</a>
結合後のPDFファイルをダウンロードするためのリンク(初期状態では非表示)。
JavaScript
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdf-lib/1.17.1/pdf-lib.min.js"></script>
pdf-libライブラリをCDNから読み込みます。このライブラリはPDFの操作を行うために使用されます。
<script>
JavaScriptコードを含むセクション。
PDF分割の処理
ファイルをアップロードし、ページ番号を指定してPDFを分割するための処理が含まれています。
split-buttonのクリックイベントリスナーを設定し、分割処理を実行します。
PDF結合の処理
二つのPDFファイルをアップロードし、結合するための処理が含まれています。
merge-buttonのクリックイベントリスナーを設定し、結合処理を実行します。
JavaScript関数
mergePdfs
二つのPDFを結合する非同期関数。
downloadPdf
結合されたPDFをダウンロードリンクに設定し、表示する関数。
このファイル全体で、PDFの分割および結合の機能を実装し、ユーザーが簡単にこれらの操作を行えるようになっています。