Class GroupedRows<T>

java.lang.Object
io.leandev.appfuse.report.GroupedRows<T>
Type Parameters:
T - 領域資料型別

public final class GroupedRows<T> extends Object

把已排序的領域資料串流轉成帶群組角色的 TableRow 串流

先宣告群組鍵、彙總器與各列的輸出方式,再以 apply(Stream) 套用到每次 render 的資料:

var rows = GroupedRows.<Sale>define(7);
var amount = rows.aggregate(Collectors.summingLong(Sale::amount));
rows.groupBy(Sale::store, store -> List.of("門市:" + store))
    .groupBy(Sale::month)
    .detail(sale -> List.of(sale.orderNo(), ...))
    .footer((group, totals) -> List.of(group.key() + " 小計", money(totals.get(amount))))
    .grandTotal(totals -> List.of("總計", money(totals.get(amount))));

RowSource.lazy(() -> rows.apply(repository.streamSales(query)));

記憶體有界:同時存在的狀態只有「開啟中的各層群組 × 彙總器的累加狀態」與少數待輸出的列,與列數無關; 明細列讀一筆輸出一筆,不保留原始資料。前提是 Collector 的累加狀態有界(加總、計數、最大最小); 會保留元素的 collector(toList()、groupingBy(...))不支援。

排序檢查:同層群組鍵必須遞增;比前一個群組小時丟出 IllegalStateException,因為未排序的輸入會產生錯誤小計。 資料依業務順序而非鍵的自然順序排序時,提供對應的 Comparator:

var storeOrder = List.of("台北信義門市", "新北板橋門市", "台中西屯門市");
rows.groupBy(Sale::store, Comparator.comparingInt(storeOrder::indexOf), store -> List.of("門市:" + store));

各輸出函式回傳每格文字:一格時跨全部欄,否則格數必須等於欄數。

Since:
4.0.0
  • Method Details

    • define

      public static <T> GroupedRows<T> define(int columnCount)
      開始定義
      Type Parameters:
      T - 領域資料型別
      Parameters:
      columnCount - 表格欄數
      Returns:
      定義
    • aggregate

      public <R> GroupedRows.Aggregate<R> aggregate(Collector<? super T, ?, R> collector)
      註冊彙總器;彙總同時套用到每層群組與總計
      Type Parameters:
      R - 彙總結果型別
      Parameters:
      collector - 累加狀態有界的 collector
      Returns:
      讀取彙總結果用的 handle
    • groupBy

      public <K extends Comparable<? super K>> GroupedRows<T> groupBy(Function<? super T, ? extends K> key)
      新增一層群組,以鍵的自然順序排序,群組標題為鍵的文字
    • groupBy

      public <K extends Comparable<? super K>> GroupedRows<T> groupBy(Function<? super T, ? extends K> key, Function<? super K, List<String>> header)
      新增一層群組,以鍵的自然順序排序
    • groupBy

      public <K> GroupedRows<T> groupBy(Function<? super T, ? extends K> key, Comparator<? super K> order, Function<? super K, List<String>> header)
      新增一層群組
      Type Parameters:
      K - 鍵型別
      Parameters:
      key - 群組鍵
      order - 鍵的順序;輸入必須依此遞增
      header - 群組標題列的各格文字
      Returns:
      本定義
    • detail

      public GroupedRows<T> detail(Function<? super T, List<String>> cells)
      明細列的各格文字;未設定時不輸出明細列
    • footer

      群組小計列的各格文字;每層群組結束時呼叫,未設定時不輸出小計列
    • grandTotal

      public GroupedRows<T> grandTotal(Function<GroupedRows.Totals, List<String>> cells)
      總計列的各格文字;未設定時不輸出總計列
    • apply

      public Stream<TableRow> apply(Stream<T> source)

      套用到一次 render 的資料;關閉回傳的串流時一併關閉 source

      建立過程失敗(例如 collector 的 supplier 丟出例外)時,先關閉 source 再傳出例外。

      Parameters:
      source - 依群組鍵排序的資料
      Returns:
      表格列串流