YellowfinのWebサービスでPDFやExcelファイルを出力する


YellowfinにはPDFやExcel、CSVといったファイル形式でレポートを出力する機能が備わっていますが、実はWebサービス経由で外部から実行することもできます。
これを使えば、Yellowfinのファイル出力機能のみを別システムに組み込むことも可能です。

# いきなりコードから

例えばPDFを出力する最もシンプルな例は以下のとおりです。

```jsp:sample1.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*, java.text.*" %>
<%@ page import="com.hof.mi.web.service.*" %>
<%
  String host = "localhost";
  Integer port = 8080;
  String userid = "admin@yellowfin.com.au";
  String password = "test";
  String path = "/services/ReportService";
  String uuid = "80162f66-b23e-4a2b-b209-497a960d96d5";
  String format = "PDF";
  String contentType = "application/pdf";

  ReportServiceClient rsc = new ReportServiceClient(host, port, userid, password, path);

  i4Report report = rsc.loadReportForUser(uuid, userid, password, orgid);

  HashMap elementStorage = new HashMap();
  report.run(elementStorage, format);

  response.setContentType(contentType);
  java.io.BufferedOutputStream o = new java.io.BufferedOutputStream(response.getOutputStream(), 32000);
  o.write(report.renderBinary());
  o.flush();
%>
```

上記の例はYellowfinから提供されているクライアントライブラリを使っている前提です。なお、クライアントライブラリってなんぞ？という方は [以前の記事](http://qiita.com/hadatuna/items/e766c3390ccf65d6fec2) をご覧ください。

やっていることは見ればわかるでしょうから詳細は割愛します。
ポートやUUIDなんかはご自身の環境に合わせて適宜修正してください。

# PDF以外のファイル形式にするには

言わずもがなですが、ファイル形式を変えたいときは *format* と *contentType* を書き換えればOKです。例えばCSVであれば以下のように。

```jsp:
String format = "CSV";
String contentType = "text/comma-separated-values";
```

# フィルターを使いたいんだけど

ご安心ください。もちろんフィルターも使えます。
レポートをloadしてから、runするまでの間に *setFilter* すればOKです。

```jsp:
i4Report report = rsc.loadReportForUser(uuid, userid, password, orgid);

String key = "Region"; //フィルター項目の名称
String value = "アジア"; //条件にする値
report.setFilter(key, value);

HashMap elementStorage = new HashMap();
report.run(elementStorage, format);

```

# URLのパラメータで条件を渡せるようにしてみる

あまりスマートなやり方ではありませんが、まあそんなことも当然できます。

```jsp:sample2.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*, java.text.*" %>
<%@ page import="com.hof.mi.web.service.*" %>
<%
  String host = "localhost";
  Integer port = 8080;
  String userid = "admin@yellowfin.com.au";
  String password = "test";
  String orgid = "";
  String uuid = "f894a22c-373d-45b9-b7c0-922e70f0697d";
  String path = "/services/ReportService";

  String format = request.getParameter("format");
  String contentType = "application/octet-stream";
  if (format == null) format = "PDF";
  if (format.equals("CSV")) contentType = "text/comma-separated-values";
  else if (format.equals("PDF")) contentType = "application/pdf";
  else if (format.equals("XLS")) contentType = "application/vnd.ms-excel";
  else if (format.equals("XLSX")) contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  else if (format.equals("RTF")) contentType = "application/rtf";
  else if (format.equals("TEXT")) contentType = "text/tab-separated-values";

  HashMap filters = new HashMap();
  boolean cleared = filters.size() == 0;
  Iterator f = request.getParameterMap().keySet().iterator();
  while (f.hasNext()) {
    String key = (String) f.next();
    if (key.startsWith("filter")) {
      if (!cleared) {
        filters.clear();
        cleared = true;
      }
      String value = request.getParameter(key);
      int pipeIndex = value.indexOf("|");
      if (pipeIndex == -1) continue;
      key = value.substring(0, pipeIndex);
      value = value.substring(pipeIndex + 1);
      filters.put(key, value);
    }
  }

  ReportServiceClient rsc = new ReportServiceClient(host, port, userid, password, path);
  i4Report report = rsc.loadReportForUser(uuid, userid, password, orgid);

  f = filters.keySet().iterator();
  while (f.hasNext()) {
    String key = (String) f.next();
    String value = (String) filters.get(key);
    report.setFilter(key, value);
  }

  HashMap elementStorage = new HashMap();
  report.run(elementStorage, format);

  response.setContentType(contentType);
  java.io.BufferedOutputStream o = new java.io.BufferedOutputStream(response.getOutputStream(), 32000);
  o.write(report.renderBinary());
  o.flush();
%>
```

上記の例では *sample2.jsp?format=PDF&filter1=Region|Asia&filter2=Age|20* のような形でファイル形式やフィルター条件を渡すことができます。

# できあがり

条件入力するフォームを作って、サンプルのJSPへパラメータを渡すとこうなります。

![output_pdf.gif](https://qiita-image-store.s3.amazonaws.com/0/116818/5835912e-7805-9778-aee8-cd0141ae2ed2.gif "output_pdf.gif")


# もっと詳しく知りたいときは

*[Yellowfinのインストールディレクトリ]/development* にWebサービスのドキュメントとサンプルがあります。

- ドキュメント： *development/doc*
- サンプル： *development/examples*

特に今回やった内容に関しては *examples/webservices* にある *ws_report_interface.jsp* が参考になります。