エクセルファイルをPDFに変換するWEBサービスを作ります。
初めに
- エクセルファイルアップロードすると、PDFファイルがダウンロードできるようにする。
- Dockerfile を使ってデプロイを簡単にする。
ファイル構成
この3つで完結できます。
- Dockerfile
- main.py
- requirements.txt

Dockerfile
PythonアプリケーションをDockerコンテナで実行する構成となっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| FROM python:3.9-alpine3.12
WORKDIR /app COPY . /app
RUN apk update
RUN apk add --no-cache --virtual .build-rundeps \ linux-headers \ build-base \ mariadb-connector-c-dev \ libxml2-dev \ libxslt-dev
RUN apk add --no-cache --virtual .libreoffice-rundeps \ libreoffice \ libreoffice-base \ libreoffice-lang-ja \ font-noto-cjk
COPY requirements.txt . RUN pip install --upgrade pip RUN python3 -m pip install --no-cache-dir -r requirements.txt
EXPOSE 80
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
|
Dockerfileの説明
ベースイメージの設定
1
| FROM python:3.9-alpine3.12
|
Python 3.9 がインストールされた Alpine Linux 3.12 イメージをベースに使用します。
作業ディレクトリの設定
作業ディレクトリをコンテナ内の app
に設定します。
ファイルのコピー
ホストマシンの現在のディレクトリの内容をコンテナ内の app
にコピーします。
パッケージの更新
Alpine Linux のパッケージリストを更新します。
依存パッケージのインストール(ビルド関連)
1 2 3 4 5 6
| RUN apk add --no-cache --virtual .build-rundeps \ linux-headers \ build-base \ mariadb-connector-c-dev \ libxml2-dev \ libxslt-dev
|
ビルドに関連する依存パッケージをインストールします。
依存パッケージのインストール(LibreOffice関連)
1 2 3 4 5
| RUN apk add --no-cache --virtual .libreoffice-rundeps \ libreoffice \ libreoffice-base \ libreoffice-lang-ja \ font-noto-cjk
|
LibreOffice および関連パッケージをインストールします。
Python の依存ライブラリのインストール
1 2 3
| COPY requirements.txt . RUN pip install --upgrade pip RUN python3 -m pip install --no-cache-dir -r requirements.txt
|
Python の依存ライブラリを requirements.txt
ファイルに基づいてインストールします。
ポートの公開
コンテナがポート 80 を外部に公開することを宣言します。
コンテナの起動コマンド
1
| CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80"]
|
コンテナが起動された際に実行されるコマンドを指定します。 uvicorn
を使用して Pythonアプリケーション を ホスト:0.0.0.0
の ポート:80
で実行します。
main.py
- FastAPI を使用してWebサービスを構築します。
- ExcelファイルからPDFへの変換機能を提供します。
- ユーザーはExcelファイルをアップロードし、変換されたPDFファイルを受け取ることができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| import os import shutil import tempfile import subprocess
from fastapi import FastAPI, UploadFile from fastapi.responses import FileResponse
app = FastAPI()
def convertXlsx2Pdf(out_path, file_name): cmd = [] cmd.append("libreoffice") cmd.append("--headless") cmd.append("--nologo") cmd.append("--nofirststartwizard") cmd.append("--convert-to") cmd.append("pdf:calc_pdf_Export") cmd.append("--outdir") cmd.append(out_path) cmd.append(file_name)
subprocess.run(" ".join(cmd), shell=True)
@app.post("/xlsx2pdf/") async def create_upload_file(upload_file: UploadFile):
with tempfile.NamedTemporaryFile(delete=False) as temp_file: shutil.copyfileobj(upload_file.file, temp_file)
convertXlsx2Pdf('./work', temp_file.name)
temp_file_name = os.path.basename(temp_file.name) upload_file_name = upload_file.filename.rsplit('.', 1)[0]
return FileResponse(f'./work/{temp_file_name}.pdf', media_type='application/octet-stream', filename=f'{upload_file_name}.pdf')
|
requirements.txt
1 2 3
| fastapi==0.104.0 uvicorn==0.23.2 python-multipart==0.0.6
|
実行
次のコマンドで Dockerイメージ
を作成し、Dockerコンテナー
を実行します。
1 2
| docker build -t xlsx2pdf-image . docker run -p 80:80 xlsx2pdf-image
|
Dockerコンテナーが起動したらブラウザーで http://localhost/docs を開くことができます。

- XLSXファイルをアップロードする。
- Execute で ファイルを POST する。
- Download file で 変換されたPDFをダウンロードする。

あとは、自身のWEBサービスから呼んであげてください。
GitHub
https://github.com/noitaro/python-xlsx2pdf