反応とスタイルのコンポーネントを使用してPDFを生成する


AnvilのサポートHTMLとCSSからPDFファイルを生成します.シンプルさと相互運用性のために、エンドポイントのみバニラHTML&CSSを受け入れる.明らかにバニラHTML & CSSを書くことは辛いです.
反応、Vue、より少ない、SASS、スタイルの構成要素などのような最新技術は、よりモジュラーで再利用可能なコードを書くことができます.幸運にもこれらの技術はすべて、バニラHTMLとCSSにコンパイルされます.
したがって、エンドポイントはバニラHTMLとCSSだけを受け入れる間、あなたはHTMLとCSSを生成したいと思うどんな技術も使用して、それをAPIに送ります.たとえば、上記のライブラリを使用することができます反応とVue、あるいはあなたの狂気の自家製のテンプレート言語.ライブラリがHTMLとCSS文字列を生成できる限り、APIを使用することができます!
この記事では、いくつかのPDFを作成するために、ノード内の反応とスタイルのコンポーネントを使用する方法を示しますan invoice PDF .
ポストの要点は以下の通りです.始めましょう.

足場を設置する


まず最初に、HTMLとCSSからPDFを生成するクイックノードスクリプトを設定します.最初にバニラHTMLとCSSの文字列を使います.それから、私たちは反応してスタイルの構成要素の段階的に層になります.
まず、あなたが持っていることを確認し、アンビルをインストールしてくださいNode API client :
yarn add '@anvilco/anvil'
# or
npm install '@anvilco/anvil'
それから、このスクリプトはPDFを生成します.
// generate-pdf.js script

import fs from 'fs'
import path from 'path'
import Anvil from '@anvilco/anvil'

const apiKey = 'YOUR_ANVIL_API_KEY'

// Subsequent code samples will focus on modifying
// this buildHTMLToPDFPayload() function
function buildHTMLToPDFPayload () {
  // We'll change these lines soon!
  const html = '<div>Hello World</div>'
  const css = ''
  return {
    data: {
      html,
      css,
    },
  }
}

async function main () {
  const client = new Anvil({ apiKey })
  const exampleData = buildHTMLToPDFPayload()
  const { statusCode, data, errors } = await client.generatePDF(exampleData)

  if (statusCode === 200) {
    fs.writeFileSync('output.pdf', data, { encoding: null })
  } else {
    console.log(statusCode, JSON.stringify(errors || data, null, 2))
  }
}

main()
このスクリプトを実行し、次の出力が表示されます.大仕事!

こんにちはWorld HTML

バベルを加える


反応の利用jsx ノードの構文はbabel . ほとんどの読者が持っていると思うbabel セットアップ.あなたがするならば、このセクションをスキップしてください!
以下はスーパーミニマルインストールです.あなたの生産環境はずっと頑丈になるでしょう.最初のステップは2つのコアパッケージをインストールし、プリセットのカップルが最も重要な存在です@babel/preset-react .
yarn add -D @babel/core @babel/node @babel/preset-env @babel/preset-react
# or
npm install --save-dev @babel/core @babel/node @babel/preset-env @babel/preset-react
最後のステップは.babelrc インストール済みのプリセットを使用したプロジェクトのルートファイルです.
{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
  ]
}
これでスクリプトを実行できますyarn babel-node generate-pdf.js .

反応を加える


反応を伴う若干のHTMLを生成する時間.サーバサイドレンダリングを使用しますreact-dom/server .
インストールreact and react-dom
yarn add react react-dom
# or
npm install react react-dom
現在使用ReactDOMServer.renderToStaticMarkup HTMLを生成するには私たちはrenderToStaticMarkup の代わりにrenderToString だってrenderToStaticMarkup いくつかの属性は、動的更新のための反応を使用します.我々はPDFを生成しているので、動的な更新がないので、余分な属性を使用していない.
// Import React packages
import React from 'react'
import ReactDOMServer from 'react-dom/server'

// The component to render
const Hello = () => (
  <div>Hello React!</div>
)

function buildHTMLToPDFPayload () {
  // Then generate an HTML string!
  const html = ReactDOMServer.renderToStaticMarkup(
    <Hello />
  )
  // css is still the same for now...
  const css = ''
  return {
    data: {
      html,
      css,
    },
  }
}
スクリプトを実行し、ガスで調理します.

こんにちはHTMLをPDFに反応

スタイルコンポーネントの追加


次はCSSです.CSS文字列を生成するstyled-components . 最初のインストールstyled-components :
yarn add styled-components
# or
npm install styled-components
反応するようにstyled-components サーバーのレンダリング機能があります.私たちのパスは、新しいServerStyleSheet , レンダリングsheet.collectStyles(<YourComponent />) , それから、ストリングとしてすべてのスタイルを得てください.
迅速なスニペットは、それが反応する方法を示します.
import { ServerStyleSheet } from 'styled-components'

// Generate the HTML, taking care to render the
// component with styled-components
const sheet = new ServerStyleSheet()
const html = ReactDOMServer.renderToStaticMarkup(
  sheet.collectStyles(
    <Hello />
  )
)
const css = sheet.instance.toString()
次に、いくつかの実際のスタイルでコンテキスト内のスニペットを示します.
// Import styled-components
import styled, { ServerStyleSheet } from 'styled-components'

// Use styled components
const Container = styled.div`
  font-size: 20px;
`

const Magenta = styled.span`
  color: magenta;
`

const Blue = styled.span`
  color: blue;
`

const Hello = () => (
  <Container>
    Ooh, <Magenta>so</Magenta> <Blue>pretty</Blue>!
  </Container>
)

function buildHTMLToPDFPayload () {
  // Generate the HTML, taking care to render the
  // component with styled-components
  const sheet = new ServerStyleSheet()
  const html = ReactDOMServer.renderToStaticMarkup(
    sheet.collectStyles(
      <Hello />
    )
  )

  // Finally, get the CSS as a string
  const css = sheet.instance.toString()

  return {
    data: {
      html,
      css,
    },
  }
}
結果:

HTML&CSSにスタイル&コンポーネントにスタイル

グローバルスタイルを挿入


おそらくPDFにいくつかのグローバルなスタイルを注入する必要があります.たとえば、フォントサイズ、色、ページの詳細などを設定するには、スタイルコンポーネントを活用できますcreateGlobalStyle() 関数.最後の例では、Container 'フォントサイズ20px , しかし、我々はちょうどそのスタイルをすることができましたbody ルール.
ここでは、簡略化されたスニペットです.
import styled, { ServerStyleSheet, createGlobalStyle } from 'styled-components'

const GlobalStyle = createGlobalStyle`
  body {
    font-size: 20px;
  }
`
const Hello = () => ( /* render hello */ )

const sheet = new ServerStyleSheet()
const html = ReactDOMServer.renderToStaticMarkup(
  sheet.collectStyles(
    <>
      <GlobalStyle />
      <Hello />
    </>
  )
)
const css = sheet.instance.toString()
スクリプトでこれを使用すると、最後の例と同じ結果が得られます:

グローバルスタイルと同じ結果

スクリプト全体


ここで我々は全体enchiladaで:反応します.styled-components , とグローバルスタイル.このスクリプトは、あなたが反応し、スタイルのコンポーネントの方法でPDFにしたいものをレンダリングするために必要なすべてが含まれています.
import fs from 'fs'
import path from 'path'
import Anvil from '@anvilco/anvil'

import React from 'react'
import ReactDOMServer from 'react-dom/server'
import styled, { ServerStyleSheet, createGlobalStyle } from 'styled-components'

const apiKey = 'YOUR_ANVIL_API_KEY'

const GlobalStyle = createGlobalStyle`
  body {
    font-size: 20px;
  }
`

const Package = styled.span`
  color: magenta;
`

const Hello = () => (
  <div>
    Hello from <Package>React</Package> & <Package>styled-components</Package>!
  </div>
)

function buildHTMLToPDFPayload () {
  const sheet = new ServerStyleSheet()
  const html = ReactDOMServer.renderToStaticMarkup(
    sheet.collectStyles(
      <Hello />
    )
  )
  const css = sheet.instance.toString()
  return {
    data: {
      html,
      css,
    },
  }
}

async function main () {
  const client = new Anvil({ apiKey })
  const exampleData = buildHTMLToPDFPayload()
  const { statusCode, data, errors } = await client.generatePDF(exampleData)

  if (statusCode === 200) {
    fs.writeFileSync('output.pdf', data, { encoding: null })
  } else {
    console.log(statusCode, JSON.stringify(errors || data, null, 2))
  }
}

main()

請求書例


こんにちは世界の例はかわいいです、そして、すべて、しかし、あなたは現実の例を見たいかもしれません.
我々は作成したReact to PDF invoice example このブログ記事のアプローチを使用します.このポストで議論される技術とともに、請求書の例はページ番号付け、ヘッダー/フッターレンダリング、特別なテーブル機能などのような特徴を使用します.

反応&スタイルコンポーネントを使用して請求書のPDF生成例

概要


あなた自身の反応&スタイルのコンポーネントコードからPDFファイルを作成するために必要なすべてのツールを持っている必要があります.あなたは、このポストのアプローチを外挿することによってあなたの選択(例えばVue + SSSS)の他のテクノロジーを使用することができます.つまり、HTMLとCSS文字列を出力できるなら、HTMLでPDFエンドポイントに使用できます.
あなたが質問をするか、あなたがPDFでクールな何かを開発しているならば、我々に知らせてください[email protected] . 私たちはあなたから聞いてみたい.