Upgrade to Pro — share decks privately, control downloads, hide ads and more …

FigmaとPHPで作る1ミリたりとも表示崩れしない最強の帳票印刷ソリューション

 FigmaとPHPで作る1ミリたりとも表示崩れしない最強の帳票印刷ソリューション

PHPカンファレンス小田原2024 の発表資料です。
https://phpcon-odawara.connpass.com/event/296492/
https://fortee.jp/phpconodawara-2024/proposal/7c57d5ca-213a-4d7a-aaf0-26ddc44897f0

登壇時の様子がYouTubeに上がっていますのでよろしければあわせてご覧ください。
https://www.youtube.com/watch?v=tIxd8C5IDLQ

Takashi Kanemoto

April 13, 2024
Tweet

More Decks by Takashi Kanemoto

Other Decks in Programming

Transcript

  1. / 122 Figma PHP 1 示 2 024 / 04

    / 1 3 PHP 小田 @ttskch  1 #phpcon_odawara #boko
  2. / 122 手 1 . HTML/CSS PDF 2 . Excel

    LibreO ff i ce PDF 3 . 用 手  6 🔖
  3. / 122 手 1 . HTML/CSS PDF 2 . Excel

    LibreO ff i ce PDF 3 . 用 手  7 🔖
  4. / 122 PDF 力 HTML PDF 見 手 自 ⾒

    見 1 人 工 力  13
  5. / 122 手 1 . HTML/CSS PDF 2 . Excel

    LibreO ff i ce PDF 3 . 用 手  14 🔖
  6. <table> <tr> <td colspan="4"></td> <th></th> <td></td> </tr> <tr> <th rowspan="3"></th>

    <td colspan="3"></td> <td colspan="2"></td> </tr> <tr> <td rowspan="2" colspan="3"></td> </tr> <tr> <td colspan="2"></td> </tr> <tr> <th rowspan="5"></th> <td colspan="2"></td> <td rowspan="4"></td> <th></th> <td></td> </tr> <tr> <td rowspan="3" colspan="2"></td> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <td></td> <td colspan="2"></td> <th></th> <td></td> </tr> </table> HTML
  7. <table> <tr> <td colspan="4"></td> <th></th> <td></td> </tr> <tr> <th rowspan="3"></th>

    <td colspan="3"></td> <td colspan="2"></td> </tr> <tr> <td rowspan="2" colspan="3"></td> </tr> <tr> <td colspan="2"></td> </tr> <tr> <th rowspan="5"></th> <td colspan="2"></td> <td rowspan="4"></td> <th></th> <td></td> </tr> <tr> <td rowspan="3" colspan="2"></td> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <td></td> <td colspan="2"></td> <th></th> <td></td> </tr> </table> HTML rowspan colspan ⾒ td 🙄
  8. / 122  21 <table> <tr> <td colspan="4"></td> <th></th> <td></td>

    </tr> <tr> <th rowspan="3"></th> <td colspan="3"></td> <td colspan="2"></td> </tr> <tr> <td rowspan="2" colspan="3"></td> </tr> <tr> <td colspan="2"></td> </tr> <tr> <th rowspan="5"></th> <td colspan="2"></td> <td rowspan="4"></td> <th></th> <td></td> </tr> <tr> <td rowspan="3" colspan="2"></td> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <td></td> <td colspan="2"></td> <th></th> <td></td> </tr> </table> 見
  9. / 122  22 <table> <tr> <td colspan="4"></td> <th></th> <td></td>

    </tr> <tr> <th rowspan="3"></th> <td colspan="3"></td> <td colspan="2"></td> </tr> <tr> <td rowspan="2" colspan="3"></td> </tr> <tr> <td colspan="2"></td> </tr> <tr> <th rowspan="5"></th> <td colspan="2"></td> <td rowspan="4"></td> <th></th> <td></td> </tr> <tr> <td rowspan="3" colspan="2"></td> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <td></td> <td colspan="2"></td> <th></th> <td></td> </tr> </table> 見 人
  10. / 122 <table> <tr> <td colspan="4"></td> <th></th> <td></td> </tr> <tr>

    <th rowspan="3"></th> <td colspan="3"></td> <td colspan="2"></td> </tr> <tr> <td rowspan="2" colspan="3"></td> </tr> <tr> <td colspan="2"></td> </tr> <tr> <th rowspan="5"></th> <td colspan="2"></td> <td rowspan="4"></td> <th></th> <td></td> </tr> <tr> <td rowspan="3" colspan="2"></td> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <th></th> <td></td> </tr> <tr> <td></td> <td colspan="2"></td> <th></th> <td></td> </tr> </table> 1  24 言 日
  11. / 122 手 1 . HTML/CSS PDF 2 . Excel

    LibreO ff i ce PDF 3 . 用 手  26 🔖
  12. / 122 LibreO ffi ce Microsoft O ff i ce

    OSS CLI Excel PDF PDF  28 https://qiita.com/hirohiro 77 /items/ 942 eb 46 1 e 8 f 47 27 e 4 b 38
  13. / 122 LibreO ffi ce Microsoft O ff i ce

    OSS CLI Excel PDF PDF  29 https://qiita.com/hirohiro 77 /items/ 942 eb 46 1 e 8 f 47 27 e 4 b 38
  14. / 122 Excel PDF 見 目 LibreO ff i ce

    Mac Linux PDF 力 欠 力 誘 示  33
  15. / 122 手 1 . HTML/CSS PDF 2 . Excel

    LibreO ff i ce PDF 3 . 用 手  35 🔖
  16. / 122 SVF  38 https://web.archive.org/web/ 20 21120 7 2

    1 48 06 /https://www.wingarc.com/cloud/svfc/price.html 2021 11 月 金非
  17. / 122 手 1 . HTML/CSS PDF 2 . Excel

    LibreO ff i ce PDF 3 . 用 手  42 🔖
  18. / 122 骨子  46 1 . Figma 2 .

    入 % % 3 . SVG 4 . SVG 文 HTML <svg> 5 . CSS 6 . SVG 文
  19. / 122 骨子  47 1 . Figma 2 .

    入 % % 3 . SVG 4 . SVG 文 HTML <svg> 5 . CSS 6 . SVG 文
  20. / 122 pdf 2 svg  51 $ brew install

    pdf2svg $ pdf2svg طଘͷாථ.pdf طଘͷாථ.svg PDF ⾒ pdf 2 svg Figma .svg 生 Figma 面 D&D
  21. / 122 SVG  53 https://zenn.dev/ttskch/articles/ 1 f 157 2

    cfd 2 e 37 5 文 <path> <text> 力 文 <text> id 力 用
  22. / 122 骨子  55 1 . Figma 2 .

    入 % % 3 . SVG 4 . SVG 文 HTML <svg> 5 . CSS 6 . SVG 文
  23. / 122 <!-- index.php --> <!DOCTYPE html> <html lang="ja"> <head>

    <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>ݟੵॻ</title> </head> <body> <?= file_get_contents('/path/to/ݟੵॻ.svg') ?> </body> </html>  60
  24. / 122  62 CSS * { margin: 0; padding:

    0; user-select: none; } body { width: 210mm; color-adjust: exact; svg { width: 210mm; height: 297mm; page-break-after: always; } } @page { size: A4 portrait; margin: 0; } @media screen { body { background: #dbdce0; margin: 0 auto; svg { background: #fff; box-shadow: 0 .5mm 2mm rgba(0,0,0,.3); margin-top: 5mm; } } } https://zenn.dev/ttskch/articles/ 1 f 157 2 cfd 2 e 37 5
  25. / 122 骨子  66 1 . Figma 2 .

    入 % % 3 . SVG 4 . SVG 文 HTML <svg> 5 . CSS 6 . SVG 文
  26. / 122 文  72 HTML 文 < &lt; &lt;

    文 言 文 文 Unicode 文 &#x{16 }; &#{10 }; Unicode Figma SVG 文 文 用
  27. / 122 文  73 PHP html_entity_decode() // จࣈࢀরͰهड़͞ΕͨจࣈྻΛUTF-8ͷจࣈྻʹม׵ echo

    html_entity_decode('খ&#x7530;ݪ', encoding: 'UTF-8'); // ग़ྗ݁Ռ: খాݪ UTF- 8
  28. / 122 人 🙏 ⾒ Unicode UTF- 8 文 方

    Wikipedia 100 💪  82 Unicode UTF- 8 chr()
  29. / 122 // จࣈࢀরॻࣜͰॻ͔ΕͨUTF-8όΠτྻΛσίʔυ $svg = preg_replace_callback( '/&#(\d+);/', fn ($matches)

    => chr($matches[1]), $svg ); // ௨ৗͷจࣈࢀরΛσίʔυ $svg = html_entity_decode($svg, encoding: 'UTF-8');  84
  30. / 122 // id ʹ͍ͭͯͷΈ % Λ _ ʹஔ׵ $svg

    = preg_replace('/id="%(.+)%"/', 'id="_$1_"', $svg);  89 一手
  31. / 122 $replacements = [ '%ސ٬໊%' => 'גࣜձࣾ΄͛΄͛', '%ݟੵ೔%' =>

    '2024/04/13(౔)', // : // : ]; foreach ($replacements as $placeholder => $value) { $svg = str_replace($placeholder, $value, $svg); }  91 str_replace()
  32. / 122 自 小  99 https://zenn.dev/ttskch/articles/ 1 f 157

    2 cfd 2 e 37 5 SVG <text> textLength 長 小 長 😓 長 ⾒ textLength 文
  33. / 122 ・  100 https://zenn.dev/ttskch/articles/ 1 f 157 2

    cfd 2 e 37 5 SVG <text> text-anchor ( | | ) 力 ( | ) <text> X 心 ⾒ / ⾒ ⾒ X 自
  34. / 122 ・  101 https://zenn.dev/ttskch/articles/ 1 f 157 2

    cfd 2 e 37 5 text-anchor ໌ࡉֹۚ ςΩετςΩετςΩετ X ໌ࡉֹۚ ςΩετςΩετςΩετ X text-anchor="end" ໌ࡉֹۚ ςΩετςΩετςΩετ X ໌ࡉֹۚ ςΩετςΩετςΩετ X ໌ࡉֹۚ ςΩετςΩετςΩετ X text-anchor="end"
  35. / 122 自 小  105 https://zenn.dev/ttskch/articles/ 1 f 157

    2 cfd 2 e 37 5 SVG <text> 行 自 行 1 . 行 2 . 高 font-size 小 行 3 . 1, 2 😓
  36. / 122 手 1 . HTML/CSS PDF 2 . Excel

    LibreO ff i ce PDF 3 . 用 手  109 🔖
  37. / 122 ✅ ✅ 一行 自 小・ ・ ✅ 行

    自 ・ 小 API 🙌 README ttskch/svg-paper  113