Add-On
次の2つを入れて、LibraOfficeを使えるようにする。
heroku-buildpack-apt
heroku buildpacks:add --index 1 heroku-community/apt
|
heroku-buildpack-libreoffice-for-heroku-18
heroku buildpacks:add --index 2 https://github.com/BlueTeaLondon/heroku-buildpack-libreoffice-for-heroku-18.git
|
Aptfile
ルートにAptfileを設置し、次を書き込む。
libsm6 libice6 libxinerama1 libdbus-glib-1-2 libharfbuzz0b libharfbuzz-icu0 libx11-xcb1 libxcb1
|
フォント
日本語フォントの使用
ルートに.fontsディレクトリを設置し、その中にIPAexフォントのipaexg.ttfとipaexm.ttfを格納する。
フォントの変換
いろいろな明朝とゴシックがIPAexフォントで開かれるようにする。
このため、ルートに.config/fontconfig/fonts.confファイルを設置し、次のようなエイリアスを必要なだけ書き込む。
<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "fonts.dtd"> <fontconfig> <alias> <family>MS ゴシック</family> <prefer> <family>IPAexゴシック</family> </prefer> </alias> </fontconfig>
|
スクリプト
次をsoffice.pyとしておく。
import os import subprocess import shutil import glob
default_user_profile = os.environ['HOME'] + "/.config/libreoffice/4/user"
class PdfConverter: def __init__(self, file_in:str, file_out:str, timeout_sec:int=15, user_profile:str=None): self.file_in = file_in self.file_out = file_out self.timeout_sec = timeout_sec self.user_profile = user_profile if self.user_profile: if not os.path.exists(self.user_profile): shutil.copytree(default_user_profile, self.user_profile) def __enter__(self): return self def __exit__(self): self.stop() def start(self): args = [ 'soffice', '--headless', '--convert-to', 'pdf', self.file_in, '--outdir', self.file_out, ] if self.user_profile: args.append('-env:UserInstallation=file://%s' % self.user_profile) stdout_str = "" stderr_str = "" rc = 0 try: ret = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, timeout=self.timeout_sec, check=True, text=True) rc = ret.returncode stdout_str = ret.stdout stderr_str = ret.stderr except subprocess.CalledProcessError as cpe: rc = -1 stdout_str = cpe.stdout stderr_str = cpe.stderr except subprocess.TimeoutExpired as te: rc = -2 stdout_str = te.stdout stderr_str = te.stderr finally: if stdout_str: print(stdout_str) if stderr_str: print(stderr_str) self.stop() return rc def stop(self): tmp_files = self.file_out + '/*.tmp' for f in glob.glob(tmp_files): os.remove(f) print('soffice finished')
if __name__ == "__main__": pc = PdfConverter('test1.xlsx', './output') pc.start()
|
これを例えばflaskで
from soffice import * from flask import Flask, request, send_file
app = Flask(__name__)
@app.route("/hoge/") def hoge(): pc = PdfConverter('test1.xlsx', './output') pc.start() output_file_path = './output/test1.pdf' return send_file(output_file_path, as_attachment=True, download_name='test.pdf')
|
とすればよい
コメント・シェア