0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

公文書をWebブラウザ上で簡単に表示・変換できる「かんたん公文書ビューア」を作ってみた

Posted at

公文書を簡単に表示・変換できる「かんたん公文書ビューア」を作ってみた

はじめに

e-Govでダウンロードした公文書は XML + XSL 形式で配布されることが多いですが、一般のWebブラウザではそのまま表示できません。公式にはEdgeのInternet Explorerモードというよくわからない機能を使わなければ表示できないとのことで、エンジニアでない人にとっては非常に扱いづらいフォーマットです。(エンジニアの私もいつもどうやって表示するかわからなくなります)

そこで、ZIP ファイルでまとめられた XML 公文書を Web ブラウザ上で簡単に閲覧できる「かんたん公文書ビューア」 を作成しました。
https://kantan-docs.primewave.co.jp/

公文書ビューア_文書表示.png

本記事では、その開発の経緯や技術的なポイントを紹介します。


公文書ビューアの機能

ZIP ファイルから XML + XSL を自動解析

ZIP ファイルをアップロードすると、含まれる XML 文書を解析し、対応する XSLT(スタイルシート)を適用して Web ブラウザで表示します。

PDF 形式でのダウンロード

ブラウザで表示した公文書を ボタン一つで PDF に変換・ダウンロード できるようにしました。

画像として保存(PNG 形式)

PDF 形式に変換するとレイアウトが崩れる場合があるため、表示内容を 画像(PNG)として保存できる機能 も追加しました。

A4 サイズ固定の表示

公文書は基本的に A4 サイズで作成されるため、ビューアも A4 サイズ(210mm × 297mm)に固定して表示します。

サブドメインで公開し、Web サービス化

最終的に、独自ドメインのサブドメインを作成し、「かんたん公文書ビューア」として公開しました。


使用技術

技術 用途
HTML5 + CSS3 レイアウト、デザイン
JavaScript (Vanilla JS) XML / XSLT の処理、動的表示
JSZip ZIP ファイルの解析
XSLTProcessor XML から HTML への変換
html2pdf.js PDF 生成
html2canvas 画像として保存

実装のポイント

1. ZIP の解析と XML / XSL の読み込み

const fileMap = {};

document.getElementById('zipInput').addEventListener('change', async (event) => {
  const file = event.target.files[0];
  if (!file) return;

  const zip = new JSZip();
  const arrayBuffer = await file.arrayBuffer();
  const loadedZip = await zip.loadAsync(arrayBuffer);

  for (const relativePath in loadedZip.files) {
    const zipEntry = loadedZip.files[relativePath];
    if (zipEntry.dir) continue;
    if (/(\.xml|\.xsl)$/i.test(relativePath)) {
      const textData = await zipEntry.async("string");
      fileMap[relativePath] = { text: textData };
    }
  }
  await transformAllXmlInMemory();
  renderDocList();
});

JSZip を使って ZIP 内の XML / XSL ファイルを解析。


2. XSLTProcessor による変換

const parser = new DOMParser();
const processor = new XSLTProcessor();

function transformXml(xmlText, xslText) {
  const xmlDoc = parser.parseFromString(xmlText, "application/xml");
  const xslDoc = parser.parseFromString(xslText, "application/xml");
  processor.importStylesheet(xslDoc);
  return processor.transformToFragment(xmlDoc, document);
}

XSLTProcessor を使用して XML に XSL を適用し、HTML に変換。


3. PDF 変換(html2pdf.js)

document.getElementById("downloadPdfButton").addEventListener("click", async () => {
  const docContent = document.getElementById("docFrame").contentWindow.document.body;
  await html2pdf().from(docContent).save("document.pdf");
});

html2pdf.js で Web 上の HTML を PDF に変換。


4. 画像として保存(html2canvas)

document.getElementById("downloadImageButton").addEventListener("click", async () => {
  const docContent = document.getElementById("docFrame").contentWindow.document.body;
  const canvas = await html2canvas(docContent, { scale: 2 });
  const link = document.createElement("a");
  link.download = "document.png";
  link.href = canvas.toDataURL("image/png");
  link.click();
});

html2canvasWeb ページを画像としてキャプチャし、PNG 形式で保存


まとめ

公文書ビューアの開発で学んだこと:

  • XML + XSLT の扱い方
  • ZIP 解析と Web での動的コンテンツ表示
  • PDF や画像変換の技術
  • Web サービスの公開方法(サブドメイン, SSL 設定, .htaccess)

今後の改善点

  • PDF保存に失敗することがある不具合を修正
  • 下記画像のようにレイアウトが崩れて表示されることがある不具合を修正
    公文書ビューア_レイアウト崩れ.png

公開サイト:https://kantan-docs.primewave.co.jp/

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?