/**
  * エクスポーターを追加する。
  *
  * @param exporter 追加するエクスポーター
  */
 public void addReportBookExporter(ReportBookExporter exporter) {
   exporters.put(exporter.getFormatType(), exporter);
 }
  /**
   * ワークブックの変換処理を実行する。
   *
   * @param reportBook ワークブックの置換情報
   */
  private void processBook(ReportBook reportBook) {

    if (reportBook == null) {
      return;
    }

    Workbook workbook = getTemplateWorkbook(reportBook.getInputStream());

    for (ReportProcessListener listener : listeners) {
      listener.preBookParse(workbook, reportBook);
    }

    checkReportBook(reportBook);

    // テンプレート展開
    Set<Integer> delTemplateIndexs = expandTemplate(workbook, reportBook);

    // 出力ファイル取得
    BookController controller = new BookController(workbook);

    // Parserの設定
    for (ReportsTagParser<?> tagParser : parsers.values()) {
      controller.addTagParser(tagParser);
    }
    // リスナーの設定
    controller.addSheetParseListener(new RemoveAdapter());
    for (ReportProcessListener listener : listeners) {
      controller.addSheetParseListener(listener);
    }

    // Exporterの設定
    for (ConvertConfiguration configuration : reportBook.getConfigurations()) {
      if (configuration == null) {
        continue;
      }
      for (ReportBookExporter reportExporter : exporters.values()) {
        if (configuration.getFormatType().equals(reportExporter.getFormatType())) {
          reportExporter.setConfiguration(configuration);
          reportExporter.setOutputStream(reportBook.getOutputStream());
          controller.addBookExporter(reportExporter);
        }
      }
    }

    ReportsParserInfo reportsParserInfo = new ReportsParserInfo();
    reportsParserInfo.setReportParsers(new ArrayList<ReportsTagParser<?>>(parsers.values()));
    reportsParserInfo.setReportBook(reportBook);

    BookData bookData = controller.getBookData();
    bookData.clear();
    for (String sheetName : controller.getSheetNames()) {
      if (sheetName.startsWith(BookController.COMMENT_PREFIX)) {
        continue;
      }
      ReportSheet reportSheet = ReportsUtil.getReportSheet(sheetName, reportBook);
      if (reportSheet != null) {

        reportsParserInfo.setParamInfo(reportSheet.getParamInfo());
        // 解析の実行
        SheetData sheetData = controller.parseSheet(sheetName, reportsParserInfo);
        // 結果の追加
        controller.getBookData().putSheetData(sheetName, sheetData);
      }
    }

    // 不要テンプレート削除
    for (Integer deleteSheetIndex : delTemplateIndexs) {
      workbook.removeSheetAt(deleteSheetIndex);
    }

    // 出力処理前にリスナー呼び出し
    for (ReportProcessListener listener : listeners) {
      listener.postBookParse(workbook, reportBook);
    }

    // 出力処理の実行
    for (BookExporter exporter : controller.getExporter()) {
      if (exporter != null) {
        exporter.setup();
        try {
          exporter.export(workbook, bookData);
        } finally {
          exporter.tearDown();
        }
      }
    }
  }