こんにちは、こんです🦊
今日は Commercial Invoice 出力機能のブラッシュアップに取り組みました。特に「merged cells に罫線(外枠)だけを引く」という、ごく一見簡単そうに見える課題が、意外と奥深く、そして罠が多かったので、その記録を残します。
🎯 今日のテーマ:テンプレートに忠実なExcel生成
元々作っていた Streamlitアプリでは、納品Excelをアップするだけで次の3つを自動出力できる構成を目指しています:
SagawaOms出荷データ(Excel形式)
納品書(PDF形式)
Commercial Invoice(Excel形式)
このうち、Commercial Invoiceの出力には、テンプレートを忠実に再現するための細かいExcelレイアウト制御が必要です。
🧪 試行錯誤ポイント:「merged cells に外枠を引く」
試したこと:
xlsxwriter の write_blank() + add_format({"top": 1})
set_top(), set_left() などの専用メソッドによる個別罫線設定
merge_range() の前後タイミングを変える
conditional_format() を使って範囲指定でスタイル適用
問題点:
merged_range() で結合されたセルの内部(中継セル)にも write_blank() すると、結合が壊れたり、罫線が重複して表示されたりする
set_top() などでフォーマットを作っても、それを どのセルにいつ書くか で結果が変わる
write_blank() では中身が上書きされないと思いきや、結合セルの一部に書くと全体が壊れる
🔧 最小構成で再検証
一旦すべての高度な処理を止め、**「A2セルの上だけに線を引く」**という最小単位でコード検証を実施:
import xlsxwriter
wb = xlsxwriter.Workbook("border_test.xlsx")
ws = wb.add_worksheet()
fmt = wb.add_format()
fmt.set_top(1) # 上線のみ
ws.write_blank(1, 0, None, fmt) # A2 = (row=1, col=0)
wb.close()
このコードで期待通りA2セルの上に線が引かれることを確認し、ようやく罫線ロジックの本質的な動作に確信を持てました。
📦 それでも進んだ成果たち
今日はあくまで「罫線」に時間を使ってしまった日ではありますが、それでも以下の前進がありました:
Commercial Invoiceテンプレートの構造が整理され、すべての merge_range 指定と row height が明文化
draw_outer_border() の構造が単純化され、検証単位ごとのロールバックが可能になった
複数の方法を検証して、xlsxwriter の制約と自由度を把握できた
💡 今日の学び:簡単なことこそ“仕様”を正確に知る
「セルの周りに線を引く」という当たり前のことが、merged cell × Python × 書式という条件になると急に難しくなる。
でも、こうした一見些細な処理こそが、テンプレートの完成度を大きく左右します。
🧭 明日以降の方針
draw_outer_border() を使って 結合セルの周囲だけに罫線を引く実装を確定
そのうえで、レイアウト全体に均一な品質で罫線を適用
必要に応じて fpdf でPDF版との構造差異を吸収し、出力一貫性の確保へ
🧠 ハッシュタグ
#100日チャレンジ
#xlsxwriter
#PythonでExcel自動化
#業務改善
#罫線問題
#Streamlit開発記録
#テンプレート忠実再現
#DXの泥臭いところ