表の入ったpdfファイルをcsvファイルに変換

## はじめに
表の入ったpdfファイルを受け取ってcsvファイルに変換できるwebアプリをdjangoで作ってみました。
tabulaというpdfを読み取ってくれるライブラリを使用してみました。

### 参考にしたサイト
[PythonでPDFファイルのテーブルデータを読み取る](https://qiita.com/OgawaHideyuki/items/5e474976b6d85f1029dc)
[Django 公式ドキュメント](https://docs.djangoproject.com/ja/2.1/topics/http/file-uploads/)

## 完成したもの
見た目はこだわってないのでご容赦ください
![Screen Shot 2021-04-07 at 11.33.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708343/0695d13a-7ad0-b01d-125d-f62763843d84.png)

ここにpdfファイルをアップロードしてボタンをクリックします。
今回は参考記事と同じくこちらの[pdf]("https://www.mhlw.go.jp/content/10906000/000618483.pdf")を扱いました。

![Screen Shot 2021-04-07 at 11.40.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708343/4ec31e54-969c-72c3-e40f-faca591dd383.png)
はい。手抜きなんです。成功が返ってきました。
保存先は自分の開発しているフォルダに入っています。そのcsvファイルをあけてみると、、、
<img width="200" alt="Screen Shot 2021-04-07 at 11.47.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/708343/e4f22913-b221-b0ae-8125-bf802171c085.png">

取得することができました。こんな感じです。

## コード
```python:views.py
from django.shortcuts import render
from django.http import HttpResponseRedirect,HttpResponse
from .forms import UploadFileForm

import pandas as pd

#pdfからcsvに変換するためのライブラリ
from tabula import read_pdf

def fileUpload(request):
  if request.method == 'POST':
    # ファイルデータの受け取り
    form = UploadFileForm(request.POST, request.FILES)
    if form.is_valid():
      file_obj = request.FILES['file']
      handle_uploaded_file(file_obj)
      toCsv(file_obj)
      context = {
         'success': '成功！',
         }
      return render(request,'TableImageToCsv/result.html',context)
  else:
    form = UploadFileForm()
  return render(request, 'TableImageToCsv/index.html', {'form': form})

# 受け取ったpdfファイルを保存する関数
def handle_uploaded_file(file_obj):
  file_path = file_obj.name
  with open(file_path, 'wb+') as destination:
    for chunk in file_obj.chunks():
      destination.write(chunk)

# 表pdfをcsvにする関数
def toCsv(file_obj):
  file_name = file_obj.name.split('.')[0] + '.pdf'
# ここでtabulaを使ってpdfを読み取っている
  df = read_pdf(file_name)
  csv_file = file_obj.name.split('.')[0] + '.csv'
  # １つのページに複数の表があるときはdfの配列番号を指定すると良い
  pd.DataFrame(df[0]).to_csv(csv_file, encoding='shift-jis')
```

```html:index.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta http-equiv="CONTENT-TYPE"
    content="text/html; charset=utf-8" />
  <title>表の入ったpdfファイルをcsvに変換するアプリ</title>
</head>

<body>
  <h3>表の入ったpdfファイルをアップロードしてください</h3>
  <form method="POST"
    enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">アップロード</button>
  </form>
</body>

</html>
```

```html:result.html
<!DOCTYPE html>
<html lang="ja">

<head>
  <meta http-equiv="CONTENT-TYPE"
    content="text/html; charset=utf-8" />
  <title>表画像をcsvに変換するアプリ</title>
</head>

<body>
  <h3>結果</h3>
  <h2>{{success}}</h2>
</body>

</html>
```

```python:forms.py
from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()
```

## おわりに
今回このアプリの実装は2日くらいかかったのですが、最初は表画像からcsvに変換するアプリを作るつもりでした。
そのために画像->pdf->csvとやろうとしていたのですが、結果上手くいきませんでした。
どうやら、pdfに変換する際に画像が荒くなってtabulaで読み取りきれてないように感じました。
同じ表でも画像とpdfでは読み込みの結果が異なってしまいました。
他のライブラリを使用したり、変換方法を変えたりすればよかったのかもしれませんが、ライブラリの仕組みについてもっと自分で勉強したいと思いました。
あと、作成したcsvファイルをユーザーがダウンロードできるような機能も実装すると使えるアプリになるのかなと思います。