文章やレポート結果を 「1行N文字」 になるように整形(=自動で改行を入れる)
整形した内容を Word(.docx) に出力して共有できる形にする
手順の全体像(5ステップ)
- 事前準備(ライブラリを入れる)
- 整形したい文章(AI生成文/要約文など)を用意
- 1行あたりの文字数(例:40文字) を決める
- Word(.docx)に書き出す
- 保存する(またはStreamlitで配布)
なぜ「手動改行」を入れるのか
Wordの自動改行は、フォント・余白・表示環境で折り返し位置が変わります。
そこで先に「1行40文字」で改行を入れておくと、誰が開いても同じ見た目になりやすいです。
ここでの「40」は 40行ではなく、40文字(40字)です。
1ページ40行」に揃えるのは別の設定(余白・行間・フォント固定)が必要です。
手順①:事前準備
1) ライブラリを入れる
pip install python-docx
手順②:整形したい文章(AI生成文/要約文など)を用意
ここで用意するのは、Wordに出力したい「本文テキスト」です。
入力は どの形式でもOK なので、状況に合わせて次のいずれかで準備します。
パターンA:すでに文章がある(コピペでOK)
すでにAIが生成した文章や要約文がある場合は、そのままコピーして text に入れます。
text = """ここに整形したい文章を貼り付ける
複数段落でもOK(空行で段落区切り)"""
- 改行(段落)も含めてそのまま扱えます
- 長文でも問題ありません(あとで「1行N文字」で折り返します)
パターンB:AI生成の結果をそのまま変数に入れる(実務向け)
OpenAI APIなどで生成した「本文」を、後工程(折り返し→Word出力)に渡す想定です。
# 例:AI生成結果(実際はAPIレスポンスなどから入る)
generated_text = "...AIが作った本文..."
text = generated_text
- ここに入れるのは最終的にWord化したい本文です
パターンC:テキストファイルから読み込む(再現性重視)
毎回同じ文章でレポートを作るなら、txt から読み込むのが便利です。
from pathlib import Path
text = Path("input.txt").read_text(encoding="utf-8")
- Notion共有では「input.txtを差し替えるだけで使える」と説明できるので運用がラクです
入力テキストの注意(ここだけ押さえればOK)
- Word側の自動折り返しに任せないので、本文はどんな長さでも大丈夫
- すでに改行が入っている場合は、段落として尊重されます
- ここで用意した
textを次のステップで「1行◯文字」に折り返します
手順③:一行あたりN文字に整形する(改行を入れる)
日本語は英単語のようにスペースで区切られないため、textwrapよりも 「文字数で切る」関数が安定します。
コード例
def wrap_by_chars(text: str, width: int = 39) -> str:
"""
text を width 文字ごとに折り返して改行を挿入する。
既存の改行は段落として維持し、段落単位で折り返す。
"""
if not text:
return ""
text = text.replace("\r\n", "\n").replace("\r", "\n")
paragraphs = text.split("\n")
out = []
for para in paragraphs:
if para == "":
out.append("")
continue
buf = para
while len(buf) > width:
out.append(buf[:width])
buf = buf[width:]
out.append(buf)
return "\n".join(out)
width=40 なら「1行40文字」
Word上でもこの改行がそのまま反映されます
手順④:Word(.docx)に書き出す
-
python-docxは\nをそのまま入れるより、手動改行(LINE break)を明示した方が安定します -
WD_BREAK.LINEを使うと、Word上で Shift+Enter 相当の改行になります
from io import BytesIO
from docx import Document
from docx.shared import Pt
from docx.enum.text import WD_BREAK
def build_docx_bytes(
text: str,
*,
title: str = "タイトル",
font_name: str = "MS Mincho",
font_size_pt: int = 11,
) -> bytes:
doc = Document()
# 標準フォント設定
style = doc.styles["Normal"].font
style.name = font_name
style.size = Pt(font_size_pt)
# タイトル
doc.add_heading(title, level=1)
# 本文(段落:空行で区切る運用にするなら \n\n を段落とする)
for block in text.split("\n\n"):
p = doc.add_paragraph()
lines = block.split("\n")
for i, line in enumerate(lines):
run = p.add_run(line)
run.font.name = font_name
run.font.size = Pt(font_size_pt)
if i < len(lines) - 1:
run.add_break(WD_BREAK.LINE)
buf = BytesIO()
doc.save(buf)
return buf.getvalue()
手順⑤:保存する(またはStreamlitで配布)
ローカルに保存する例
text ="(ここにレポート本文)"
wrapped = wrap_by_chars(original_text, width=40)
docx_bytes = build_docx_bytes(wrapped, title="タイトル")
withopen("レポート_40字折返し.docx","wb")as f:
f.write(docx_bytes)
Streamlitでダウンロードさせる例
import streamlitas st
st.download_button(
label="Wordで出力(40字折返し)",
data=docx_bytes,
file_name="レポート_40字折返し.docx",
mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
)
まとめ
Wordで見た目を崩さず共有したいなら、Word側の自動折り返しに任せず、先に「1行N文字」で改行(ハード改行)を入れてから .docx に書き出すのが安定です。
手順はシンプルで、事前準備でライブラリを入れ、整形したい文章を用意した後、やることは2つだけ:
- wrap_by_chars() で N文字ごとに改行を挿入する
- build_docx_bytes() で 改行を“手動改行(Shift+Enter相当)”としてWordに書き込む
最後は用途に応じて、ローカル保存 or Streamlitの download_button に載せればOKです。