LoginSignup
0
0

[MUI X Data Grid v6] で画像をセルに埋め込む / フィルタ後のデータにも適用する

Posted at

画像をセルに埋め込む

Excel export
This feature relies on exceljs. The Excel export allows translating columns' type and tree structure of a DataGrid to an Excel file.

Customizing the document
You can customize the document using two callback functions:
exceljsPreProcess called before adding the rows' dataset.
exceljsPostProcess called after the dataset has been exported to the document.
Both functions receive { workbook, worksheet } as input. They are exceljs objects and allow you to directly manipulate the Excel file.

exceljsPostProcess

GridToolbarExportexceljsPostProcessを渡してエクセルの出力をexceljsを使って制御する。

  1. まずworkbookaddImageで画像を追加する
  2. 次にworksheetaddImageでセルに画像を埋め込む
CustomToolbar.tsx
const rows = ... // data gridで表示しているデータ

<GridToolbarExport
excelOptions={{
  fileName: "export-filename",
  exceljsPreProcess: ({ workbook, worksheet }: ExcelJsProcessProps) => {

    rows.forEach((row, index) => {
      const base64 = ...

      const imageId = workbook.addImage({
        base64, // https://github.com/exceljs/exceljs?tab=readme-ov-file#add-image-to-workbook
        extension: "jpeg",
      })
    
      worksheet.addImage(
        imageId,
        `A${index + 1}:A${index + 1}`
      )
    })
  },
}}

フィルタ後のデータにも適用する

例えばData Gridに10行あったとして、フィルタの使用で3行に絞り込んでいる状態からexcelを出力しようとしたとする。この場合、Data Gridでフィルタ後の表示されている行だけで画像の埋め込みを行わなければいけない。
が、exceljsPreProcessでは絞り込み後のデータは受け取れないので自分でなんとかするしか無い。

ListPage.tsx
<DataGridPremium
  onStateChange={(params) => {
    const ids = Object.entries(params.filter.filteredRowsLookup)
      .filter(([_, shown]) => shown)
      .map(([id, _]) => id)

    sessionStorage.setItem("excel.export.ids", JSON.stringify(ids))
  }}
/>

まずはこのようにしてsessionStorageに表示されている行のIDを一時保存しておく。

CustomToolbar.tsx
const ids = JSON.parse(sessionStorage.getItem("excel.export.ids"))
const rows = ... // data gridで表示しているデータ
const filteredRows = rows.filter((row) => ids.includes(row.id.toString()))

// 以下は同じ

ポイントはDataGridPremiumのonStateChangesessionStorageを使う所。

  • React.useStateに入れようとすると無限にre-renderを繰り返してエラーになる
  • React.useRefだとうまくToolbarコンポーネントに渡せない

sessionStorageならブラウザを閉じれば消えるし、re-renderなどの副作用もない。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0