Edited at

Visualforceページを使ったExcelファイル出力時にどうしても越えられないガバナ制限を超えるには

More than 1 year has passed since last update.


概要

Salesforceでアプリを作る場合避けて通れないのがガバナ制限です。マルチテナント(複数組織)でサーバを使っている為に、リソース使用にキャップがかかっているというもの。

様々なアプリケーションを実現するに当たっては、この制限を考慮しなければならないのですが、テスト環境では問題なかったのに本番環境でガバナ制限にぶち当たるという事が往々にしてあります。

きっとそんな時には皆さん「Salesforce ガバナ制限」といった形で検索し

Salesforceガバナ制限を回避するためにやってきたこと

などを引き当てるのです。私も当然そうでした。


一番最後どうしても超えられなかった壁


  • ビューステートサイズの壁

  • CPU time limitの壁

テスト環境程度のデータ量であれば問題なく動くのですが、本番環境のデータ量に耐えられない。完成したと思った矢先に現れる壁に愕然とするはずです。どの程度まで処理を削減すれば良いかの見通しもなかなか立たなかったりしますよね。

今回は、これはもうどうしようもないと諦めるのに2週間くらい格闘してしまった…最終的には処理を分割することで決着しました。


やりたいこと


  • Salesforceに入っているデータを使って、任意のリストデータを作成したい。

  • データは出来ればExcelで複数シートに分けられた形で出力したい


出来たこと

最終的に出力したファイルは44M程度の大きさになっていました。


回避策

今回作るファイルはExcelファイルです。リストはカテゴリー別に別れており、カテゴリーごとにシートを分けています。

ExcelにはXMLファイルを読み込むことが出来るという機能があります。最初からExcel形式で出力しなくても開くことが出来るのです。

XML データのインポート Microsoft

これが非常に便利です。

VisualforceでCSVファイルとExcelファイルを出力するには

こちらの「Open XMLファイル形式に則って記述」という部分です。

Open XML形式概要

<Workbook>

<Worksheet>

<Table>

<Row>

<Cell>

<Data></Data>

</Cell>

</Row>

</Table>

</Worksheet>

</Workbook>



こんな感じです。

XMLファイルで指定すれば、セルの結合や装飾なんかも可能です。思ったとおりのExcelファイルを作ることが出来るでしょう。

今回は、シートごとにデータが出力されるようにしました。つまり、上記で言うところにWorksheet毎に出力を分けています。

ボタンを押すと、必要なデータを落とせるようなVisualforceページが複数開き、自動的にバラバラになったファイルがダウンロードされます。22個くらいのファイルに分割されました。

最終的にはローカルに落ちてきたファイルを全てコマンドでつなげてしまいます。

cat *.xml > output.xml

こうやって完成したxmlファイルをExcelで開き、xlsx形式で保存すれば完成。


結論

リストファイルの出力だったら、処理を分割して、ローカルでファイルを結合するというやり方にすれば、どんなにデータ量が増えてもなんとかなります。(それが適切なファイルサイズで出力されるようにプログラムを作れば良いので)

割り切ったほうが良いですね。


注意点

xmlファイルは厳密に作る必要があります。

シンタックスエラーがあると読み込んだ際にエラーが出ます。そして、何が悪いのかを探すのが結構な手間です。


注意点2

XMLファイルをcatでまとめる際に、ファイル名が重要になります。頭から連番になるように組みましょう。

Visualforceページをダウンロードする場合は

<apex:page controller="コントローラ名" showHeader="false" sidebar="false" readOnly="true" contentType="application/xml#{!xmlNumber}.xml">

こんな感じでXMLの番号{!xmlNumber}をclass側からを渡してやれば、その番号のついたファイルが落ちてきます。

ファイルは、内容量によってダウンロード順が前後しますので、ファイル名を明示してダウンロードするようにしましょう。


驚いたこと

44MのXMLファイルですが、エクセル形式で保存したところ5Mに圧縮されました。どうなってるんでしょうね…(すごい!