LAPTOP-SB56SG4Q\86185
3 years ago
8 changed files with 672 additions and 1 deletions
@ -1,3 +1,6 @@ |
|||||||
# open-JSD-7756 |
# open-JSD-7756 |
||||||
|
|
||||||
JSD-7756 定时调度邮件推送折叠树默认不展开 |
JSD-7756 定时调度邮件推送折叠树默认不展开\ |
||||||
|
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ |
||||||
|
仅作为开发者学习参考使用!禁止用于任何商业用途!\ |
||||||
|
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 |
@ -0,0 +1,17 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?><plugin> |
||||||
|
<id>com.fr.plugin.mail.fold</id> |
||||||
|
<name><![CDATA[邮件折叠]]></name> |
||||||
|
<active>yes</active> |
||||||
|
<version>1.2</version> |
||||||
|
<env-version>10.0</env-version> |
||||||
|
<jartime>2018-07-31</jartime> |
||||||
|
<vendor>fr.open</vendor> |
||||||
|
<description><![CDATA[邮件折叠]]></description> |
||||||
|
<change-notes><![CDATA[ |
||||||
|
<!--[2016-11-01]改进API接口,更加好的支持多多种类型的导出。<br/>--> |
||||||
|
]]></change-notes> |
||||||
|
<extra-decision> |
||||||
|
<OutputFormulaProvider class="com.fr.plugin.mail.fold.MailFoldFormula"/> |
||||||
|
</extra-decision> |
||||||
|
<function-recorder class="com.fr.plugin.mail.fold.MailFoldFormula"/> |
||||||
|
</plugin> |
@ -0,0 +1,269 @@ |
|||||||
|
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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,38 @@ |
|||||||
|
package com.fr.plugin.mail.fold; |
||||||
|
|
||||||
|
import com.fr.stable.html.Tag; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fr.open |
||||||
|
* @version 10.0 |
||||||
|
* Created by fr.open on 2020/7/6 |
||||||
|
*/ |
||||||
|
public class JoinedTag extends Tag { |
||||||
|
|
||||||
|
public JoinedTag(Tag originalTag) { |
||||||
|
super.setTagName( originalTag.getTagName()); |
||||||
|
super.setId(originalTag.getId()); |
||||||
|
super.setClasses(originalTag.getClasses()); |
||||||
|
super.setStyles(originalTag.getStyles()); |
||||||
|
super.setAttributes(originalTag.getAttributes()); |
||||||
|
super.setSubHtmlList(originalTag.getSubHtmlList()); |
||||||
|
super.setSiblingHtmlList(originalTag.getSiblingHtmlList()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public StringBuffer getClassList() { |
||||||
|
StringBuffer sb = new StringBuffer(); |
||||||
|
List<String> classes = super.getClasses(); |
||||||
|
if (classes != null && classes.size() > 0) { |
||||||
|
int size = classes.size(); |
||||||
|
for (int i = 0; i < size - 1; i++) { |
||||||
|
sb.append(classes.get(i)); |
||||||
|
sb.append(' '); |
||||||
|
} |
||||||
|
sb.append(classes.get(size - 1)); |
||||||
|
} |
||||||
|
return new StringBuffer(sb.toString().replace(" ", "")); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,79 @@ |
|||||||
|
package com.fr.plugin.mail.fold; |
||||||
|
|
||||||
|
import com.fr.main.workbook.ResultWorkBook; |
||||||
|
import com.fr.plugin.transform.FunctionRecorder; |
||||||
|
import com.fr.report.cell.ResultCellElement; |
||||||
|
import com.fr.report.cell.WidgetAttrElem; |
||||||
|
import com.fr.report.web.button.form.TreeNodeToggleButton; |
||||||
|
import com.fr.report.worksheet.AnalysisRWorkSheet; |
||||||
|
import com.fr.schedule.base.bean.output.OutputEmail; |
||||||
|
import com.fr.schedule.base.constant.ScheduleConstants; |
||||||
|
import com.fr.schedule.extension.report.job.output.formula.EmailFormula; |
||||||
|
import com.fr.schedule.extension.report.util.ScheduleParameterUtils; |
||||||
|
import com.fr.schedule.feature.util.ScheduleUtils; |
||||||
|
import com.fr.stable.unit.UNIT; |
||||||
|
import com.fr.web.core.ReportSessionIDInfor; |
||||||
|
|
||||||
|
import java.util.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @Author fr.open |
||||||
|
* @Date 2021/5/8 |
||||||
|
* @Description |
||||||
|
**/ |
||||||
|
@FunctionRecorder |
||||||
|
public class MailFoldFormula extends EmailFormula { |
||||||
|
@Override |
||||||
|
public void dealWithFormulaParam(OutputEmail outputEmail, ResultWorkBook resultWorkBook, List<Map<String, Object>> list) throws Exception { |
||||||
|
ResultWorkBook fold = getFold(resultWorkBook, list.get(0)); |
||||||
|
String contentText = ScheduleParameterUtils.dealWithParameter(outputEmail.getBodyContent(), list.get(0), fold); |
||||||
|
super.dealWithFormulaParam(outputEmail, fold, list); |
||||||
|
ReportSessionIDInfor sessionIdInfo = (new ReportSessionIDInfor(Collections.emptyMap())).buildResultWorkBook(fold); |
||||||
|
boolean showTPL = outputEmail.isPreviewAttach();// 是否勾选正文
|
||||||
|
boolean addLink = outputEmail.isAddLink();// 是否勾选链接
|
||||||
|
String bodyContent = contentText; |
||||||
|
bodyContent = showTPL ? bodyContent + "<br />" + TagUtils.exportTemplateAsHtml(null, sessionIdInfo) : bodyContent; |
||||||
|
bodyContent = addLink ? bodyContent + "<br /> <a href=" + outputEmail.getResultURL() + ScheduleUtils.getScheduleResultURL((Map) list.get(1)) + ">" + ScheduleConstants.SCHEDULE_LINK + "</a>" : bodyContent; |
||||||
|
outputEmail.setBodyContent(bodyContent); |
||||||
|
outputEmail.setBodyContentWithoutTPL(bodyContent); |
||||||
|
} |
||||||
|
|
||||||
|
private ResultWorkBook getFold(ResultWorkBook book, Map<String, Object> param) { |
||||||
|
if (param.containsKey("expand") && "false".equals(param.get("expand").toString())) { |
||||||
|
return book; |
||||||
|
} |
||||||
|
for (int i = 0; i < book.getReportCount(); i++) { |
||||||
|
if (book.getReport(i) instanceof AnalysisRWorkSheet) { |
||||||
|
AnalysisRWorkSheet sheet = (AnalysisRWorkSheet) book.getReport(i); |
||||||
|
Map<Integer, TreeNode> map = ExportUtil.generateNodeTree(sheet, new ArrayList()); |
||||||
|
for (int j = 0; j < sheet.getRowCount(); j++) { |
||||||
|
if (findToggleCell(sheet, j)) { |
||||||
|
if (map.get(j) == null || map.get(j).getParent() != -1) { |
||||||
|
sheet.setRowHeight(j, UNIT.ZERO); |
||||||
|
if (map.get(j) != null && map.get(j).getSons() != null) { |
||||||
|
for (int k = 1; k < map.get(j).getSons().size(); k++) { |
||||||
|
sheet.setRowHeight(map.get(j).getSons().get(k), UNIT.ZERO); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return book; |
||||||
|
} |
||||||
|
|
||||||
|
private boolean 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 true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,202 @@ |
|||||||
|
package com.fr.plugin.mail.fold; |
||||||
|
|
||||||
|
import com.fr.base.Base64; |
||||||
|
import com.fr.base.EmailAttachment; |
||||||
|
import com.fr.page.web.EmailCssHolder; |
||||||
|
import com.fr.stable.CommonCodeUtils; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.stable.email.EmailAttachmentProvider; |
||||||
|
import com.fr.stable.html.Tag; |
||||||
|
import com.fr.web.core.ReportSessionIDInfor; |
||||||
|
import com.fr.web.email.EmailPreviewContentReader; |
||||||
|
|
||||||
|
import javax.activation.DataHandler; |
||||||
|
import javax.mail.MessagingException; |
||||||
|
import javax.mail.internet.MimeBodyPart; |
||||||
|
import javax.mail.internet.MimeMultipart; |
||||||
|
import javax.servlet.http.HttpServletRequest; |
||||||
|
import java.util.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* @Author: fr.open |
||||||
|
* @Date: 2020/8/11 16:36 |
||||||
|
* 模板正文导出成html或者base64图片 |
||||||
|
*/ |
||||||
|
public class TagUtils { |
||||||
|
|
||||||
|
public static String exportTemplateAsHtml(HttpServletRequest req, ReportSessionIDInfor sessionIDInfor) throws Exception { |
||||||
|
Map<String, String> cssMap = EmailCssHolder.getInstance().getCssMap("/com/fr/web/core/css/report.core.css"); |
||||||
|
// Tag reportContentTag = MA.F().B(req, sessionIDInfor);
|
||||||
|
Tag reportContentTag = EmailPreviewContentReader.getInstance().getContentTag(req, sessionIDInfor); |
||||||
|
Set<String> classGroupSet = getAllClsGroup(reportContentTag); |
||||||
|
StringBuffer finalcss = new StringBuffer(); |
||||||
|
for (String clsGroup : classGroupSet) { |
||||||
|
String[] claArr = clsGroup.split(" "); |
||||||
|
String key = clsGroup.replace(" ", ""); |
||||||
|
StringBuffer mergecss = new StringBuffer("{"); |
||||||
|
for (String cls : claArr) { |
||||||
|
String text = cssMap.get("." + cls); |
||||||
|
if (StringUtils.isNotEmpty(text)) { |
||||||
|
text = text.replace("*", ""); // outlook 网页端不兼容*号css样式,*是outlook全局样式
|
||||||
|
/* if (!StringUtils.contains(text,"word-break")&&!StringUtils.contains(text,"word-wrap")){ |
||||||
|
mergecss.append(text.substring(text.indexOf("{") + 1, text.lastIndexOf("}"))).append(";"); |
||||||
|
}*/ |
||||||
|
mergecss.append(text.substring(text.indexOf("{") + 1, text.lastIndexOf("}"))).append(";"); |
||||||
|
} |
||||||
|
} |
||||||
|
if (!"{".equals(mergecss.toString())) { |
||||||
|
mergecss.append("}"); |
||||||
|
finalcss.append(".").append(key).append(" ").append(mergecss); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
finalcss.append("table.x-table{overflow:visible;line-height:1;}");//QQ邮箱样式影响
|
||||||
|
finalcss.append("td{line-height:1 !important;}");//网易邮箱样式影响
|
||||||
|
|
||||||
|
// setTdNowrap(reportContentTag);
|
||||||
|
|
||||||
|
Set<Tag> allUndisplayTag = findAllUndisplayTag(reportContentTag); |
||||||
|
String contetTag = reportContentTag.toString(); |
||||||
|
for (Tag tag : allUndisplayTag) { |
||||||
|
contetTag = contetTag.replace(tag.toString(), ""); // 把隐藏的tag不输出,outlook客户端不兼容display:none的style样式
|
||||||
|
} |
||||||
|
String bodyContent = "<style type=\"text/css\" id=\"_fr_content_style\">" + finalcss + "</style>" + contetTag; |
||||||
|
changeBase64ToPng(bodyContent); |
||||||
|
return bodyContent; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private static Set<String> getAllClsGroup(Tag tag) { |
||||||
|
Set<String> result = new HashSet<String>(); |
||||||
|
if (tag != null) { |
||||||
|
String tagCls = tag.getClassList().toString(); |
||||||
|
if (StringUtils.isNotEmpty(tagCls)) { |
||||||
|
result.add(tagCls); |
||||||
|
} |
||||||
|
List subList = tag.getSubHtmlList(); |
||||||
|
if (subList != null) { |
||||||
|
for (int i = 0; i < subList.size(); i++) { |
||||||
|
Object html = subList.get(i); |
||||||
|
if (html instanceof Tag) { |
||||||
|
result.addAll(getAllClsGroup((Tag) html)); |
||||||
|
if ("td".equals(((Tag) html).getTagName())) { |
||||||
|
html = new JoinedTag((Tag) html); |
||||||
|
subList.set(i, html); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private static Set<Tag> findAllUndisplayTag(Tag tag) { |
||||||
|
Set<Tag> result = new HashSet(); |
||||||
|
if (tag != null) { |
||||||
|
String tagStyle = tag.getStyleList().toString(); |
||||||
|
if (StringUtils.contains(tagStyle, "display:none")) { |
||||||
|
result.add(tag); |
||||||
|
} |
||||||
|
|
||||||
|
List subList = tag.getSubHtmlList(); |
||||||
|
if (subList != null) { |
||||||
|
for (int i = 0; i < subList.size(); i++) { |
||||||
|
Object html = subList.get(i); |
||||||
|
if (html instanceof Tag) { |
||||||
|
result.addAll(findAllUndisplayTag((Tag) html)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
//((Tag) html).setAttributes((Map<String, String>) new HashMap().put("nowrap","nowrap"));
|
||||||
|
private static void setTdNowrap(Tag tag) { |
||||||
|
if (tag != null) { |
||||||
|
if ("td".equals(tag.getTagName())) { |
||||||
|
tag.setAttributes((Map<String, String>) new HashMap().put("nowrap", "nowrap")); |
||||||
|
} |
||||||
|
List subList = tag.getSubHtmlList(); |
||||||
|
if (subList != null) { |
||||||
|
for (int i = 0; i < subList.size(); i++) { |
||||||
|
Object html = subList.get(i); |
||||||
|
if (html instanceof Tag) { |
||||||
|
setTdNowrap((Tag) html); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static EmailAttachment[] buildBase64ToPngEmailAttachment(String bodyContent) throws MessagingException { |
||||||
|
ArrayList emailAttachmentsGroup = new ArrayList<EmailAttachment>(); |
||||||
|
String defaultName = "templateImage"; |
||||||
|
String base64Tag = "data:image/png;base64,"; |
||||||
|
MimeMultipart multipart = new MimeMultipart(); |
||||||
|
if (bodyContent.contains(base64Tag)) { |
||||||
|
MimeBodyPart htmlPart = new MimeBodyPart(); |
||||||
|
while (bodyContent.contains(base64Tag)) { |
||||||
|
int start = bodyContent.indexOf(base64Tag); |
||||||
|
int end = bodyContent.indexOf("></img>", start); |
||||||
|
String base64 = bodyContent.substring(start + base64Tag.length(), end); |
||||||
|
String cidPrefix = defaultName+ UUID.randomUUID(); |
||||||
|
bodyContent = bodyContent.substring(0, start) + "cid:" + cidPrefix + "\"" + bodyContent.substring(end); |
||||||
|
// 跟代码看到com.fr.base.EmailManager.sendWithRecord里面,setFormat直接给的null,这里暂时先用null
|
||||||
|
String setFormat = null; |
||||||
|
htmlPart.setContent(bodyContent, setFormat); |
||||||
|
EmailAttachment emailAttachment = new EmailAttachment(Base64.decode(CommonCodeUtils.attributeHtmlDecode(base64)), cidPrefix); |
||||||
|
emailAttachmentsGroup.add(emailAttachment); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int size = emailAttachmentsGroup.size(); |
||||||
|
EmailAttachment[] emailAttachments = new EmailAttachment[size]; |
||||||
|
if (!emailAttachmentsGroup.isEmpty()){ |
||||||
|
for (int i=0;i<size;i++){ |
||||||
|
EmailAttachment attachment = (EmailAttachment) emailAttachmentsGroup.get(i); |
||||||
|
emailAttachments[i] = attachment; |
||||||
|
} |
||||||
|
} |
||||||
|
return emailAttachments; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static MimeMultipart changeBase64ToPng(String bodyContent) throws MessagingException { |
||||||
|
String defaultName = "templateImage"; |
||||||
|
String base64Tag = "data:image/png;base64,"; |
||||||
|
MimeMultipart multipart = new MimeMultipart(); |
||||||
|
if (bodyContent.contains(base64Tag)) { |
||||||
|
MimeBodyPart htmlPart = new MimeBodyPart(); |
||||||
|
while (bodyContent.contains(base64Tag)) { |
||||||
|
int start = bodyContent.indexOf(base64Tag); |
||||||
|
int end = bodyContent.indexOf("></img>", start); |
||||||
|
String base64 = bodyContent.substring(start + base64Tag.length(), end); |
||||||
|
String cidPrefix = defaultName+ UUID.randomUUID(); |
||||||
|
bodyContent = bodyContent.substring(0, start) + "cid:" + cidPrefix + "\"" + bodyContent.substring(end); |
||||||
|
// 跟代码看到com.fr.base.EmailManager.sendWithRecord里面,setFormat直接给的null,这里暂时先用null
|
||||||
|
String setFormat = null; |
||||||
|
htmlPart.setContent(bodyContent, setFormat); |
||||||
|
|
||||||
|
addImagePart(multipart, new EmailAttachment(Base64.decode(CommonCodeUtils.attributeHtmlDecode(base64)), cidPrefix), cidPrefix); |
||||||
|
} |
||||||
|
multipart.addBodyPart(htmlPart); |
||||||
|
|
||||||
|
} |
||||||
|
return multipart; |
||||||
|
} |
||||||
|
|
||||||
|
private static void addImagePart(MimeMultipart mimeMultipart, EmailAttachmentProvider provider, String filename) throws MessagingException { |
||||||
|
MimeBodyPart mimeBodyPart = new MimeBodyPart(); |
||||||
|
mimeBodyPart.setDataHandler(new DataHandler(provider.getByteArrayDataSource())); |
||||||
|
mimeBodyPart.setHeader("Content-ID", "<" + filename + ">"); |
||||||
|
mimeBodyPart.setFileName(filename + ".png"); |
||||||
|
mimeBodyPart.setDisposition("inline"); |
||||||
|
mimeMultipart.addBodyPart(mimeBodyPart); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,63 @@ |
|||||||
|
package com.fr.plugin.mail.fold; |
||||||
|
|
||||||
|
import com.fr.cache.list.IntList; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author fr.open |
||||||
|
* @date 2019/6/3 |
||||||
|
*/ |
||||||
|
public class TreeNode { |
||||||
|
/** |
||||||
|
* 自身所在行 |
||||||
|
*/ |
||||||
|
private int self; |
||||||
|
/** |
||||||
|
* 父节点所在行 |
||||||
|
*/ |
||||||
|
private int parent; |
||||||
|
/** |
||||||
|
* 子节点 |
||||||
|
*/ |
||||||
|
|
||||||
|
private IntList sons; |
||||||
|
|
||||||
|
private int level; |
||||||
|
|
||||||
|
public TreeNode(int self, int parent, IntList sons) { |
||||||
|
this.self = self; |
||||||
|
this.parent = parent; |
||||||
|
this.sons = sons; |
||||||
|
} |
||||||
|
|
||||||
|
public int getParent() { |
||||||
|
return parent; |
||||||
|
} |
||||||
|
|
||||||
|
public void setParent(int parent) { |
||||||
|
this.parent = parent; |
||||||
|
} |
||||||
|
|
||||||
|
public int getSelf() { |
||||||
|
return self; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSelf(int self) { |
||||||
|
this.self = self; |
||||||
|
} |
||||||
|
|
||||||
|
public IntList getSons() { |
||||||
|
return sons; |
||||||
|
} |
||||||
|
|
||||||
|
public void setSons(IntList sons) { |
||||||
|
this.sons = sons; |
||||||
|
} |
||||||
|
|
||||||
|
public int getLevel() { |
||||||
|
return level; |
||||||
|
} |
||||||
|
|
||||||
|
public void setLevel(int level) { |
||||||
|
this.level = level; |
||||||
|
} |
||||||
|
} |
Binary file not shown.
Loading…
Reference in new issue