PleasanterとSheetJSを組み合わせてExcelファイルからデータを取得する


## はじめに

Pleasanterには手軽な外部とのデータ連携の手段としてCSVファイルによるデータのインポート機能がありますが、CSVファイルではなくExcelファイルを直接読み取りたいという要件も多くあると思います。
この記事では、SheetJS Community Editionを活用して、PleasanterにアップロードされたExcelファイルの内容を自動的にPleasanterに取り込む手法をご紹介します。

以下の画像が最終的な実現例です。
![excel2pleasanter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492700/3e40d7eb-b3b4-80d7-c235-9c9f69b0f5d0.gif)

## SheetJS (Community Edition)とは

 SheetJSは、JavaScriptでExcelやCSVを含む表計算ファイルを操作可能にするライブラリです。
このライブラリを使えば、ブラウザやNode.jsでスプレッドシートの読み書きができます。SheetJSには有料のProfessional Editionもありますが、基本的な機能はCommunity Editionでカバーできます。この記事では、PleasanterとSheetJS Community Editionを連携する方法を紹介します。

https://docs.sheetjs.com/

## サンプルデータ

Pleasanterに取り込むExcelのサンプルデータとして、以下のような簡単なデータを用意しました。

|　|A|B|
|---|---|---|
|1|商品名|りんご|
|2|商品分類|果実|
|3|単価|100|

上記をシート`Sheet1`に記述し、Excelブック形式（拡張子:.xlsx）保存します。

## 事前の準備

### Pleasanterの動作環境

今回のデモではPleasanterのバージョンは ver.1.4.1.1 を使用しています。  


### サイトの作成と画面項目の設定

任意の名称で記録テーブル、もしくは期限付きテーブルでサイトを作成します。  
作成したサイトのテーブルの管理から`エディタ`を選択、以下の項目を有効化して適宜表示名を設定します。

|項目|表示名|設定|
|---|---|---|
|Title|商品名|| 
|ClassA|商品分類| |
|NumA|単価| |
|AttachmentsA|添付ファイル| `ファイル数制限` を 1 に設定|

### ヘッダーにHTMLを挿入

対象サイトのテーブルの管理から `HTML`を選択し、以下のコードを 挿入位置 `Head bottom`を指定します。出力先は `新規作成` と `編集` を指定します。

```html
<script src="https://cdn.sheetjs.com/xlsx-0.20.1/package/dist/xlsx.mini.min.js"></script>
```
上記の設定により、CDNに配置されたSheetJSのライブラリを参照します。

なお、SheetJSには すべての機能を備えたFull版と、機能を省略したMini版があります。この記事では単純なセルの参照のみのため、Mini版を利用しています。

CDNからの読み込みについて詳しくは下記ドキュメントを参照してください。

[Standalone Browser Scripts | SheetJS Community Edition](https://docs.sheetjs.com/docs/getting-started/installation/standalone/)

## スクリプトの設定
### スクリプト

対象サイトのテーブルの管理から`スクリプト`を選択し、以下のコードを貼り付けます。出力先は `新規作成` と `編集` を指定します。

```javascript
$p.events.after_set = async function () {
	// 添付ファイルA項目の値を取得
	const attachmentsJson = $p.getControl('AttachmentsA').val();

	// 配列に変換
	const attachmentsArray = JSON.parse(attachmentsJson);

	if(attachmentsArray.length === 1){
		// 添付ファイルの情報
		const attachment = attachmentsArray[0];
		// 添付ファイルの拡張子
		const attachmentExt = attachment.Extention;

		// 添付されたファイルの拡張子が .xlsxであるか
		if (attachmentExt === '.xlsx') {

			// アップロードされたファイルのURL
			const fileUrl = "/binaries/"+ attachment.Guid.toLowerCase() +"/showtemp";
   
			// URLをもとにExcelファイルを取得
			const fileResponse = await fetch(fileUrl);
			const fileData = await fileResponse.arrayBuffer();
			const workbookObj = XLSX.read(fileData);
   
			// Sheet1を参照
			const sheetObj = workbookObj.Sheets["Sheet1"];

			// タイトル項目にB1セルの値をセット
			$p.set($p.getControl('Title'), sheetObj["B1"].w);
			// 分類A項目にB2セルの値をセット
			$p.set($p.getControl('ClassA'), sheetObj["B2"].w);
			// 数値A項目にB3セルの値をセット
			$p.set($p.getControl('NumA'), sheetObj["B3"].w);
		}
	}
}
```

### スクリプトの説明
#### 添付ファイル情報の取得・ファイルの確認
`$p.events.after_set` はデータがサーバに送信され、画面が更新された後に実行されるメソッドです。
Pleasanterの編集画面では、レコードにファイルを添付するとWebサーバにデータがアップロードされ、アップロード済みのファイル名称が画面に表示されます。
今回はレコード更新前にExcelファイルをアップロード完了した時点で即レコードに反映させるため、`$p.events.after_set` が実行されたタイミングに処理を記述しています。

[開発者向け機能：スクリプト：$p.events.after_set | Pleasanter](https://pleasanter.org/manual/script-events-after-set)

Pleasanterの添付ファイル項目（Attachments）は、1つの項目に複数のファイルをアップロードすることができますが、今回は動作を簡略化するため、エディタの設定で添付可能なファイル数制限を1とし、スクリプトでも配列から情報の取り出しを`attachmentsArray[0]`と明記しています。  

#### SheetJS によるExcelファイルの読み取り

Pleasanterのサーバへアップロードされた添付ファイルのURLをもとにSheetJSを用いてExcelファイル、ワークブックの内容を参照します。
操作としては、`XLSX.read(fileData)` でワークブックを開いたあとは、対象のSheetとセルを指定し、`.w`と指定してセルから書式設定されたテキストの値を取得しています。

操作の詳細は、以下SheetJSのチュートリアル、ドキュメントに詳しく記載されています。

[Import Tutorial | SheetJS Community Edition](https://docs.sheetjs.com/docs/getting-started/examples/import#download-file)

[Data Import | SheetJS Community Edition](https://docs.sheetjs.com/docs/solutions/input)

[Cell Objects | SheetJS Community Edition](https://docs.sheetjs.com/docs/csf/cell)

## 操作説明
以上の設定を行い、当該テーブルに`新規作成`でレコードの編集画面を開きます。  
続いて、予め作成したExcelファイルをドラッグアンドドロップか、ファイルを開くダイアログで指定します。ファイルのアップロードが完了し、ファイル名が添付ファイル欄に表示されると、スクリプトによって各項目にExcelファイルの内容が自動で転記されます。

#### 動作例
![excel2pleasanter.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492700/3e40d7eb-b3b4-80d7-c235-9c9f69b0f5d0.gif)
## まとめ

この記事では、PleasanterとSheetJS (Community Edition)を組み合わせて、Pleasanterに添付されたExcelファイルからデータを自動転記する方法を解説しました。

この方法はExcelファイルからデータを取り込む際に、手作業での入力やCSVファイルへの変換などの手間を省くことができます。また、SheetJSはExcelファイルだけでなく、様々なデータ形式に対応しており、Pleasanterのスクリプト機能と組み合わせることで、柔軟なデータ操作が可能になります。  

[Data Export | SheetJS Community Edition](https://docs.sheetjs.com/docs/miscellany/formats)

ぜひ、PleasanterとSheetJSを使って、効率的なデータ管理を実現してみてください。