web-dev-qa-db-ja.com

Blobオブジェクトを使用してクライアント側で `docx`ファイルを開くことができません-VanillaJavaScript

これはクライアント側のコードであり、他の開発者が自分でこれをテストできるようにする、最小限の完全で検証可能なスニペットです。

// requires: a string that contains html tags
// returns: a Word document that can be downloaded with extension .doc or docx
// @ param cvAsHTML is a string that contains html tags

const preHtml = "<html xmlns:v='urn:schemas-Microsoft-com:vml' xmlns:o='urn:schemas-Microsoft-com:office:office' xmlns:w='urn:schemas-Microsoft-com:office:Word' xmlns='http://www.w3.org/TR/html4/loose.dtd\'><head><meta charset='utf-8'></head><body>";
const postHtml = "</body></html>";
const html = preHtml + cvAsHTML + postHtml;

let filename = "filename";
const blob = new Blob(["\ufeff", html], { type: "application/msword"});

上記のスニペットはチャームのように機能します。 XMLスキーマは冗長であり、実際には不要であることに注意してください。 docファイルはそれらがなくても機能しますが、headタグとbodyタグが存在する必要があります。

docxファイルの場合、ファイルをダウンロードできません。ファイルが破損しているようで、何度か試した後、どうしたらよいかわかりません。これはdocxファイルのコードです:

const preHtml = "<?xml version='1.0' encoding='UTF-8?><html xmlns:v='urn:schemas-Microsoft-com:vml' xmlns:o='urn:schemas-Microsoft-com:office:office' xmlns:w='urn:schemas-Microsoft-com:office:Word' xmlns='http://www.w3.org/TR/html4/loose.dtd\'><head><meta charset='utf-8'></head><body>";
const postHtml = "</body></html>";
const html = preHtml + cvAsHTML + postHtml;

let filename = "filename.docx";
const blob = new Blob(["\ufeff", html], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document.main"});

注:Blobオブジェクト内のMIMEタイプを変更し、application/Zipapplication/octet-streamなどの他のさまざまなオプションを試しました。役に立たないなど。また、prehtml変数を変更して次のものを含めました。

<?xml version='1.0' encoding='UTF-8?>

Docxファイルは基本的にxmlセグメントを含むzipファイルであることを理解しています...

与えられた助けを本当に感謝します。

編集:2019年12月16日

これは、@ dw_によって提案された実装後に撮ったスクリーンショットです。

JSZipを使用した実装は、次の理由で期待どおりに機能しません。

  1. ブラウザは、docファイルの場合のように、ユーザーがMicrosoftWordでファイルを開くことをネイティブに許可しません。
  2. ユーザーは最初にファイルを保存する必要がありますが、それでもファイルが破損しているため、ファイルは開きません。

enter image description here

4
rags2riches

それほど単純ではないと思います。 docx拡張子の付いたドキュメントは実際に圧縮されますが、単一の圧縮ファイルはありませんが、特定のフォルダー構造とファイル名が必要です。 https://en.wikipedia.org/wiki/Office_Open_XML_file_formats を参照してください。ドキュメントを動的に生成できるようにするには、「最小の構造とファイル」を生成する必要があります。空のdocxファイルを保存して解凍すると、私が何を意味するのかがわかります。 MS WordやLibreOfficeなどで試してみてください。構造は、「同じ」になります。

ジッピングで-多分これは役立つかもしれません https://stuk.github.io/jszip/ は助けることができます。

ドキュメント自体で-私たちが使用したアプローチを提案することができます。 Officeアプリで「テンプレートドキュメント」を用意し、$ HEADER $、$ BODY $などのプレースホルダーを配置しました。次に、プログラムでそれを解凍し、プレースホルダーを実際の文字列に置き換えてから、出力に圧縮しました。これは非常に効果的で実用的でした。最終的なドキュメントを完全に制御でき、デザイン、色、静的テキストを変更するのは非常に簡単でした。テンプレートを編集してアップロードするだけです。

0
Tom HANAX