Wordにコメントをつけると下図のようにコメントを入れた人の名前が入ります。今回は仕事での必要に迫られて、このコメントの名前を変更もしくは削除するWebサービスを作成してみたのでご紹介します。

私は業務の1つとして、他人が書いた文章を査読する仕事をしているのですが、その中で誰がコメントしたかを分からないようにする「ブラインド化」が必要になります。これまでは特定の名前が登録されていないPCで作業したり、自分のPCで査読後に自作のPythonプログラムを使ってコメントの作者名を削除していたのですが、職場で他の人もそのプログラムを使いたいという要望がありWebサービスとして試しに作成したのが今回紹介するものです。
Webサービスはこちら:
https://share.streamlit.io/life-wisdom/streamlit/blind_docx_comment.py
※注)このサイトはテスト用に作ったものなので、実際に職場で使うものは別のサイトに作成し運用します。
実際の動作
サイトにアクセスすると以下のような画面が表示されます。

ページ中ほどに「作者名」を入力する欄があります。デフォルトで作者名を「Anonymous Author」に変更するようになっていますが、この入力欄に変更したい名前を入力すれば、Wordファイルのコメントの作者名がその名前に変わるようになっています。
ページ下方に別の欄(灰色背景)がありますが、ここにコメントが入ったWordファイルをドラッグ&ドロップすると、コメント作者名を変更する処理が行われます。処理後、ダウンロードリンクが現れるので、それをクリックしてファイルをダウンロードしてください。
下にコメントの入った処理前のファイルと、コメント作者名を削除した処理後のファイルを示します。


「George」というコメント作者名が「Anonymous Author」に変更されていることが分かります。
もし「作者名」の欄を空欄にした場合はコメントの作者名が削除されます。

作者名を削除した場合

ソースコード
セキュリティの関係でソースコードのすべてを公開できませんが、Wordファイルから著者情報を削除する部分だけご紹介します(※元のプログラムから一部を抜き出したものなので、このままでは正しく動きません。ご注意ください)。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
import os import re import io import hashlib from zipfile import ZipFile from docx import Document ''' 中略 以下のように変数 uploaded_file にファイルへのパスが、変数 user_input に変更後のコメント作者名が入っています。 uploaded_file = "XXXX.docx" # ファイル名 user_input = "Anonymous Author" ''' doc = Document(uploaded_file) # remove author information core_properties = doc.core_properties meta_fields= ["author", "category", "last_modified_by", "comments", "content_status", "identifier", "keywords", "language", "subject", "title", "version"] for meta_field in meta_fields: setattr(core_properties, meta_field, "") doc.save(uploaded_file) # filename output_filename = hashlib.sha224(uploaded_file.encode()).hexdigest() srcfile = uploaded_file dstfile = output_filename with zipfile.ZipFile(srcfile) as inzip, zipfile.ZipFile(dstfile, "w") as outzip: # Iterate the input files for inzipinfo in inzip.infolist(): with inzip.open(inzipinfo) as infile: if inzipinfo.filename.startswith("word/comments.xml"): comments = infile.read() comments_new = str() comments_new += re.sub(r'w:author="[^"]*"', f"w:author=\"{user_input}\"", comments.decode()) outzip.writestr(inzipinfo.filename, comments_new) else: outzip.writestr(inzipinfo.filename, infile.read()) ''' このあとダウンロード処理が続く 以下略 ''' |
中略した部分に書いてあることですが、uploaded_fileという変数にファイルへのパスが入っています。またuser_inputという変数に変更後のコメント作者名(デフォルト値が「Anonymous Author」)が入っています。
以下、重要なところだけ簡単に説明していきます。
|
18 19 20 21 22 23 24 25 |
doc = Document(uploaded_file) # remove author information core_properties = doc.core_properties meta_fields= ["author", "category", "last_modified_by", "comments", "content_status", "identifier", "keywords", "language", "subject", "title", "version"] for meta_field in meta_fields: setattr(core_properties, meta_field, "") doc.save(uploaded_file) |
まずはpython-docxライブラリを使ってWordファイルを開いています。その後、以前紹介したdocxファイルから著者情報を削除する処理を入れています。
|
33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
with zipfile.ZipFile(srcfile) as inzip, zipfile.ZipFile(dstfile, "w") as outzip: # Iterate the input files for inzipinfo in inzip.infolist(): with inzip.open(inzipinfo) as infile: if inzipinfo.filename.startswith("word/comments.xml"): comments = infile.read() comments_new = str() comments_new += re.sub(r'w:author="[^"]*"', f"w:author=\"{user_input}\"", comments.decode()) outzip.writestr(inzipinfo.filename, comments_new) else: outzip.writestr(inzipinfo.filename, infile.read()) |
こちらがコメントの作者名を変更している箇所です。
docxファイルというのは実は圧縮ファイルであるzipファイルで、複数のファイルを1つにまとめたものです。なのでzipfileライブラリを使って中に含まれるファイルを1つ1つチェックしていき、コメントが記載されている「comments.xml」ファイルを見つけたら、それに修正を加えています。
comments.xml の中で「w:author=」という部分にコメントの作者名が入っているので、正規表現を使って、文字列を変数 user_input の値に置き換えています。
comments.xml 以外のファイルはそのままコピーしています。
さいごに
かなりマニアックな用途で、あまりニーズがないWebサービスだと思いますが、自分のスキルアップのために試作してみました。今後、特定の名前を別の名前に置き換えることもできるようにしたいと思います。
※注意
今回紹介したWebサービスは個人的な用途で作成したものです。Wordファイルの内容が破損するなど何らかの障害が起こっても責任は持てませんので、ご使用にはご注意ください。
- 投稿タグ
- プログラミング