You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
270 lines
10 KiB
270 lines
10 KiB
3 years ago
|
package com.fr.plugin.mail.fold;
|
||
|
|
||
|
import com.fr.base.DynamicUnitList;
|
||
|
import com.fr.cache.list.IntList;
|
||
|
import com.fr.form.ui.Widget;
|
||
|
import com.fr.main.workbook.ResultWorkBook;
|
||
|
import com.fr.report.ReportHelper;
|
||
|
import com.fr.report.cell.ResultCellElement;
|
||
|
import com.fr.report.cell.WidgetAttrElem;
|
||
|
import com.fr.report.elementcase.ElementCase;
|
||
|
import com.fr.report.report.Report;
|
||
|
import com.fr.report.web.button.form.TreeNodeToggleButton;
|
||
|
import com.fr.report.worksheet.AnalysisRWorkSheet;
|
||
|
import com.fr.script.Calculator;
|
||
|
import com.fr.stable.ViewActor;
|
||
|
import com.fr.stable.script.CalculatorProvider;
|
||
|
import com.fr.stable.web.SessionProvider;
|
||
|
import com.fr.third.v2.org.apache.poi.ss.usermodel.Sheet;
|
||
|
import com.fr.third.v2.org.apache.poi.ss.usermodel.Workbook;
|
||
|
import com.fr.third.v2.org.apache.poi.xssf.usermodel.XSSFRow;
|
||
|
import com.fr.web.core.ReportSessionIDInfor;
|
||
|
import com.fr.web.core.TreeHTMLWriter;
|
||
|
import com.fr.web.core.reportcase.WebElementReportCase;
|
||
|
import com.fr.web.output.html.chwriter.ViewCellWriter;
|
||
|
import com.fr.web.request.EmptyRepository;
|
||
|
|
||
|
import java.io.ByteArrayInputStream;
|
||
|
import java.io.ByteArrayOutputStream;
|
||
|
import java.io.OutputStream;
|
||
|
import java.util.*;
|
||
|
|
||
|
/**
|
||
|
* @author fr.open
|
||
|
* @date 2019/6/4
|
||
|
*/
|
||
|
public class ExportUtil {
|
||
|
|
||
|
public static void FoldTree(ResultWorkBook book, Workbook workbook, int i, ReportSessionIDInfor sessionProvider) throws CloneNotSupportedException {
|
||
|
book = sessionProvider.getWorkBookDefine().execute(book.getExecuteParameters(), new ViewActor());
|
||
|
SessionRepository sessionRepository = new SessionRepository().buildSession(sessionProvider);
|
||
|
Sheet poiSheet = workbook.getSheetAt(i);
|
||
|
if (book.getReport(i) instanceof AnalysisRWorkSheet) {
|
||
|
AnalysisRWorkSheet sheet = (AnalysisRWorkSheet) book.getReport(i);
|
||
|
Calculator c = Calculator.createCalculator();
|
||
|
c.setAttribute(Report.KEY, sheet);
|
||
|
TreeHTMLWriter htmlWriter = new TreeHTMLWriter();
|
||
|
ViewCellWriter cellHtmlWriter = new ViewCellWriter(sessionRepository, i, sheet.getReportSettings(), true);
|
||
|
htmlWriter.writeReportToHtml(new WebElementReportCase(sheet, sessionRepository), i, cellHtmlWriter, new EmptyRepository(), "");
|
||
|
cellHtmlWriter.dealWithAllTreeNodeRelation(c);
|
||
|
DynamicUnitList rowHeightList = (DynamicUnitList) ReportHelper.getRowHeightList((ElementCase) book.getReport(i)).clone();
|
||
|
List<Integer> spanList = new ArrayList();
|
||
|
for (int j = 0; j < rowHeightList.size(); j++) {
|
||
|
if (rowHeightList.get(j).equal_zero()) {
|
||
|
spanList.add(j);
|
||
|
}
|
||
|
}
|
||
|
Map<Integer, TreeNode> map = ExportUtil.generateNodeTree(sheet, spanList);
|
||
|
Map<Integer, TreeNode> map1 = ExportUtil.generateNodeTree(sheet, new ArrayList());
|
||
|
if (!map.isEmpty()) {
|
||
|
Iterator<Integer> it = map.keySet().iterator();
|
||
|
while (it.hasNext()) {
|
||
|
TreeNode node = map.get(it.next());
|
||
|
if (node.getParent() == -1) {
|
||
|
foldRow(map, node.getSelf(), poiSheet);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static class SessionRepository extends EmptyRepository {
|
||
|
private CalculatorProvider calculatorProvider = Calculator.createCalculator();
|
||
|
|
||
|
|
||
|
public SessionRepository buildSession(ReportSessionIDInfor sessionIDInfor) {
|
||
|
calculatorProvider.setAttribute(SessionProvider.KEY, sessionIDInfor);
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public CalculatorProvider getCalculator() {
|
||
|
return calculatorProvider;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String getSessionID() {
|
||
|
return ((SessionProvider) calculatorProvider.getAttribute(SessionProvider.KEY)).getSessionID();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
private static void foldRow(Map<Integer, TreeNode> map, int self, Sheet poiSheet) {
|
||
|
TreeNode node = map.get(self);
|
||
|
if (node == null) {
|
||
|
return;
|
||
|
}
|
||
|
int start = node.getSons().get(1);
|
||
|
int end = node.getSons().get(node.getSons().size() - 1);
|
||
|
for (int i = 1; i < node.getSons().size(); i++) {
|
||
|
int curStart = getStart(map, node.getSons().get(i));
|
||
|
int curEnd = getEnd(map, node.getSons().get(i));
|
||
|
if (curStart < start) {
|
||
|
start = curStart;
|
||
|
}
|
||
|
if (curEnd > end) {
|
||
|
end = curEnd;
|
||
|
}
|
||
|
foldRow(map, node.getSons().get(i), poiSheet);
|
||
|
}
|
||
|
|
||
|
poiSheet.groupRow(start, end);
|
||
|
if (poiSheet.getRow(self) instanceof XSSFRow) {
|
||
|
for (int r = start; r <= end; r++) {
|
||
|
XSSFRow expand = (XSSFRow) poiSheet.getRow(r);
|
||
|
expand.getCTRow().setHidden(true);
|
||
|
}
|
||
|
XSSFRow xssfRow = (XSSFRow) poiSheet.getRow(self);
|
||
|
xssfRow.getCTRow().setCollapsed(true);
|
||
|
}
|
||
|
if (node.getParent() == -1) {
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
private static int getStart(Map<Integer, TreeNode> map, int self) {
|
||
|
int start = self;
|
||
|
TreeNode node = map.get(self);
|
||
|
if (node == null) {
|
||
|
return start;
|
||
|
}
|
||
|
if (node.getSons() == null) {
|
||
|
return start;
|
||
|
}
|
||
|
for (int i = 1; i < node.getSons().size(); i++) {
|
||
|
int son = getStart(map, node.getSons().get(i));
|
||
|
if (son < start) {
|
||
|
start = son;
|
||
|
}
|
||
|
}
|
||
|
return start;
|
||
|
|
||
|
}
|
||
|
|
||
|
private static int getEnd(Map<Integer, TreeNode> map, int self) {
|
||
|
int end = self;
|
||
|
TreeNode node = map.get(self);
|
||
|
if (node == null) {
|
||
|
return end;
|
||
|
}
|
||
|
if (node.getSons() == null) {
|
||
|
return end;
|
||
|
}
|
||
|
for (int i = 1; i < node.getSons().size(); i++) {
|
||
|
int son = getEnd(map, node.getSons().get(i));
|
||
|
if (son > end) {
|
||
|
end = son;
|
||
|
}
|
||
|
}
|
||
|
return end;
|
||
|
}
|
||
|
|
||
|
public static ByteArrayInputStream parse(final OutputStream out) throws Exception {
|
||
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||
|
baos = (ByteArrayOutputStream) out;
|
||
|
final ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
|
||
|
return swapStream;
|
||
|
}
|
||
|
|
||
|
private static ResultCellElement findToggleCell(AnalysisRWorkSheet reportCase, int rowIndex) {
|
||
|
Iterator cellIterator = reportCase.getRow(rowIndex);
|
||
|
while (cellIterator.hasNext()) {
|
||
|
ResultCellElement tmpCell = (ResultCellElement) cellIterator.next();
|
||
|
if (tmpCell instanceof WidgetAttrElem) {
|
||
|
if (((WidgetAttrElem) tmpCell).getWidget() instanceof TreeNodeToggleButton) {
|
||
|
return tmpCell;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
public static void buildNodeMap(AnalysisRWorkSheet reportCase, ResultCellElement cellElment, Map<Integer, TreeNode> nodeMap, int parent, List<Integer> spanList) {
|
||
|
if (cellElment == null) {
|
||
|
return;
|
||
|
}
|
||
|
TreeNodeToggleButton toggleButton = (TreeNodeToggleButton) ((WidgetAttrElem) cellElment).getWidget();
|
||
|
int self = cellElment.getRow();
|
||
|
IntList sonList = toggleButton.getRelativeIndexList();
|
||
|
//折叠行
|
||
|
if (sonList != null && sonList.size() > 1) {
|
||
|
if (sonList.get(0) == -1) {
|
||
|
nodeMap.put(span(self, spanList), new TreeNode(span(self, spanList), span(parent, spanList), span(sonList, spanList)));
|
||
|
int size = sonList.size();
|
||
|
for (int i = 0; i < size; i++) {
|
||
|
buildNodeMap(reportCase, findToggleCell(reportCase, sonList.get(i)), nodeMap, self, spanList);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static IntList span(IntList list, List<Integer> spanList) {
|
||
|
IntList res = new IntList();
|
||
|
for (int i = 0; i < list.size(); i++) {
|
||
|
res.add(span(list.get(i), spanList));
|
||
|
}
|
||
|
return res;
|
||
|
}
|
||
|
|
||
|
private static int span(int row, List<Integer> spanList) {
|
||
|
if (spanList.isEmpty()) {
|
||
|
return row;
|
||
|
}
|
||
|
for (int i = 0; i < spanList.size(); i++) {
|
||
|
if (row >= spanList.get(i) && (i == spanList.size() - 1 || row < spanList.get(i + 1))) {
|
||
|
return row - (i + 1);
|
||
|
}
|
||
|
}
|
||
|
return row;
|
||
|
}
|
||
|
|
||
|
private static void setLevel(Map<Integer, TreeNode> map) {
|
||
|
for (Integer key : map.keySet()) {
|
||
|
int level = getLevel(map, map.get(key));
|
||
|
TreeNode node = map.get(key);
|
||
|
node.setLevel(level);
|
||
|
map.put(key, node);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static int getLevel(Map<Integer, TreeNode> map, TreeNode treeNode) {
|
||
|
if (treeNode.getParent() == -1) {
|
||
|
return 0;
|
||
|
}
|
||
|
int level = 0;
|
||
|
int tmp = treeNode.getParent();
|
||
|
while (map.get(tmp) != null) {
|
||
|
level++;
|
||
|
tmp = map.get(tmp).getParent();
|
||
|
}
|
||
|
return level;
|
||
|
}
|
||
|
|
||
|
public static Map<Integer, TreeNode> generateNodeTree(AnalysisRWorkSheet resultWS, List<Integer> spanList) {
|
||
|
int rowSize = resultWS.getRowCount();
|
||
|
Map<Integer, TreeNode> nodeMap = new HashMap<Integer, TreeNode>();
|
||
|
//遍历行
|
||
|
for (int rowIndex = rowSize; rowIndex > -1; rowIndex--) {
|
||
|
ResultCellElement treeNodeCell = findToggleCell(resultWS, rowIndex);
|
||
|
if (treeNodeCell != null) {
|
||
|
Widget widget = ((WidgetAttrElem) treeNodeCell).getWidget();
|
||
|
IntList sonList = ((TreeNodeToggleButton) widget).getRelativeIndexList();
|
||
|
if (sonList != null && sonList.size() > 1) {
|
||
|
if (sonList.get(0) == -1) {
|
||
|
//折叠行
|
||
|
if (nodeMap.containsKey(span(treeNodeCell.getRow(),spanList))) {
|
||
|
continue;
|
||
|
}
|
||
|
buildNodeMap(resultWS, treeNodeCell, nodeMap, -1, spanList);
|
||
|
setLevel(nodeMap);
|
||
|
} else {
|
||
|
//折叠列 暂不处理
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return nodeMap;
|
||
|
}
|
||
|
}
|