123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- import 'package:flyinsonolite/consultation/reports/reportinfo/input_text_info.dart';
- import 'package:flyinsonolite/consultation/reports/reportinfo/rt_cell_info.dart';
- import 'package:flyinsonolite/consultation/reports/reportinfo/rt_table_info.dart';
- import 'package:flyinsonolite/consultation/reports/reporttemplate/cell_postion.dart';
- import 'package:flyinsonolite/consultation/reports/reporttemplate/input_text.dart';
- import 'package:flyinsonolite/consultation/reports/reporttemplate/interfaces/cell.dart';
- import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_Cell.dart';
- import 'package:flyinsonolite/consultation/reports/reporttemplate/rt_table.dart';
- /// 表格数据过滤器
- class TableDataHelper {
- /// 数据过滤器,过滤空数据
- static RTTableInfo removeEmptyCells(RTTableInfo rtTableInfo) {
- RTTableInfo newRtTableInfo = rtTableInfo.clone();
- if (newRtTableInfo.cells == null) {
- return newRtTableInfo;
- }
- int tableWidth = newRtTableInfo.columnDefinitions!.length;
- Map<CellPostion, RTCellInfo> newCells = {};
- Map<CellPostion, ICell> newElementCells = {};
- Map<String, GroupFieldArgs> groupFieldMap = {};
- /// 遍历 cells 输出
- for (MapEntry<CellPostion, RTCellInfo> cell
- in newRtTableInfo.cells!.entries) {
- RTCellInfo cellInfo = cell.value;
- CellPostion cellPostion = cell.key;
- RTCell cellElement = cellInfo.element as RTCell;
- if (cellElement.groupField == null || cellElement.groupField!.isEmpty) {
- continue;
- } else {
- if (groupFieldMap[cellElement.groupField!] != null) {
- groupFieldMap[cellElement.groupField!]!
- .addSize(cellPostion.columnSpan!);
- groupFieldMap[cellElement.groupField!]!
- .addCell(cellPostion, cellInfo);
- } else {
- groupFieldMap[cellElement.groupField!] =
- GroupFieldArgs(cellPostion.columnSpan!, {cellPostion: cellInfo});
- }
- }
- }
- if (groupFieldMap.isEmpty) {
- return newRtTableInfo;
- }
- /// 是否为特殊模式
- final isSpecialMode = _isSpecialMode(groupFieldMap);
- /// 带有输入框的分组字段
- List<String> inputGroupFieldList = [];
- /// 带有值的分组字段
- List<String> valueGroupFieldList = [];
- /// 再次遍历 cells,存在空值就移除对应 map
- for (MapEntry<CellPostion, RTCellInfo> cell
- in newRtTableInfo.cells!.entries) {
- RTCellInfo cellInfo = cell.value;
- RTCell cellElement = cellInfo.element as RTCell;
- if (cellInfo.blocks == null || cellInfo.blocks!.isEmpty) {
- continue;
- }
- if (cellInfo.blocks![0].elementInfos == null ||
- cellInfo.blocks![0].elementInfos!.isEmpty) {
- continue;
- }
- if (cellInfo.blocks![0].elementInfos![0] is InputTextInfo) {
- InputTextInfo inputText =
- cellInfo.blocks![0].elementInfos![0] as InputTextInfo;
- if (!inputGroupFieldList.contains(cellElement.groupField!)) {
- inputGroupFieldList.add(cellElement.groupField!);
- }
- if (inputText.text.isNotEmpty) {
- if (!valueGroupFieldList.contains(cellElement.groupField!)) {
- // 如果是特殊模式的函数字段,需要判断内容是否正确【函数字段的宽度为 2 ,使用宽度来判断】
- if (isSpecialMode && cell.key.columnSpan == 2) {
- // 如果函数值无前缀,则删除 valueGroupFieldList 中的该字段
- int firstIndex = inputText.text.indexOf('[');
- int lastIndex = inputText.text.lastIndexOf(']');
- if (firstIndex < lastIndex && firstIndex > 0) {
- valueGroupFieldList.add(cellElement.groupField!);
- }
- } else {
- // 非特殊模式,直接添加
- valueGroupFieldList.add(cellElement.groupField!);
- }
- }
- }
- }
- }
- // 无任何输入,直接返回空
- if (valueGroupFieldList.isEmpty) {
- newRtTableInfo.cells = null;
- return newRtTableInfo;
- }
- /// inputGroupFieldMap 和 valueGroupFieldMap 取差集
- List<String> emptyGroupFieldList = [];
- for (String inputGroupField in inputGroupFieldList) {
- if (!valueGroupFieldList.contains(inputGroupField)) {
- emptyGroupFieldList.add(inputGroupField);
- }
- }
- /// 如果是特殊模式,需要特殊对齐处理,此时记录左上角单元格 LeftTopPos,还需要将函数字段的空值也移除
- int specialGroupsTopPos = -1;
- int specialGroupsLeftPos = -1;
- if (isSpecialMode) {
- for (GroupFieldArgs groupField in groupFieldMap.values) {
- if (groupField.cellsCount == 1) {
- continue;
- }
- if (specialGroupsTopPos == -1 ||
- groupField.topPos < specialGroupsTopPos) {
- specialGroupsTopPos = groupField.topPos;
- }
- if (specialGroupsLeftPos == -1 ||
- groupField.leftPos < specialGroupsLeftPos) {
- specialGroupsLeftPos = groupField.leftPos;
- }
- }
- }
- /// 遍历 emptyGroupFieldList,移除对应的 map
- for (String emptyGroupField in emptyGroupFieldList) {
- if (groupFieldMap[emptyGroupField] != null) {
- groupFieldMap.remove(emptyGroupField);
- }
- }
- for (MapEntry<CellPostion, RTCellInfo> cell
- in newRtTableInfo.cells!.entries) {
- RTCellInfo cellInfo = cell.value;
- RTCell cellElement = cellInfo.element as RTCell;
- if (cellElement.groupField == null || cellElement.groupField!.isEmpty) {
- newCells.addEntries([cell]);
- } else if (groupFieldMap.keys.contains(cellElement.groupField!)) {
- newCells.addEntries([cell]);
- }
- }
- for (MapEntry<CellPostion, ICell> cell
- in (newRtTableInfo.element as RTTable).cells!.entries) {
- ICell cellInfo = cell.value;
- if (cellInfo.groupField == null || cellInfo.groupField!.isEmpty) {
- newElementCells.addEntries([cell]);
- } else if (groupFieldMap.keys.contains(cellInfo.groupField!)) {
- newElementCells.addEntries([cell]);
- }
- }
- /// 移除尾部空格,然后重排序
- removeTailEmptyCells(newCells);
- if (isSpecialMode) {
- newRtTableInfo.cells = specialSortCells(
- newCells, groupFieldMap, specialGroupsLeftPos, specialGroupsTopPos);
- } else {
- newRtTableInfo.cells = sortCells(newCells, groupFieldMap, tableWidth);
- }
- (newRtTableInfo.element as RTTable).cells = newElementCells;
- return newRtTableInfo;
- }
- /// 重排序
- static Map<CellPostion, RTCellInfo> sortCells(
- Map<CellPostion, RTCellInfo> cells,
- Map<String, GroupFieldArgs> groupFieldMap,
- int tableWidth) {
- Map<CellPostion, RTCellInfo> newCells = {};
- MapEntry<CellPostion, RTCellInfo>? headGrid;
- int currTop = 0;
- int currLeft = 0;
- int availableWidth = tableWidth;
- // int lastCellHeight = 1;
- CellPostion previousGridPos = CellPostion();
- while ((headGrid = _getFirstGrid(cells)) != null) {
- CellPostion headGridPos = headGrid!.key;
- RTCell cellElement = headGrid.value.element as RTCell;
- int groupFieldWidth = groupFieldMap[cellElement.groupField!] == null
- ? headGridPos.columnSpan!
- : groupFieldMap[cellElement.groupField!]!.size;
- if (cellElement.blocks != null &&
- cellElement.blocks!.isNotEmpty &&
- cellElement.blocks![0].elements!.isNotEmpty &&
- cellElement.blocks![0].elements![0] is InputText) {
- groupFieldWidth = headGridPos.columnSpan!;
- }
- if (groupFieldWidth > availableWidth) {
- /// 换行前需要补全剩余空间
- if (availableWidth > 0) {
- Map<CellPostion, RTCellInfo> lostCells = _getEmptyCells(
- currTop, currLeft, previousGridPos.rowSpan!, availableWidth);
- newCells.addAll(lostCells);
- }
- currTop += previousGridPos.rowSpan!;
- currLeft = 0;
- availableWidth = tableWidth;
- }
- CellPostion newGridPos = CellPostion();
- newGridPos.row = currTop;
- newGridPos.column = currLeft;
- newGridPos.rowSpan = headGridPos.rowSpan;
- newGridPos.columnSpan = headGridPos.columnSpan;
- currLeft += newGridPos.columnSpan!;
- availableWidth -= newGridPos.columnSpan!;
- /// 如果追加的后一格高于前一格,需要补齐前一格下方空缺
- if (newGridPos.column! > 0 &&
- newGridPos.rowSpan! > previousGridPos.rowSpan!) {
- // print("如果追加的后一格高于前一格,需要补齐前一格下方空缺 ++++");
- newCells.addAll(_getLostCell(previousGridPos, newGridPos.rowSpan!));
- }
- /// 如果追加的后一格低于前一格,需要补齐后一格下方空缺
- if (newGridPos.column! > 0 &&
- newGridPos.rowSpan! < previousGridPos.rowSpan!) {
- // print("如果追加的后一格低于前一格,需要补齐后一格下方空缺");
- newCells.addAll(_getLostCell(newGridPos, previousGridPos.rowSpan!));
- }
- previousGridPos = newGridPos;
- newCells.addAll({newGridPos: headGrid.value});
- }
- if (availableWidth > 0) {
- Map<CellPostion, RTCellInfo> lostCells = _getEmptyCells(
- currTop, currLeft, previousGridPos.rowSpan!, availableWidth);
- newCells.addAll(lostCells);
- }
- return newCells;
- }
- /// 特殊模式重排序
- static Map<CellPostion, RTCellInfo> specialSortCells(
- Map<CellPostion, RTCellInfo> cells,
- Map<String, GroupFieldArgs> groupFieldMap,
- int groupStartPosX,
- int groupStartPosY,
- ) {
- Map<CellPostion, RTCellInfo> newCells = {};
- List<String> titleGroupFieldList = [];
- for (MapEntry<String, GroupFieldArgs> group in groupFieldMap.entries) {
- if (group.value.cellsCount == 1) {
- newCells.addAll(group.value.cells);
- group.value.cells.forEach((key, value) {
- cells.remove(key);
- });
- titleGroupFieldList.add(group.key);
- }
- }
- groupFieldMap
- .removeWhere((key, value) => titleGroupFieldList.contains(key));
- /// 按左上优先的顺序写入 groups
- MapEntry<String, GroupFieldArgs>? headGroupField =
- _getFirstGroupField(groupFieldMap);
- int layoutX = groupStartPosX;
- int layoutY = groupStartPosY;
- while (headGroupField != null) {
- GroupFieldArgs groupArgs = headGroupField.value;
- Map<CellPostion, RTCellInfo> groupCells = groupArgs.cells;
- List<CellPostion> originPosList = groupCells.keys.toList();
- originPosList.sort((a, b) {
- if (a.row! == b.row!) {
- return a.column!.compareTo(b.column!);
- } else {
- return a.row!.compareTo(b.row!);
- }
- });
- if (originPosList.length == 3) {
- // 处理第一个格
- CellPostion firstCellPos = originPosList[0];
- firstCellPos.row = layoutY;
- firstCellPos.column = layoutX;
- newCells.addAll({firstCellPos: groupCells[originPosList[0]]!});
- // 处理第二个格
- CellPostion secondCellPos = originPosList[1];
- secondCellPos.row = layoutY;
- secondCellPos.column = layoutX + 1;
- newCells.addAll({secondCellPos: groupCells[originPosList[1]]!});
- // 处理第三个格
- CellPostion thirdCellPos = originPosList[2];
- thirdCellPos.row = layoutY + 1;
- thirdCellPos.column = layoutX;
- newCells.addAll({thirdCellPos: groupCells[originPosList[2]]!});
- layoutX += 2;
- if (layoutX >= 4) {
- layoutX = 0;
- layoutY += 2;
- }
- }
- cells.removeWhere((key, value) => originPosList.contains(key));
- groupFieldMap.remove(headGroupField.key);
- headGroupField = _getFirstGroupField(groupFieldMap);
- }
- if (layoutX != 0) {
- Map<CellPostion, RTCellInfo> lostCells =
- _getEmptyCells(layoutY, layoutX, 2, 2);
- newCells.addAll(lostCells);
- }
- return newCells;
- }
- /// 移除尾部的占位格
- static removeTailEmptyCells(Map<CellPostion, RTCellInfo> cells) {
- MapEntry<CellPostion, RTCellInfo>? lastGrid = _getLastGrid(cells);
- while (lastGrid != null && lastGrid.value.blocks != null) {
- if (lastGrid.value.blocks![0].elementInfos!.isEmpty) {
- cells.remove(lastGrid.key);
- lastGrid = _getLastGrid(cells);
- } else {
- break;
- }
- }
- }
- /// 获取补缺口的单元格
- static Map<CellPostion, RTCellInfo> _getLostCell(
- CellPostion gridPos, int maxHeight) {
- Map<CellPostion, RTCellInfo> lostCells = _getEmptyCells(
- gridPos.row! + gridPos.rowSpan!,
- 0,
- maxHeight - gridPos.rowSpan!,
- gridPos.column! + gridPos.columnSpan!);
- return lostCells;
- }
- static Map<CellPostion, RTCellInfo> _getEmptyCells(
- int startRow, int startColumn, int rowSpan, int columnSpan) {
- // 根据传入位置及尺寸,生成 1x1 的空单元格,返回
- Map<CellPostion, RTCellInfo> emptyCells = {};
- for (int i = 0; i < rowSpan; i++) {
- for (int j = 0; j < columnSpan; j++) {
- CellPostion newGridPos = CellPostion();
- RTCell emptyICell = RTCell.fromJson(_emptyCellJson);
- RTCellInfo emptyCell = RTCellInfo.fromElement(emptyICell);
- newGridPos.rowSpan = 1;
- newGridPos.columnSpan = 1;
- newGridPos.row = startRow + i;
- newGridPos.column = startColumn + j;
- emptyCells.addAll({newGridPos: emptyCell});
- }
- }
- return emptyCells;
- }
- /// 遍历 cells 找出最左上角的单元格
- static MapEntry<CellPostion, RTCellInfo>? _getFirstGrid(
- Map<CellPostion, RTCellInfo> cells) {
- if (cells.isEmpty) return null;
- MapEntry<CellPostion, RTCellInfo> headGrid = cells.entries.first;
- for (MapEntry<CellPostion, RTCellInfo> cell in cells.entries) {
- if (cell.key.row! < headGrid.key.row!) {
- headGrid = cell;
- } else if (cell.key.row! == headGrid.key.row!) {
- if (cell.key.column! < headGrid.key.column!) {
- headGrid = cell;
- }
- }
- }
- cells.removeWhere((key, value) => key == headGrid.key);
- return headGrid;
- }
- /// 遍历 cells 找出最右下的单元格
- static MapEntry<CellPostion, RTCellInfo>? _getLastGrid(
- Map<CellPostion, RTCellInfo> cells) {
- if (cells.isEmpty) return null;
- MapEntry<CellPostion, RTCellInfo> tailGrid = cells.entries.first;
- for (MapEntry<CellPostion, RTCellInfo> cell in cells.entries) {
- if (cell.key.row! + cell.key.rowSpan! >
- tailGrid.key.row! + tailGrid.key.rowSpan!) {
- tailGrid = cell;
- } else if (cell.key.row! + cell.key.rowSpan! ==
- tailGrid.key.row! + tailGrid.key.rowSpan!) {
- if (cell.key.column! + cell.key.columnSpan! >
- tailGrid.key.column! + tailGrid.key.columnSpan!) {
- tailGrid = cell;
- }
- }
- }
- return tailGrid;
- }
- /// 遍历 groupFields 找出最左上角的 groupField
- static MapEntry<String, GroupFieldArgs>? _getFirstGroupField(
- Map<String, GroupFieldArgs> groupFields) {
- if (groupFields.isEmpty) return null;
- MapEntry<String, GroupFieldArgs> headGroupField = groupFields.entries.first;
- for (MapEntry<String, GroupFieldArgs> groupField in groupFields.entries) {
- if (groupField.value.topPos < headGroupField.value.topPos) {
- headGroupField = groupField;
- } else if (groupField.value.topPos == headGroupField.value.topPos) {
- if (groupField.value.leftPos < headGroupField.value.leftPos) {
- headGroupField = groupField;
- }
- }
- }
- return headGroupField;
- }
- static final Map<String, dynamic> _emptyCellJson = {
- "Blocks": [],
- "Background": {
- "RGB": "rgb(255,255,255)",
- "R": 255,
- "G": 255,
- "B": 255,
- "A": 255
- },
- "WidthType": "FixedValue",
- "HeightType": "MinValue",
- "Borders": {
- "Left": {
- "BorderStyle": "Solid",
- "Color": {"RGB": "rgb(0,0,0)", "R": 0, "G": 0, "B": 0, "A": 255},
- "Thickness": 1
- },
- "Top": {
- "BorderStyle": "Solid",
- "Color": {"RGB": "rgb(0,0,0)", "R": 0, "G": 0, "B": 0, "A": 255},
- "Thickness": 1
- },
- "Right": {
- "BorderStyle": "Solid",
- "Color": {"RGB": "rgb(0,0,0)", "R": 0, "G": 0, "B": 0, "A": 255},
- "Thickness": 1
- },
- "Bottom": {
- "BorderStyle": "Solid",
- "Color": {"RGB": "rgb(0,0,0)", "R": 0, "G": 0, "B": 0, "A": 255},
- "Thickness": 1
- }
- },
- "GroupField": "",
- "HorizontalAlignment": "Left",
- "VerticalAlignment": "Center",
- "Margin": {"Left": 0, "Top": 0, "Right": 0, "Bottom": 0},
- "ElementType": {"Name": "RTCell"}
- };
- /// 是否是特殊模式,形如:
- /// |--------------------|
- /// | | |
- /// |--------------------|
- /// | |
- /// |--------------------|
- /// TODO 该模式的匹配还需要细化
- static bool _isSpecialMode(Map<String, GroupFieldArgs> groupFieldMap) {
- // 如果所有的 groupFieldMap 的值都是 4,那么就是特殊模式
- for (GroupFieldArgs value in groupFieldMap.values) {
- if (value.cellsCount == 1) {
- continue;
- }
- if (value.size != 4 || value.cellsCount != 3) {
- return false;
- }
- }
- return true;
- }
- }
- class GroupFieldArgs {
- int size;
- Map<CellPostion, RTCellInfo> cells = {};
- int topPos = -1;
- int leftPos = -1;
- GroupFieldArgs(this.size, this.cells) {
- for (MapEntry<CellPostion, RTCellInfo> cell in cells.entries) {
- CellPostion pos = cell.key;
- if (topPos == -1 || pos.row! < topPos) {
- topPos = pos.row!;
- }
- if (leftPos == -1 || pos.column! < leftPos) {
- leftPos = pos.column!;
- }
- }
- }
- get cellsCount => cells.length;
- addSize(int add) {
- size += add;
- }
- addCell(CellPostion cellPos, RTCellInfo cellInfo) {
- cells.addAll({cellPos: cellInfo});
- if (topPos == -1 || cellPos.row! < topPos) {
- topPos = cellPos.row!;
- }
- if (leftPos == -1 || cellPos.column! < leftPos) {
- leftPos = cellPos.column!;
- }
- }
- }
|