Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
2
Help us understand the problem. What are the problem?

react-pdfで罫線と文字列と画像をPDF出力する

背景

React+Goを使ってWebアプリケーション開発をしております。フォームの入力内容をもとに履歴書としてPDF出力する処理を実装することになり、Reactのライブラリ「React-pdf」を使用して実装することができました。ただ、欲しかった情報があっちこっちに散乱していたので、今回この記事にまとめてみました。

公式ドキュメントだけ読んでもPDF出力は実装できませんでした。全角文字は文字化け(?)されてしまうし、Firebase Storage内の画像のです。調べているうちに、特定のフォント指定が必要であることがわかりました。それについても解説しています。

この記事で解説する内容

  • React-pdfを使用したPDF出力のプログラムソース
  • フォント「ナス」のバイナリファイルダウンロード方法(コレ重要!)

なぜフォントに「ナス」を使うのか?

  • フォントが「ナス」「源真ゴシック」でないとPDF出力結果の全角かな文字が別の文字へ置き換えられてしまうため。フォントを指定しないと「あ→B」「い→D」「う→F」へ置き換えられてしまう。

ライブラリのインストール

いずれかをコマンド実行してインストールする。

  • yarn
yarn add @react-pdf/renderer
  • npm
npm install @react-pdf/renderer --save

プログラムソース

プロジェクトフォルダ構成はこんな感じを想定しています。

ProjectName(プロジェクトフォルダ)
 └ backend
   └┬ react-app
     └ src
       └┬ fonts
         │  ┝ Nasu-Bold.ttf(フォントファイル)
         │  └ Nasu-Regular.ttf(フォントファイル)
         │
        ┝ components
         │  └ resume.js
         │
        └─ index.js

「index.js」から「resume.js」(コンポーネント)を呼び出しているとします。

resume.js
inport React from 'react';
import { PDFDownloadLink, PDFViewer, Page, Text, View, Font, Document, StyleSheet } from '@react-pdf/renderer';
import fontRegular from '../fonts/Nasu-Regular.ttf'  //ttfファイル参照
import fontBold from '../fonts/Nasu-Bold.ttf'        //ttfファイル参照

export const Resume = () => {
  // ttfファイルのフォント定義
  // フォント「ナス レギュラー」
  Font.register({
    family: 'Nasu-Regular',
    src: fontRegular
  });

  // フォント「ナス 太字」
  Font.register({
    family: 'Nasu-Bold',
    src: fontBold
  });

  // CSSスタイル定義
  const wk_styles = StyleSheet.create({
    text1: { fontSize: '11pt', fontFamily: 'Nasu-Regular' },
    text2: { fontSize: '8pt', fontFamily: 'Nasu-Regular' },
    text3: { fontSize: '7pt', fontFamily: 'Nasu-Regular' }
  });

  const MyDoc = () => {
    return (
      <Document>
        {/* orientationは用紙の縦横を指定する(公式ドキュメント参照) */}
        <Page size="A4" orientation="landscape" style={style.body}>
          {/* View要素で罫線を出力、Text要素で文字列を出力 */}
          <View style={{textAlign: 'center', position: 'absolute', top: '100px', left: '35px', width: '40px', height: '32px', borderWidth: '0.2mm 0.2mm 0.2mm 0.2mm', borderStyle: 'solid solid solid solid'}}>
            <Text style={wk_styles.text1}>大きい文字列です</Text>
            <Text style={wk_styles.text2}>ふつうの文字列です</Text>
            <Text style={wk_styles.text3}>小さい文字列です</Text>
          </View>
        </Page>
      </Document>
    )
  }

  return (
    <>
      {/* ①②は自分の目的に合わせて選ぶ */}
      {/* ①:クリックするとPDFをダウンロードする */}
      <PDFDownloadLink document={<MyDoc />} fileName="test1.pdf">
      {({loading}) => (loading ? 'Loading document...' : 'クリックでPDFダウンロード')}
      </PDFDownloadLink>

      {/* ②:PDFをビューアーで表示する */}
      <PDFViewer>
        <MyDoc />
      </PDFViewer>
    <>
  );
};

フォント「ナス」のバイナリファイルダウンロード方法

フォントはインストールせず、tffファイルをダウンロードしてプロジェクト内に配置します。

まずはttfファイルを以下GitHubからダウンロードします。
https://github.com/kashimuraryo/font-nasu

次に以下の場所へttfファイルを配置します。
ProjectName(プロジェクトフォルダ)
 └ backend
   └┬ react-app
     └ src
       └┬ fonts
         │  └ ここに配置
         │
        ┝ components
         │  └ resume.js
         │
        └─ index.js

参考

まとめ

  • 公式ドキュメント(英語)、Qiita記事などを参考にしたがなかなか実装できなかっため、この記事+公式ドキュメントさえ見れば簡単に実装できるように今回まとめてみました。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
2
Help us understand the problem. What are the problem?