import gradio as gr import os, sys, pypdf, copy from datetime import datetime, timedelta import io #import pytz from datetime import datetime, timedelta from pypdf import PdfReader, PdfWriter from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4 from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase import pdfmetrics def write_date_in_pdf(date, comments): # 日付の書式を設定 weekday_num = date.weekday() japanese_weekdays = ["月", "火", "水", "木", "金", "土", "日"] formatted_date = date.strftime("%Y年%m月%d日(") + japanese_weekdays[weekday_num] + ")" # 表紙ファイル名を指定 input_pdf_path = "cover.pdf" # PDFファイルを読み込む reader = PdfReader(input_pdf_path) writer = PdfWriter() # 1ページ目を処理 page = reader.pages[0] # 新しいPDFページを作成 packet = io.BytesIO() can = canvas.Canvas(packet, pagesize=A4) width, height = A4 # フォント登録 # 源真ゴシック( http://jikasei.me/font/genshin/) GEN_SHIN_GOTHIC_MEDIUM_TTF = "./GenShinGothic-Medium.ttf" pdfmetrics.registerFont(TTFont('GenShinGothic', GEN_SHIN_GOTHIC_MEDIUM_TTF)) # 中央に日付を書き込む font_size = 16 can.setFont('GenShinGothic', font_size) can.drawString(width *.565, height *.605, formatted_date) # 表紙コメント font_size = 10 can.setFont('GenShinGothic', font_size) i = 0 for comment in comments: can.drawString(width / 6, height * (1 / 15 - i / 48), comment) i = i + 1 can.save() # 新しいPDFページを読み込む packet.seek(0) new_pdf = PdfReader(packet) # 元のページと新しいページをマージ page.merge_page(new_pdf.pages[0]) writer.add_page(page) # 更新されたPDFを新しいファイルに書き込む with open("hyousi.pdf", 'wb') as output_pdf: writer.write(output_pdf) # 指定のページを削除 def delpage(pdf_path, page_nums): reader = pypdf.PdfReader(pdf_path) writer = pypdf.PdfWriter() for i in range(reader.get_num_pages()): if i not in page_nums: writer.add_page(reader.pages[i]) with open(pdf_path, 'wb') as f: writer.write(f) # 実行ボタンの動作 def exec(date, types, pdf_files, del_page_nums, comments): # 表紙に日付とコメントを記入 write_date_in_pdf(date, comments) # 日報記録表紙PDF化 cover_pdf = "hyousi.pdf" # 出力ファイルを作成 output = pypdf.PdfWriter() output.append(cover_pdf) for type in types: for file in pdf_files: if type in file.name: output.append(file.name) # PDFファイルを出力 output_path = "未承認_日報記録" + date.strftime('%Y年%m月%d日') + ".pdf" with open(output_path, 'wb') as f: output.write(f) # 指定されたページを削除 delpage(output_path, del_page_nums) return output_path # Gradioインターフェースの設定 def gradio_interface(inputs, date_str, delpagenum_str, *comments): # 文字列をdatetimeオブジェクトに変換 if(date_str == ""): date_object = datetime.now() - timedelta(hours=15) else: date_object = datetime.strptime(date_str, '%Y/%m/%d') # 結合前ファイル名を読み込み with open("日報記録種別.csv", "r", encoding="shift_jis") as f: types = f.read().split("\n")[0].split(",") # 削除するページを指定 del_page_nums = [int(x) - 1 for x in delpagenum_str.split(',')] # 実行 output_path = exec(date_object, types, inputs, del_page_nums, comments) return output_path def main(): # 1日前の日付を計算 # default_date = datetime.now() - timedelta(hours=15) # default_date = datetime.now(pytz.timezone('Asia/Tokyo')) - timedelta(days=1) # Gradio Blocksの定義 with gr.Blocks() as demo: gr.Markdown("# 日報記録結合app") gr.Markdown("input PDF filesに自動出力された日報記録pdfファイルを入力して、mergeしてください。output PDF fileに結合済みpdfファイルが出力されます。日付が空欄の場合前日として扱うよう変更しました。") # 表紙コメント内容 comments = [ "※有効電力量 西日本5 池原幹線: 2024/12/17WHM撤去に伴う情報削除により空欄", "※有効電力量 西日本7 人吉大口線2L,人吉川内川線: 2025/2/19TSOメータ化に伴う情報削除により空欄", "※変電記録 日報2 154kV送電線: 2025/3/1 154kV設備廃止に伴い0固定" ] with gr.Row(): with gr.Column(): input_files = gr.File(file_count="multiple", file_types=[".pdf"], label="Input PDF files") date_input = gr.Textbox(label="Date with the format YYYY/MM/DD, automatically set to the previous date if blank") # date_input = gr.Textbox(value=default_date.strftime('%Y/%m/%d'), label="Date with the format YYYY/MM/DD, automatically set to the previous date if blank") page_num_input = gr.Textbox(value="23,45", label="Pages to delete (comma-separated)") comments_input = [gr.Textbox(value=comment, label="Comment to insert") for comment in comments] submit_button = gr.Button("merge") output_file = gr.File(label="Output PDF file") # comments_inputの各Textboxを個別に渡す submit_button.click(gradio_interface, inputs=[input_files, date_input, page_num_input] + comments_input, outputs=output_file) demo.launch(debug=True) # Gradioインターフェースの起動 if __name__ == "__main__": main()