SOQLによる検索結果をエクセル出力するVisualForce画面の作り方(出力対象の選択を標準画面で行うやり方付き)

Salesforceでよく要望に上がるのに、かゆいところに手が届かないのがレポート機能。特に、日本のビジネスシーンでは帳票のようなレポートが好んで使われることもあり、せっかくためたデータを、有効に活用するには、レポート機能を充実させたい!という要望は多いようです。

多少不便であってもSalesforceのレポート機能でできることで業務を行っていくことも時には有効ですが、ここでは、比較的簡単に自由なレポートを行える方法をご紹介します。

今回やることの概要

初めに、今回やることを大まかに見てみます。

  • 標準のリストビュー画面で出力対象のレコードを選択し、カスタムで作成したボタンを押す。
  • 選択したレコードの情報をもとに、Apexの中でSOQLを発行し、必要なオブジェクトのリストを生成。
  • 生成したオブジェクトのリストをもとに、VisualForce画面でプレビューさせる。
  • プレビュー画面で「出力」ボタンを押して、エクセルにその内容を出力する。

少し汎用的な作りにするために、対象のレコード選択の画面には標準の画面を利用していますが、完全にVisualForceの画面を出発点にしても良いと思います。エクセルにエクスポートする部分は変わりませんので。

VisualForceでは、画面の「contentType」をエクセルにすると、画面に表示したほぼそのままをエクセル出力できます。

具体的なソース

今回は簡単なサンプルとして、取引先責任者のリストビューでレコードを選んで、カスタムボタンでプレビュー画面に行き、取引先と一緒の一覧を表示することにします。構造を分かりやすくするためにシンプルな構成にしましたが、原理さえわかれば、もっと複雑なSOQLを書いて、様々な情報を取得、加工して出力することもできます。

PageController

初めに、PageControllerクラスを作ります。プレビュー画面もエクセル出力画面も、出力形式が違う以外はやることは同じなので、同じクラスを使いまわせます。

public class ContactListPageController{

    public List selectedContactList{get;set;}
    public List exportObjectList{get;set;}
    List ssId{get;set;}


    public ContactListPageController(ApexPages.StandardSetController controller) {
    
        //選択したレコードを取得
        ssId = (List)controller.getSelected();

        selectedContactList=[SELECT Id, IsDeleted, Name, Email, Title, Account.Name FROM Contact where Id IN :ssId order by Name ];

        system.debug('★SELECT='+ssId);

        exportObjectList= new List();
        ContactMeisaiInfo cInfo;

        for(Contact oneCont : selectedContactList){
            
            cInfo = new ContactMeisaiInfo();
            cInfo.AccountName =oneCont.Account.Name;
            cInfo.ConactId =oneCont.Id;
            cInfo.ConactName =oneCont.Name;            

            exportObjectList.add(cInfo);

        }
    }

    public PageReference exportAction() {
        
        system.debug('★exportAction');
        
        //return null;
        
        return Page.VFPreviewContact_Export;

    }
   
    public PageReference back() {
        String rtnPage= ApexPages.currentPage().getParameters().get('retURL');
        PageReference cancel = new PageReference(rtnPage);
        return cancel;
    }

    public class ContactMeisaiInfo{
    
        public String ConactId {get;set;}
        public String ConactName {get;set;}
        public String AccountName {get;set;}
        
        public ContactMeisaiInfo(){

        }
    
    }
    
}

プレビュー用クラス

次に作るのは、プレビュー用のクラスです。

エクセル出力用クラス

最後に作るのは、エクセル出力用のクラスです。上記のプレビュー画面で「出力」を押すことで「exportAction」が呼ばれることでエクセルに出力されます。charsetは「MS932」または「CP932」を出力すると文字化けが少ないです。(まれに対応していない文字コードが含まれると文字化けします。。。

いい解決方法があれば、ぜひ教えてください。私は、仕方なく対象の文字列をexportAction内などで置換しています。。)

⇒解決しました!こちらの記事「Salesforceのエクセル/CSV出力で文字化けするときは、文字コードをUTF-8にすればよい(BOM付き)」に書きましたので、どうぞ。

カスタムボタンの作成と、リストビューへの表示

材料のソースがそろったところで、取引先責任者の一覧画面に表示するカスタムボタンを作成しましょう。

カスタムボタンまたはカスタムリンクのところから、新規ボタン作成を選びます。「表示の種類」を「リストボタン」にすると、「内容のソース」にVisualForce画面を選べるようになるので、上記で作成したプレビューのVisualForce画面を選びます。

「保存」ボタンを押すとカスタムボタンが作成されますので、それを表示しないといけないですね。表示するには、取引先責任者のオブジェクトのカスタマイズから「検索レイアウト -> 取引先責任者 リストビュー」に行って、上記で作成したカスタムボタンを表示するように選択して「保存」します。