LoginSignup
2
5

More than 3 years have passed since last update.

ふるさと納税 ワンストップ特例制度の寄付金税額控除に係る申告特例申請書をPythonで記入する

Last updated at Posted at 2020-12-27

ふるさと納税 ワンストップ特例制度の寄付金税額控除に係る申告特例申請書をPythonで記入する

ふるさと納税ワンストップ特例制度を使う場合の申請書は1/10必着です。
手書きで記入するのが大変だったので、配布されているpdfに必要項目を記入するスクリプトを作成しました。

google Colaboratory で動かしています。

ライブラリの準備

# pdf編集に必要なライブラリ
!pip install PyPDF2 reportlab
# 日本語をpdfに書き込むためのフォント
!apt-get -y -q install fonts-ipaexfont

import io
from PyPDF2 import PdfFileWriter
from reportlab.lib.colors import Color
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from reportlab.lib.units import mm
from reportlab.lib.pagesizes import A4, portrait

# フォントを登録
pdfmetrics.registerFont(
    TTFont(
        'IPAexPMincho',
        '/usr/share/fonts/opentype/ipaexfont-mincho/ipaexm.ttf'
    )
)

# 書き込む情報
address = ["東京都〇〇区〇〇町", "123-123", "コーポ303"]
tel = "03-0000-0000"
hurigana = "ヤマダ タロウ"
name = "山田 太郎"
number = "000000000000"
sex = "male"
birth = ("令", "1", "1" ,"1")
wareki = "2"

data = [
    ("〇〇市", 2, 12, 1,100000),
    ("△△町", 2, 12, 1,50000),
]

文字を書き込む処理

def write_common(can):
    font_size = 10

    left = 49*mm
    right = 113*mm
    can.setFont('IPAexPMincho', font_size)
    can.setFillColor(Color(0, 0, 0, alpha=1))

    # 住所
    for i, row in enumerate(address):
        can.drawString(left, (37*mm + (font_size + 5) * i), row)

    # 電話番号
    can.drawString(left, 59*mm, tel)

    # フリガナ
    can.drawString(right, 33*mm, hurigana)

    # 氏名
    can.drawString(right, 39.5*mm, name)

    # 個人番号
    for i, num in enumerate(number):
        can.drawString(right - 2.1*mm + (i * 4.1)*mm, 47*mm, num)

    # 性別
    if sex == "male":
        maru = right + 13*mm
    else:
        maru = right + 27.4*mm
    can.drawString(maru, 52.7*mm, "○")

    # 生年月日
    if birth[0] == "明":
        nengou = (right - 1.5*mm, 58*mm)
    elif birth[0] == "大":
        nengou = (right + 2.7*mm, 58*mm)
    elif birth[0] == "昭":
        nengou = (right + 6.6*mm, 58*mm)
    elif birth[0] == "平":
        nengou = (right + 1.5*mm, 61*mm)
    elif birth[0] == "令":
        nengou = (right + 2.7*mm, 61*mm)
    can.drawString(*nengou, "○")
    birth_height = 60*mm
    can.drawString(right + 16*mm, birth_height, birth[1])
    can.drawString(right + 27*mm, birth_height, birth[2])
    can.drawString(right + 37*mm, birth_height, birth[3])

    # 和暦
    can.drawString(45*mm, 14*mm, wareki)

    # チェック
    can.drawString(151*mm, 161*mm, "✓")
    can.drawString(151*mm, 200*mm, "✓")

    # 記入日
    can.setFont('IPAexPMincho', 8)
    date_height = 26*mm
    can.drawString(40*mm, date_height, "2")
    can.drawString(51*mm, date_height, "12")
    can.drawString(63*mm, date_height, "31")
def write_kifu(can, kifu_data):
    can.setFont('IPAexPMincho', 10)
    can.drawRightString(68*mm, 29*mm, kifu_data[0] + "長")
    kifu_height = 134.5*mm
    can.drawString(51*mm, kifu_height, str(kifu_data[1]))
    can.drawString(62*mm, kifu_height, str(kifu_data[2]))
    can.drawString(74*mm, kifu_height, str(kifu_data[3]))
    can.drawRightString(139*mm, kifu_height, f"{kifu_data[4]:,}")

ファイルに書き込み

from PyPDF2 import PdfFileReader
# 配布されている申請書のpdfを読み込む
pdf_path = "./onestop_myNumber_form.pdf"

width, height = portrait(A4)
output = PdfFileWriter()

for row in data:
    packet = io.BytesIO()
    can = canvas.Canvas(packet, pagesize=(width, height), bottomup=False)
    write_common(can)
    write_kifu(can, row)
    can.showPage()
    can.save()

    packet.seek(0)
    new_pdf = PdfFileReader(packet)

    pdf = PdfFileReader(pdf_path)
    page = pdf.getPage(0)

    page.mergePage(new_pdf.getPage(0))
    output.addPage(page)


with open(f"./kifu.pdf", "wb") as fout:
    output.write(fout)

完成!

kifu_〇〇市.png

参考になった記事

https://buildersbox.corp-sansan.com/entry/2020/06/09/110000
https://news.mynavi.jp/article/zeropython-70/

2
5
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
2
5