PleasanterExcelMaker：PleasanterでExcel表を作成するJSライブラリ 

# PleasanterExcelMakerについて

PleasanterExcelMakerはPleasanterでExcel表を作成するJSライブラリです。  
様々なJSライブラリを使用すると実現できますが、PleasanterへのデータアクセスとExcel表の作成を容易にして、処理ロジックに集中する為に作成しました。
既に作成したExcel表にデータを埋め込む事が可能で社内で使用しているExcel表と活用する事が可能です。
GitHubからフリーで提供してるのでご自由にお使いください。

https://github.com/senetcojp/PleasanterExcelMaker

## Pleasanterのバージョン
JSライブラリを読み込む都合上 Ver.1.3.45.0 以上をお勧めします。  
クラウドバージョンについてはAPIを使用する都合上、デモライセンス及びスタンダード以上が必要です。  
オープンソース及びエンタープライズに関しては制限無く使用可能です。

## 使い方
※WBS(Sample)を添付しています。Pleasanter使用時に作成されるデモ用テーブル（またはPleasanter Cloudのデモ環境）のプロジェクト管理の例／WBSをExcelで出力するサンプルを作成しています。
![ScreenShot_2023-10-27_182527.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/7a211d6f-cfe1-8099-863e-ee25e29e17fd.png)

### １．Excel表の準備
埋め込むExcel表を準備します。
参照ファイル：wbs_excel01.xlsx
参照ファイル：wbs_excel02.xlsx

### ２．Excel登録用の記録テーブルを作成
１で作成したexcelをPleasanterに登録します。
新しい記録テーブルを作成し、添付ファイル項目を追加してください。  
新しいアイテムを作成し、添付ファイルにexcel表を添付して登録します。添付はひとつの添付ファイル項目に複数登録してもかまいません。
![ScreenShot_2023-10-27_154405.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/80f19a78-479d-5d5d-56ee-905d13c79f3d.png)
![ScreenShot_2023-10-27_154418.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/f46ca8f9-33df-5562-5b54-9329126b4b87.png)

### ３．JSライブラリの読み込み
PleasanterExcelMaker.js(https://github.com/senetcojp/PleasanterExcelMaker)
関連ライブラリ
ExcelJS(https://github.com/exceljs/exceljs)
FileSaverJS(https://github.com/eligrey/FileSaver.js)
![ScreenShot_2023-10-27_155502.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/d809ee5d-ba75-a31d-2290-4c24561e96f6.png)
![ScreenShot_2023-10-27_155511.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/ff6beb0e-b8a3-8f14-d1c2-aba1205a7983.png)
参照ファイル：HTML_ライブラリロード.txt
```
<script src="https://cdnjs.cloudflare.com/ajax/libs/exceljs/4.3.0/exceljs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/senetcojp/PleasanterExcelMaker/PleasanterExcelMaker.js"></script>
```

### ４．コマンドボタンの作成
Excel出力用のコマンドボタンを作成します。サンプルでは一覧出力用ボタン（下部）と詳細出力用ボタン（行）に作成しています。
![ScreenShot_2023-10-27_155541.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/79338590-af88-b02e-e3d6-a8d805051606.png)
![ScreenShot_2023-10-27_155549.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/423fc60d-4292-b065-777d-144dcfe440f8.png)
参照ファイル：スクリプト_Excel出力ボタン(下部).txt
```
$p.events.on_grid_load = function () {
  $('#GoBack').after('<button id="Excel01" class="button button-icon ui-button ui-corner-all ui-widget applied" type="button" onclick="excel01();" data-icon="ui-icon-calculator"><span class="ui-button-icon ui-icon ui-icon-calculator"></span><span class="ui-button-icon-space"> </span>Excel一覧出力</button>');
};
```
![ScreenShot_2023-10-27_155605.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/151fa470-a8a3-19c6-af07-626b7ac833cf.png)
![ScreenShot_2023-10-27_155616.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/f9c60ec5-f345-53c6-277d-27dbcd02650c.png)
参照ファイル：サーバスクリプト_各行に出力ボタンを追加.txt
```
columns.DescriptionA.RawText = `<button id="Excel02" class="button button-icon ui-button ui-corner-all ui-widget applied" type="button" onclick="excel02(${model.IssueId});" data-icon="ui-icon-calculator"><span class="ui-button-icon ui-icon ui-icon-calculator"></span><span class="ui-button-icon-space"> </span>Excel詳細出力</button>`;
```

### ５．出力コードの作成
![ScreenShot_2023-10-27_155502.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/aff0c4f9-8c87-1bb5-d1ef-153b9324f821.png)
![ScreenShot_2023-10-27_155522.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63349/4213a073-c63c-d676-48c2-15e7eee6c071.png)
参照ファイル：HTML_Excel出力処理.txt
```
<script type="text/javascript">
//[id] Excelを登録したアイテムのIDになります。
function excel01() {
  const em = new PleasanterExcelMaker();
  let workbook;
  em.ExcelDownloadItemAttach([id],'A','wbs_excel01.xlsx')
  .then(function(value){
    workbook = value;
    let data = {"ApiVersion": 1.0, "View": em.getFilter()}
    data.View.ApiDataType = "KeyValues";
    data.View.ApiColumnKeyDisplayType = "ColumnName";
    data.View.GridColumns = ["IssueId","Ver","Title","Body","StartTime","CompletionTime","WorkValue","ProgressRate","RemainingWorkValue","Status","ClassA","ClassB","ClassC","Owner","Manager"];
    console.log(data);
    em.ApiGet(0, data)
    .then(function(value){
      let sheet = workbook.worksheets[0];
      sheet.name = "サンプル01";
      let rset = value.data.Response.Data;
      console.log(sheet);
      console.log(rset);
      for( var c=0; c<Object.keys(rset).length; c++) {
          var row = 4+c;
          sheet.getCell(`A${row}`).value = rset[c].IssueId;
          sheet.getCell(`B${row}`).value = rset[c].ClassA;
          sheet.getCell(`C${row}`).value = rset[c].ClassB;
          sheet.getCell(`D${row}`).value = rset[c].ClassC;
          sheet.getCell(`E${row}`).value = rset[c].Title;
          sheet.getCell(`F${row}`).value = rset[c].Body;
          sheet.getCell(`G${row}`).value = rset[c].Manager;
          sheet.getCell(`H${row}`).value = rset[c].Owner;
          let t;
          t = new Date(rset[c].StartTime);
          sheet.getCell(`I${row}`).value = t.getFullYear() + "/" + (t.getMonth()+1) + "/" + t.getDate();
          t = new Date(rset[c].CompletionTime);
          sheet.getCell(`J${row}`).value = t.getFullYear() + "/" + (t.getMonth()+1) + "/" + t.getDate();
          sheet.getCell(`K${row}`).value = rset[c].WorkValue;
          sheet.getCell(`K${row}`).numFmt = '0"h"'
          sheet.getCell(`L${row}`).value = rset[c].ProgressRate;
          sheet.getCell(`L${row}`).numFmt = '0.0"%"'
          sheet.getCell(`M${row}`).value = rset[c].RemainingWorkValue;
          sheet.getCell(`M${row}`).numFmt = '0.0"h"'
          sheet.getCell(`N${row}`).value = rset[c].Status;
          sheet.getCell(`O${row}`).value = rset[c].Ver;
        }
        em.SaveAs(workbook);
    });
  });
}
  
  
function excel02(id) {
  event.stopPropagation();
  const em = new PleasanterExcelMaker();
  em.ExcelDownloadItemAttach([id],'A','wbs_excel02.xlsx')
  .then(function(value){
    workbook = value;
    let data = {"ApiVersion": 1.0, "View": em.getFilter()}
    data.View.ApiDataType = "KeyValues";
    data.View.ApiColumnKeyDisplayType = "ColumnName";
    data.View.GridColumns = ["IssueId","Ver","Title","Body","StartTime","CompletionTime","WorkValue","ProgressRate","RemainingWorkValue","Status","ClassA","ClassB","ClassC","Owner","Manager"];
    em.ApiGet(id, data)
    .then(function(value){
      workbook.worksheets[0].name = "サンプル02";
      let sheet = workbook.worksheets[0];
      const rset = value.data.Response.Data;
      if( Object.keys(rset).length == 1 ) {
          sheet.getCell(`B3`).value = rset[0].IssueId;
          sheet.getCell(`B4`).value = rset[0].ClassA;
          sheet.getCell(`B5`).value = rset[0].ClassB;
          sheet.getCell(`B6`).value = rset[0].ClassC;
          sheet.getCell(`B7`).value = rset[0].Title;
          sheet.getCell(`B8`).value = rset[0].Body;
          sheet.getCell(`B9`).value = rset[0].Manager;
          sheet.getCell(`B10`).value = rset[0].Owner;
          let t;
          t = new Date(rset[0].StartTime);
          sheet.getCell(`B11`).value = t.getFullYear() + "/" + (t.getMonth()+1) + "/" + t.getDate();
          t = new Date(rset[0].CompletionTime);
          sheet.getCell(`B12`).value = t.getFullYear() + "/" + (t.getMonth()+1) + "/" + t.getDate();
          sheet.getCell(`B13`).value = rset[0].WorkValue;
          sheet.getCell(`B13`).numFmt = '0"h"'
          sheet.getCell(`B14`).value = rset[0].ProgressRate;
          sheet.getCell(`B14`).numFmt = '0.0"%"'
          sheet.getCell(`B15`).value = rset[0].RemainingWorkValue;
          sheet.getCell(`B15`).numFmt = '0.0"h"'
          sheet.getCell(`B16`).value = rset[0].Status;
          sheet.getCell(`B17`).value = rset[0].Ver;
        }
        em.SaveAs(workbook);
    });
  });
}
</script>
```

## サンプルコード
```
const em = new PleasanterExcelMaker();
let workbook;
//アイテムID 8936956 に添付している添付ファイルAのファイル名 wbs_excel01.xlsx を取得します。
em.ExcelDownloadItemAttach(8936956,'A','wbs_excel01.xlsx')
.then(function(value){
    workbook = value;
    //Pleasanterの検索条件を取得します。
    let data = {"ApiVersion": 1.0, "View": em.getFilter()}
    //JSONファイルのデータ形式を指定します。
    data.View.ApiDataType = "KeyValues";
    data.View.ApiColumnKeyDisplayType = "ColumnName";
    //取得するフィールドを指定mします。
    data.View.GridColumns = ["IssueId","Ver","Title","Body","StartTime","CompletionTime","WorkValue","ProgressRate","RemainingWorkValue","Status","ClassA","ClassB","ClassC","Owner","Manager"];
    //データを取得します。itemidが0の場合は現在表示しているitemid（$p.id）を取得します。
    em.ApiGet(0, data)
    .then(function(value){
        //ExcelJSのコマンドに依存します。
        //取得したExcel表からSheetを取得します。
        let sheet = workbook.worksheets[0];
        sheet.name = "サンプル01";
        let rset = value.data.Response.Data;
        for( var c=0; c<Object.keys(rset).length; c++) {
            var row = 4+c;
            //セルにデータを書き込みます。
            sheet.getCell(`A${row}`).value = rset[c].IssueId;
            sheet.getCell(`B${row}`).value = rset[c].ClassA;
            sheet.getCell(`C${row}`).value = rset[c].ClassB;
            sheet.getCell(`D${row}`).value = rset[c].ClassC;
            sheet.getCell(`E${row}`).value = rset[c].Title;
            sheet.getCell(`F${row}`).value = rset[c].Body;
            sheet.getCell(`G${row}`).value = rset[c].Manager;
            sheet.getCell(`H${row}`).value = rset[c].Owner;
            let t;
            t = new Date(rset[c].StartTime);
            sheet.getCell(`I${row}`).value = t.getFullYear() + "/" + (t.getMonth()+1) + "/" + t.getDate();
            t = new Date(rset[c].CompletionTime);
            sheet.getCell(`J${row}`).value = t.getFullYear() + "/" + (t.getMonth()+1) + "/" + t.getDate();
            sheet.getCell(`K${row}`).value = rset[c].WorkValue;
            sheet.getCell(`K${row}`).numFmt = '0"h"'
            sheet.getCell(`L${row}`).value = rset[c].ProgressRate;
            sheet.getCell(`L${row}`).numFmt = '0.0"%"'
            sheet.getCell(`M${row}`).value = rset[c].RemainingWorkValue;
            sheet.getCell(`M${row}`).numFmt = '0.0"h"'
            sheet.getCell(`N${row}`).value = rset[c].Status;
            sheet.getCell(`O${row}`).value = rset[c].Ver;
        }
        //Excel表をダウンロードします。
        em.SaveAs(workbook);
    });
});
```

## 最後に
スクリプトに不具合や追加希望があればGithubのIssuesからご連絡ください。