やりたいこと
jsPDF で PDF ファイルを作成。
react プロジェクトの作成
npx create-react-app --template typescript test_pdf1
test_pdf1 のディレクトリ構成
.
├── README.md
├── node_modules
├── package-lock.json
├── package.json
├── src
│ ├── App.css
│ ├── App.test.tsx
│ ├── App.tsx
│ ├── download-pdf-button.tsx
│ ├── fonts
│ │ ├── NotoSansJP-Bold-base64.ts
│ │ ├── NotoSansJP-Bold.ttf
│ │ ├── NotoSansJP-Regular-base64.ts
│ │ ├── NotoSansJP-Regular.ttf
│ │ ├── create_NotoSansJP-Bold-base64.sh
│ │ └── create_NotoSansJP-Regular-base64.sh
│ ├── index.css
│ ├── index.tsx
│ ├── logo.svg
│ ├── pdf-creator.ts
│ ├── react-app-env.d.ts
│ ├── reportWebVitals.ts
│ └── setupTests.ts
└── tsconfig.json
jsPDF のインストール
npm install jspdf
日本語フォントの設定
Google Fonts で日本語対応フォントをダウンロード
Google Fonts で Noto Sans Japanese フォントをダウンロードする。
- "Get font" をクリック
- "Download all" をクリックして Noto_Sans_JP.zip をダウンロード
- Noto_Sans_JP.zip を unzip
- unzip Noto_Sans_JP.zip
日本語フォントを設定
- src/fonts ディレクトリを作成
mkdir src/fonts
- NotoSansJP-Regular.ttf を src/fonts にコピー
- NotoSansJP-Bold.ttf を src/fonts にコピー
- [Regular フォント] 以下のスクリプトを作成して実行し、NotoSansJP-Regular-base64.ts ファイルを作成
create_NotoSansRegularJP.sh
#!/bin/sh
TTF_FILE=NotoSansJP-Regular.ttf
TGT_FILE=NotoSansJP-Regular-base64.ts
echo '/* eslint-disable */' > ${TGT_FILE}
echo -n 'const NotoSansRegularJP = "' >> ${TGT_FILE}
base64 -w 0 ${TTF_FILE} >> ${TGT_FILE}
echo '"' >> ${TGT_FILE}
echo 'export default NotoSansRegularJP' >> ${TGT_FILE}
- [Bold フォント] 以下のスクリプトを作成して実行し、NotoSansJP-Bold-base64.ts ファイルを作成
create_NotoSansBoldJP.sh
#!/bin/sh
TTF_FILE=NotoSansJP-Bold.ttf
TGT_FILE=NotoSansJP-Bold-base64.ts
echo '/* eslint-disable */' > ${TGT_FILE}
echo -n 'const NotoSansBoldJP = "' >> ${TGT_FILE}
base64 -w 0 ${TTF_FILE} >> ${TGT_FILE}
echo '"' >> ${TGT_FILE}
echo 'export default NotoSansBoldJP' >> ${TGT_FILE}
プログラム作成
メイン
src/App.tsx
import React from 'react';
import { DownloadPdfButton } from './download-pdf-button'
function App() {
return (
<div className="App">
<DownloadPdfButton />
</div>
);
}
export default App;
PDF生成
src/pdf-creator.ts
import { jsPDF as JsPDF } from 'jspdf'
import NotoSansRegularJP from './fonts/NotoSansJP-Regular-base64'
import NotoSansBoldJP from './fonts/NotoSansJP-Bold-base64'
const FONT = 'NotoSansJP'
const fontFileRegular = './fonts/NotoSansJP-Regular.ttf'
const fontFileBold = './fonts/NotoSansJP-Bold.ttf'
const FONT_TYPES = {
NORMAL: 'normal',
BOLD: 'bold',
}
const FONT_SIZES = {
NORMAL: 50,
SMALL: 20,
}
export class PdfCreator {
font: string
doc: any
constructor() {
this.font = FONT
this.doc = null
}
create = () => {
const fileName = `output.pdf`
this.doc = new JsPDF('l', 'mm', 'a4') // l: landscape
// normal font
this.doc.addFileToVFS(fontFileRegular, NotoSansRegularJP)
this.doc.addFont(fontFileRegular, this.font, FONT_TYPES.NORMAL)
// bold font
this.doc.addFileToVFS(fontFileBold, NotoSansBoldJP)
this.doc.addFont(fontFileBold, this.font, FONT_TYPES.BOLD)
// create PDF
this.doc.setFont(this.font, FONT_TYPES.NORMAL)
this.doc.setFontSize(FONT_SIZES.NORMAL)
const pageWidth = this.doc.internal.pageSize.getWidth()
const pageHeight = this.doc.internal.pageSize.getWidth()
const x = pageWidth / 2 - 100
const y = pageHeight / 2 - 25
this.doc.text('これは 1 ページ目です', x, y, { align: 'left' })
this.doc.addPage() // 改ページ
this.doc.text('これは 2 ページ目です', x, y, { align: 'left' })
// page number
this.addPageNumber()
this.doc.save(fileName)
}
addPageNumber = () => {
const totalPages = this.doc.internal.getNumberOfPages()
const x = this.doc.internal.pageSize.width - 20
const y = this.doc.internal.pageSize.height - 10
for (let i = 1; i <= totalPages; i++) {
const pageNumberText = `${i} / ${totalPages}`
this.doc.setPage(i)
this.doc.setFont(this.font, FONT_TYPES.NORMAL)
this.doc.setFontSize(FONT_SIZES.SMALL)
this.doc.text(pageNumberText, x, y, { align: 'right' })
}
}
}
ダウンロードボタン
src/download-pdf-button.tsx
import { PdfCreator } from './pdf-creator'
export const DownloadPdfButton = () => {
const download = () => {
const pdfCreator = new PdfCreator()
pdfCreator.create()
}
return (
<button onClick={download}>Download PDF</button>
)
}
サーバ起動
npm run start
PDF ダウンロード
http://{アドレス}:3000/ にアクセスし、"Download PDF" ボタンをクリックすると、PDF ファイルをダウンロードできる。
