Fix PDF issue
This commit is contained in:
20
rog/utils.py
20
rog/utils.py
@ -1,5 +1,5 @@
|
||||
import os
|
||||
from aiohttp import ClientError
|
||||
from botocore.exceptions import ClientError
|
||||
from django.template.loader import render_to_string
|
||||
from django.conf import settings
|
||||
import logging
|
||||
@ -193,12 +193,12 @@ class S3Bucket:
|
||||
s3_key = os.path.basename(file_path)
|
||||
|
||||
# S3クライアントが指定されていない場合は新規作成
|
||||
if s3_client is None:
|
||||
s3_client = self.connect()
|
||||
if self.s3_client is None:
|
||||
self.s3_client = self.connect()
|
||||
|
||||
# ファイルのアップロード
|
||||
logger.info(f"アップロード開始: {file_path} → s3://{self.bucket_name}/{s3_key}")
|
||||
s3_client.upload_file(file_path, self.bucket_name, s3_key)
|
||||
self.s3_client.upload_file(file_path, self.bucket_name, s3_key)
|
||||
logger.info("アップロード完了")
|
||||
|
||||
return True
|
||||
@ -313,11 +313,11 @@ class S3Bucket:
|
||||
|
||||
try:
|
||||
# S3クライアントが指定されていない場合は新規作成
|
||||
if s3_client is None:
|
||||
s3_client = self.connect()
|
||||
if self.s3_client is None:
|
||||
self.s3_client = self.connect()
|
||||
|
||||
# プレフィックスに一致するオブジェクトをリスト
|
||||
paginator = s3_client.get_paginator('list_objects_v2')
|
||||
paginator = self.s3_client.get_paginator('list_objects_v2')
|
||||
pages = paginator.paginate(Bucket=self.bucket_name, Prefix=prefix)
|
||||
|
||||
for page in pages:
|
||||
@ -361,12 +361,12 @@ class S3Bucket:
|
||||
|
||||
try:
|
||||
# S3クライアントが指定されていない場合は新規作成
|
||||
if s3_client is None:
|
||||
s3_client = self.connect()
|
||||
if self.s3_client is None:
|
||||
self.s3_client = self.connect()
|
||||
|
||||
# オブジェクトの削除
|
||||
logger.info(f"削除開始: s3://{self.bucket_name}/{s3_key}")
|
||||
s3_client.delete_object(Bucket=self.bucket_name, Key=s3_key)
|
||||
self.s3_client.delete_object(Bucket=self.bucket_name, Key=s3_key)
|
||||
logger.info("削除完了")
|
||||
|
||||
return True
|
||||
|
||||
126
rog/views.py
126
rog/views.py
@ -2764,14 +2764,111 @@ def export_excel(request, zekken_number, event_code):
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
|
||||
|
||||
# 一時ディレクトリを作成(ASCII文字のみのパスを使用)
|
||||
temp_dir = tempfile.mkdtemp(prefix='lo-')
|
||||
logger.debug(f"Created temp directory: {temp_dir}")
|
||||
|
||||
# ASCII文字のみの作業ディレクトリを作成
|
||||
work_dir = os.path.join(temp_dir, 'work')
|
||||
output_dir = os.path.join(temp_dir, 'output')
|
||||
os.makedirs(work_dir, exist_ok=True)
|
||||
os.makedirs(output_dir, exist_ok=True)
|
||||
|
||||
# すべてのディレクトリに適切な権限を設定
|
||||
for directory in [temp_dir, work_dir, output_dir]:
|
||||
os.chmod(directory, 0o777)
|
||||
logger.debug(f"Set permissions for directory: {directory}")
|
||||
|
||||
# ASCII文字のみの一時ファイル名を使用
|
||||
temp_excel_name = f"certificate_{zekken_number}.xlsx"
|
||||
temp_excel_path = os.path.join(work_dir, temp_excel_name)
|
||||
|
||||
# 元のExcelファイルを作業ディレクトリにコピー
|
||||
shutil.copy2(excel_path, temp_excel_path)
|
||||
os.chmod(temp_excel_path, 0o666)
|
||||
logger.debug(f"Copied Excel file to: {temp_excel_path}")
|
||||
|
||||
|
||||
# LibreOffice設定ディレクトリを作成
|
||||
libreoffice_config_dir = os.path.join(temp_dir, 'libreoffice')
|
||||
os.makedirs(libreoffice_config_dir, exist_ok=True)
|
||||
|
||||
# フォント設定ディレクトリを作成
|
||||
font_conf_dir = os.path.join(temp_dir, 'fonts')
|
||||
os.makedirs(font_conf_dir, exist_ok=True)
|
||||
|
||||
# フォント設定ファイルを作成
|
||||
fonts_conf_content = '''<?xml version="1.0"?>
|
||||
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
|
||||
<fontconfig>
|
||||
<dir>/usr/share/fonts</dir>
|
||||
<match target="pattern">
|
||||
<test qual="any" name="family">
|
||||
<string>sans-serif</string>
|
||||
</test>
|
||||
<edit name="family" mode="assign" binding="same">
|
||||
<string>IPAexGothic</string>
|
||||
</edit>
|
||||
</match>
|
||||
<match target="pattern">
|
||||
<test qual="any" name="family">
|
||||
<string>serif</string>
|
||||
</test>
|
||||
<edit name="family" mode="assign" binding="same">
|
||||
<string>IPAexMincho</string>
|
||||
</edit>
|
||||
</match>
|
||||
</fontconfig>'''
|
||||
|
||||
font_conf_path = os.path.join(libreoffice_config_dir, 'fonts.conf')
|
||||
with open(font_conf_path, 'w') as f:
|
||||
f.write(fonts_conf_content)
|
||||
|
||||
|
||||
# LibreOfficeのフォント設定を作成
|
||||
registry_dir = os.path.join(libreoffice_config_dir, 'registry')
|
||||
os.makedirs(registry_dir, exist_ok=True)
|
||||
|
||||
# フォント埋め込み設定を作成
|
||||
pdf_export_config = '''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<oor:data xmlns:oor="http://openoffice.org/2001/registry">
|
||||
<oor:component-data oor:package="org.openoffice.Office.Common" oor:name="Filter">
|
||||
<node oor:name="PDF">
|
||||
<prop oor:name="EmbedFonts" oor:op="fuse">
|
||||
<value>true</value>
|
||||
</prop>
|
||||
<prop oor:name="ExportFormFields" oor:op="fuse">
|
||||
<value>true</value>
|
||||
</prop>
|
||||
<prop oor:name="UseTaggedPDF" oor:op="fuse">
|
||||
<value>true</value>
|
||||
</prop>
|
||||
</node>
|
||||
</oor:component-data>
|
||||
</oor:data>'''
|
||||
|
||||
pdf_config_path = os.path.join(registry_dir, 'pdf_export.xcu')
|
||||
with open(pdf_config_path, 'w') as f:
|
||||
f.write(pdf_export_config)
|
||||
|
||||
# すべてのディレクトリに適切な権限を設定
|
||||
for directory in [temp_dir, work_dir, output_dir,registry_dir]:
|
||||
os.chmod(directory, 0o777)
|
||||
logger.debug(f"Set permissions for directory: {directory}")
|
||||
|
||||
os.chmod(temp_excel_path, 0o666)
|
||||
os.chmod(font_conf_path, 0o666)
|
||||
os.chmod(pdf_config_path, 0o666)
|
||||
|
||||
# フォーマット指定(excel or pdf)
|
||||
format_type = request.query_params.get('format', 'pdf')
|
||||
|
||||
if format_type.lower() == 'pdf':
|
||||
try:
|
||||
# パスとファイル名に分離
|
||||
file_dir = os.path.dirname(excel_path) # パス部分の取得
|
||||
file_name = os.path.basename(excel_path) # ファイル名部分の取得
|
||||
file_dir = os.path.dirname(temp_excel_path) # パス部分の取得
|
||||
file_name = os.path.basename(temp_excel_path) # ファイル名部分の取得
|
||||
|
||||
# ファイル名の拡張子をpdfに変更
|
||||
base_name = os.path.splitext(file_name)[0] # 拡張子を除いたファイル名
|
||||
@ -2786,11 +2883,10 @@ def export_excel(request, zekken_number, event_code):
|
||||
conversion_command = [
|
||||
'soffice', # LibreOfficeの代替コマンド
|
||||
'--headless',
|
||||
'--convert-to',
|
||||
'pdf',
|
||||
'--outdir',
|
||||
file_dir,
|
||||
excel_path
|
||||
'--convert-to', 'pdf:writer_pdf_Export',
|
||||
'--outdir',file_dir,
|
||||
'-env:UserInstallation=file://' + libreoffice_config_dir,
|
||||
temp_excel_path
|
||||
]
|
||||
|
||||
logger.debug(f"Running conversion command: {' '.join(conversion_command)}")
|
||||
@ -2798,6 +2894,11 @@ def export_excel(request, zekken_number, event_code):
|
||||
# 環境変数を設定
|
||||
env = os.environ.copy()
|
||||
#env['HOME'] = temp_dir # LibreOfficeの設定ディレクトリを一時ディレクトリに設定
|
||||
env['HOME'] = temp_dir
|
||||
env['LANG'] = 'ja_JP.UTF-8' # 日本語環境を設定
|
||||
env['LC_ALL'] = 'ja_JP.UTF-8'
|
||||
env['FONTCONFIG_FILE'] = font_conf_path
|
||||
env['FONTCONFIG_PATH'] = font_conf_dir
|
||||
|
||||
# 変換プロセスを実行
|
||||
process = subprocess.run(
|
||||
@ -2805,7 +2906,9 @@ def export_excel(request, zekken_number, event_code):
|
||||
env=env,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
cwd=work_dir,
|
||||
check=True,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
logger.debug(f"Conversion output: {process.stdout}")
|
||||
@ -2819,9 +2922,10 @@ def export_excel(request, zekken_number, event_code):
|
||||
)
|
||||
|
||||
s3 = S3Bucket('sumasenrogaining')
|
||||
s3.upload_file(pdf_path, f'{event_code}/scoreboard', f'certificate_{zekken_number}.pdf')
|
||||
s3.upload_file(excel_path, f'{event_code}/scoreboard_excel', f'certificate_{zekken_number}.xlsx')
|
||||
s3.upload_file(pdf_path, f'{event_code}/scoreboard/certificate_{zekken_number}.pdf')
|
||||
s3.upload_file(excel_path, f'{event_code}/scoreboard_excel/certificate_{zekken_number}.xlsx')
|
||||
|
||||
os.remove(temp_excel_path)
|
||||
os.remove(excel_path)
|
||||
os.remove(pdf_path)
|
||||
|
||||
@ -2833,7 +2937,7 @@ def export_excel(request, zekken_number, event_code):
|
||||
return Response(
|
||||
{"error": f"PDF conversion failed: {str(e)}"},
|
||||
status=status.HTTP_500_INTERNAL_SERVER_ERROR
|
||||
)
|
||||
)
|
||||
finally:
|
||||
# 一時ディレクトリの削除
|
||||
if temp_dir and os.path.exists(temp_dir):
|
||||
|
||||
Reference in New Issue
Block a user