Browse Source

无JIRA任务 sdk合并finekit

master
zack 5 years ago
parent
commit
a09d0c7fb9
  1. 88
      src/main/java/com/fanruan/api/cal/CalculatorKit.java
  2. 49
      src/main/java/com/fanruan/api/cal/FormulaKit.java
  3. 67
      src/main/java/com/fanruan/api/cal/namespace/SheetInterval4CheckNameSpace.java
  4. 42
      src/main/java/com/fanruan/api/env/EnvKit.java
  5. 33
      src/main/java/com/fanruan/api/env/shell/ModuleShell.java
  6. 59
      src/main/java/com/fanruan/api/function/FunctionKit.java
  7. 46
      src/main/java/com/fanruan/api/function/shell/FineFunc.java
  8. 24
      src/main/java/com/fanruan/api/report/TemplateKit.java
  9. 47
      src/main/java/com/fanruan/api/report/analy/AnalyKit.java
  10. 75
      src/main/java/com/fanruan/api/report/analy/AnalyKitHelper.java
  11. 52
      src/main/java/com/fanruan/api/report/analy/data/TreeNode.java
  12. 58
      src/main/java/com/fanruan/api/util/TransmissionKit.java
  13. 27
      src/main/java/com/fanruan/api/util/shell/BaseSmsBody.java
  14. 94
      src/main/java/com/fanruan/api/util/shell/BatchSmsBody.java
  15. 219
      src/main/java/com/fanruan/api/util/shell/EmailBody.java
  16. 162
      src/main/java/com/fanruan/api/util/shell/SingleSmsBody.java
  17. 31
      src/test/java/com/fanruan/api/Prepare.java
  18. 49
      src/test/java/com/fanruan/api/cal/CalculatorKitEnvTest.java
  19. 40
      src/test/java/com/fanruan/api/cal/CalculatorKitTest.java
  20. 18
      src/test/java/com/fanruan/api/cal/FormulaKitTest.java
  21. 46
      src/test/java/com/fanruan/api/function/FunctionKitTest.java
  22. 10
      src/test/java/com/fanruan/api/function/TestFunc.java
  23. 31
      src/test/java/com/fanruan/api/report/analy/AnalyKitTest.java
  24. 27
      src/test/java/com/fanruan/api/util/TransmissionKitTest.java
  25. 72
      src/test/resources/com/fanruan/api/report/sheets.cpt
  26. 247
      src/test/resources/com/fanruan/api/report/tree.cpt

88
src/main/java/com/fanruan/api/cal/CalculatorKit.java

@ -0,0 +1,88 @@
package com.fanruan.api.cal;
import com.fanruan.api.cal.namespace.SheetInterval4CheckNameSpace;
import com.fanruan.api.session.SessionKit;
import com.fr.base.ParameterMapNameSpace;
import com.fr.base.TableDataNameSpace;
import com.fr.data.TableDataSource;
import com.fr.report.report.Report;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import com.fr.stable.script.CalculatorProvider;
import com.fr.stable.script.NameSpace;
import com.fr.stable.web.SessionProvider;
import com.fr.third.javax.annotation.Nullable;
import com.fr.web.core.ReportSessionIDInfor;
import com.fr.web.core.TemplateSessionIDInfo;
import com.fr.web.session.SessionIDInfo;
import java.util.Map;
/**
* @ClassName CalculatorKit
* @Author zack
* @Date 2019/8/23
* @Version 10.0
* 帆软算子工具类主要用于公式计算
*/
public class CalculatorKit {
/**
* 创建一个基础算子基础算子仅支持函数计算.比如SUM()函数
*
* @return 算子
*/
public static CalculatorProvider createCalculator() {
return Calculator.createCalculator();
}
/**
* 创建一个带参数计算的算子
* 可以支持计算入参paraMap里面相关的带参函数
* 比如paraMap带有参数a->1,b->2,CalculatorKit.createCalculator(paraMap).evalValue("SUM(a,b)")输出3
*
* @return 算子
*/
public static CalculatorProvider createCalculator(Map paraMap) {
ParameterMapNameSpace nameSpace = ParameterMapNameSpace.create(paraMap);
CalculatorProvider calculator = createCalculator();
calculator.pushNameSpace(nameSpace);
return calculator;
}
/**
* 创建一个支持单元格以及模板数据集计算的算子
*
* @param sessionID 模板的sessionID
* @param paraMap 其他参数
* @return
*/
public static CalculatorProvider createCalculator(@Nullable String sessionID, @Nullable Map paraMap) {
ParameterMapNameSpace nameSpace = ParameterMapNameSpace.create(paraMap);
CalculatorProvider calculator = createCalculator();
calculator.pushNameSpace(nameSpace);
if (StringUtils.isNotEmpty(sessionID)) {
SessionProvider rsii = SessionKit.getSession(sessionID);
if (rsii != null) {
if (rsii instanceof TemplateSessionIDInfo) {
//支持模板单元格值计算
calculator.setAttribute(TableDataSource.KEY, ((TemplateSessionIDInfo) rsii).getTableDataSource());
calculator.pushNameSpace(SessionIDInfo.asNameSpace(sessionID));
if (rsii instanceof ReportSessionIDInfor) {
//支持跨sheet计算
calculator.pushNameSpace(SheetInterval4CheckNameSpace.getInstance());
calculator.setAttribute(Report.KEY, ((ReportSessionIDInfor) rsii).getReport2Show(0));
}
}
}
}
return calculator;
}
/**
* 返回服务器数据集的算子空间可以通过调用calculator.pushNameSpace()将算子空间塞进算子实例从而支持服务器数据集相关的函数计算
* @return
*/
public static NameSpace getServerTableDataNameSpace(){
return TableDataNameSpace.getInstance();
}
}

49
src/main/java/com/fanruan/api/cal/FormulaKit.java

@ -2,13 +2,20 @@ package com.fanruan.api.cal;
import com.fanruan.api.err.KitError;
import com.fr.base.BaseFormula;
import com.fr.log.FineLoggerFactory;
import com.fr.parser.FRLexer;
import com.fr.parser.FRParser;
import com.fr.script.Calculator;
import com.fr.stable.FormulaProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.UtilEvalError;
import com.fr.stable.script.CalculatorProvider;
import com.fr.stable.script.Expression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.StringReader;
/**
* @author richie
* @version 10.0
@ -19,6 +26,7 @@ public class FormulaKit {
/**
* 计算公式的值会新建一个算子对象来计算该公式
*
* @param formula 公式内容
* @return 公式计算后的结果值
* @throws KitError 如果计算过程中出现错误则抛出此异常
@ -29,6 +37,7 @@ public class FormulaKit {
/**
* 计算公式的值
*
* @param calculator 自定义算子
* @param formula 公式内容
* @return 公式计算后的结果值
@ -44,10 +53,50 @@ public class FormulaKit {
/**
* 生成公式对象
*
* @param content 公式的内容
* @return 公式对象
*/
public static @NotNull FormulaProvider newFormula(Object content) {
return BaseFormula.createFormulaBuilder().build(content);
}
/**
* 检查公式内容合法性
*
* @param content 公式文本公式的开头等号要先去掉如果想校验等号开头的内容需要传Formula对象
* @return 如果非空且不合法返回false, 反之返回true
*/
public static boolean checkFormulaContent(String content) {
String formulaText = content.trim();
if (StringUtils.isNotEmpty(formulaText)) {
StringReader in = new StringReader(formulaText);
FRLexer lexer = new FRLexer(in);
FRParser parser = new FRParser(lexer);
Expression expression = null;
try {
expression = parser.parse();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return null != expression;
}
return true;
}
/**
* 公式合法性校验
*
* @param formula 公式对象
* @return 当前公式是否合法
*/
public static boolean checkFormulaContent(FormulaProvider formula) {
if (formula == null) {
return true;
}
return checkFormulaContent(formula.getPureContent());
}
}

67
src/main/java/com/fanruan/api/cal/namespace/SheetInterval4CheckNameSpace.java

@ -0,0 +1,67 @@
package com.fanruan.api.cal.namespace;
import com.fr.general.ComparatorUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.main.FineBook;
import com.fr.parser.SheetIntervalLiteral;
import com.fr.report.report.Report;
import com.fr.report.report.WriteECReport;
import com.fr.stable.StringUtils;
import com.fr.stable.script.AbstractNameSpace;
import com.fr.stable.script.CalculatorProvider;
import com.fr.stable.script.ColumnRowRange;
/**
* @deprecated 当sdk因为其他需求有主体jar要求的时候这边可以删掉
* 主体代码里面的这个类被混淆了sdk抄一份一样的
* @author Carl
* 填报的时候处理跨域的值
*/
public class SheetInterval4CheckNameSpace extends AbstractNameSpace {
public static final SheetInterval4CheckNameSpace SC = new SheetInterval4CheckNameSpace();
private SheetInterval4CheckNameSpace(){}
public static SheetInterval4CheckNameSpace getInstance() {
return SC;
}
@Override
public Object getVariable(Object var, CalculatorProvider calculator) {
// TODO carl:真是乱
if (!(var instanceof SheetIntervalLiteral)) {
return null;
}
Report report = calculator.getAttribute(Report.KEY);
if (report == null) {
return null;
}
FineBook wb = report.getBook();
SheetIntervalLiteral sil = (SheetIntervalLiteral)var;
if (wb == null || StringUtils.isBlank(sil.getSheetName())) {
return null;
}
for (int i = 0; i < wb.getReportCount(); i++) {
if (ComparatorUtils.equals(wb.getReportName(i), sil.getSheetName())) {
Report rp = wb.getReport(i);
if (rp instanceof WriteECReport) {
if (sil.getSheetAtom() instanceof ColumnRowRange) {
return ((WriteECReport)rp).resolveColumnRowRange((ColumnRowRange)sil.getSheetAtom(), null);
} else {
// TODO 暂时只有 ColumnRowRange和Ambiguity两种,考虑到以后会加就弄到外面来处理
// Ambiguity的情况不处理
FineLoggerFactory.getLogger().error("UnResolvedVariable " + sil.toString());
}
}
break;
}
}
return null;
}
}

42
src/main/java/com/fanruan/api/env/EnvKit.java vendored

@ -1,6 +1,22 @@
package com.fanruan.api.env;
import com.fanruan.api.env.shell.ModuleShell;
import com.fr.base.operator.common.CommonOperator;
import com.fr.chart.activator.ChartBaseActivator;
import com.fr.cluster.engine.activator.standalone.StandaloneModeActivator;
import com.fr.config.activator.BaseDBActivator;
import com.fr.config.activator.ConfigurationActivator;
import com.fr.env.operator.CommonOperatorImpl;
import com.fr.general.I18nResource;
import com.fr.module.Module;
import com.fr.module.tool.ActivatorToolBox;
import com.fr.report.ReportActivator;
import com.fr.report.RestrictionActivator;
import com.fr.report.module.ReportBaseActivator;
import com.fr.scheduler.SchedulerActivator;
import com.fr.stable.StringUtils;
import com.fr.stable.project.ProjectConstants;
import com.fr.store.StateServerActivator;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.resource.WorkResource;
@ -42,6 +58,32 @@ public class EnvKit {
}
}
/**
* 创建本地服务器启动模块
*
* @param envPath 本地工程路径 : D:\\FineReport_10.0\\webapps\\webroot\\WEB-INF
* @return 模块代理对象 使用ModuleShell的start和stop控制模块启停
*/
public static ModuleShell createLocalStartModule(String envPath) {
Module module = ActivatorToolBox.simpleLink(
new BaseDBActivator(),
new ConfigurationActivator(),
new StandaloneModeActivator(),
new StateServerActivator(),
new SchedulerActivator(),
new ReportBaseActivator(),
new RestrictionActivator(),
new ReportActivator(),
new ChartBaseActivator()
);
SimpleWork.supply(CommonOperator.class, new CommonOperatorImpl());
if (StringUtils.isNotEmpty(envPath)) {
SimpleWork.checkIn(envPath);
}
I18nResource.getInstance();
return new ModuleShell(module);
}
/**
* 退出当前工作目录
*/

33
src/main/java/com/fanruan/api/env/shell/ModuleShell.java vendored

@ -0,0 +1,33 @@
package com.fanruan.api.env.shell;
import com.fr.module.Module;
/**
* 模块封装
*/
public class ModuleShell {
private Module module;
public ModuleShell(Module module) {
this.module = module;
}
/**
* 启动模块
*/
public void start() {
if (module != null) {
module.start();
}
}
/**
* 关闭模块
*/
public void stop() {
if (module != null) {
module.stop();
}
}
}

59
src/main/java/com/fanruan/api/function/FunctionKit.java

@ -0,0 +1,59 @@
package com.fanruan.api.function;
import com.fanruan.api.function.shell.FineFunc;
import com.fr.file.FunctionManager;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import com.fr.stable.script.FunctionDef;
import java.util.ArrayList;
import java.util.List;
/**
* @ClassName FunctionKit
* @Author zack
* @Date 2019/8/23
* @Version 10.0
* 函数相关工具类
*/
public class FunctionKit {
/**
* 新增一个自定义函数
*
* @param fineFunc 自定义函数对象
*/
public static void addFunc(FineFunc fineFunc) {
if (fineFunc == null) {
return;
}
if (Calculator.createCalculator().resolveMethod(fineFunc.getName()) == null) {
FunctionManager.getInstance().addFunctionDef(new FunctionDef(fineFunc.getName(), fineFunc.getDescription(), fineFunc.getClassName()));
}
}
/**
* 根据自定义函数类路径移除一个自定义函数
*
* @param className 自定义函数类路径
*/
public static void removeFunc(String className) {
if (StringUtils.isEmpty(className)) {
return;
}
int count = FunctionManager.getInstance().getFunctionDefCount();
List<FunctionDef> functionDefList = new ArrayList<FunctionDef>(count);
for (int i = 0; i < count; i++) {
FunctionDef functionDef = FunctionManager.getInstance().getFunctionDef(i);
if (!className.equalsIgnoreCase(functionDef.getClassName())) {
functionDefList.add(functionDef);
}
}
if (functionDefList.size() == count) {
return;
}
FunctionManager.getInstance().clearAllFunctionDef();
for (FunctionDef fun : functionDefList) {
FunctionManager.getInstance().addFunctionDef(fun);
}
}
}

46
src/main/java/com/fanruan/api/function/shell/FineFunc.java

@ -0,0 +1,46 @@
package com.fanruan.api.function.shell;
import com.fr.stable.StringUtils;
/**
* 自定义函数封装
*/
public class FineFunc {
private String name;//函数名
private String description;//描述
private String className;//完整类名
public FineFunc(String name, String description, String className) {
this.name = name;
this.description = description;
this.className = className;
}
public FineFunc(String name, String className) {
this(name, StringUtils.EMPTY, className);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
}

24
src/main/java/com/fanruan/api/report/TemplateKit.java

@ -0,0 +1,24 @@
package com.fanruan.api.report;
import com.fr.io.TemplateWorkBookIO;
import com.fr.main.TemplateWorkBook;
/**
* @ClassName TemplateKit
* @Author zack
* @Date 2019/8/23
* @Version 10.0
* 模板操作相关工具类
*/
public class TemplateKit {
/**
* 通过相对路径读取模板
*
* @param relativePath 相对路径相对reportlets目录
* @return 模板对象
* @throws Exception 模板读取异常
*/
public static TemplateWorkBook readTemplateByPath(String relativePath) throws Exception {
return TemplateWorkBookIO.readTemplateWorkBook(
relativePath);
}
}

47
src/main/java/com/fanruan/api/report/analy/AnalyKit.java

@ -0,0 +1,47 @@
package com.fanruan.api.report.analy;
import com.fanruan.api.report.analy.data.TreeNode;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.report.report.Report;
import com.fr.report.report.ResultReport;
import com.fr.report.worksheet.AnalysisRWorkSheet;
import com.fr.script.Calculator;
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.util.Map;
/**
* @ClassName AnalyKit
* @Author zack
* @Date 2019/8/23
* @Version 10.0
* 数据分析相关工具类
*/
public class AnalyKit {
/**
* 折叠树模板将结果报表行转成一个树形数据结构
*
* @param book 结果报表
* @param index sheet索引
* @return 树节点集合
*/
public static Map<Integer, TreeNode> generateResultBookTree(ResultWorkBook book, int index) {
ResultReport resultWS = book.getResultReport(index);
if (!(resultWS instanceof AnalysisRWorkSheet)) {
//只有分析预览支持折叠树
throw new UnsupportedOperationException();
}
AnalysisRWorkSheet analysisRWorkSheet = (AnalysisRWorkSheet) resultWS;
Calculator c = Calculator.createCalculator();
c.setAttribute(Report.KEY, analysisRWorkSheet);
TreeHTMLWriter htmlWriter = new TreeHTMLWriter();
ViewCellWriter cellHtmlWriter = new ViewCellWriter(new EmptyRepository(), 1, resultWS.getReportSettings(), true);
htmlWriter.writeReportToHtml(new WebElementReportCase(analysisRWorkSheet, new EmptyRepository()), 1, cellHtmlWriter, new EmptyRepository(), "");
cellHtmlWriter.dealWithAllTreeNodeRelation(c);
return AnalyKitHelper.generateNodeTree(analysisRWorkSheet);
}
}

75
src/main/java/com/fanruan/api/report/analy/AnalyKitHelper.java

@ -0,0 +1,75 @@
package com.fanruan.api.report.analy;
import com.fanruan.api.report.analy.data.TreeNode;
import com.fr.cache.list.IntList;
import com.fr.form.ui.Widget;
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 java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* 数据分析相关的业务类此类是为了接盘AnalyKit中的庞杂的私有方法增强AnalyKit的可读性
*/
public class AnalyKitHelper {
public static Map<Integer, TreeNode> generateNodeTree(AnalysisRWorkSheet resultWS) {
int rowSize = resultWS.getRowCount();
Map<Integer, TreeNode> nodeMap = new HashMap<Integer, TreeNode>();
for (int rowIndex = 0; rowIndex < rowSize; 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(treeNodeCell.getRow())) {
continue;
}
buildNodeMap(resultWS, treeNodeCell, nodeMap, -1);
} else {
//折叠列 暂不处理
}
}
}
}
return nodeMap;
}
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;
}
private static void buildNodeMap(AnalysisRWorkSheet reportCase, ResultCellElement cellElment, Map<Integer, TreeNode> nodeMap, int parent) {
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(self, new TreeNode(self, parent, sonList));
int size = sonList.size();
for (int i = 0; i < size; i++) {
buildNodeMap(reportCase, findToggleCell(reportCase, sonList.get(i)), nodeMap, self);
}
}
}
}
}

52
src/main/java/com/fanruan/api/report/analy/data/TreeNode.java

@ -0,0 +1,52 @@
package com.fanruan.api.report.analy.data;
import com.fr.cache.list.IntList;
/**
* 折叠行树节点对象
*/
public class TreeNode {
private int self;//自身所在行
private int parent;//父节点所在行
private IntList sons;//子节点
public TreeNode(int self, int parent, IntList sons) {
this.self = self;
this.parent = parent;
this.sons = sons;
}
public void setParent(int parent) {
this.parent = parent;
}
public void setSons(IntList sons) {
this.sons = sons;
}
public void setSelf(int self) {
this.self = self;
}
public int getParent() {
return parent;
}
public int getSelf() {
return self;
}
public IntList getSons() {
return sons;
}
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(self).append("#").append(parent);
if (sons != null) {
stringBuffer.append("#").append(sons.toString());
}
return stringBuffer.toString();
}
}

58
src/main/java/com/fanruan/api/util/TransmissionKit.java

@ -0,0 +1,58 @@
package com.fanruan.api.util;
import com.fanruan.api.util.shell.BaseSmsBody;
import com.fanruan.api.util.shell.EmailBody;
import com.fr.base.EmailManager;
import com.fr.base.sms.SMSManager;
/**
* @ClassName TransmissionKit
* @Author zack
* @Date 2019/8/23
* @Version 10.0
* fine kit for data transmission.(eg. email or sms...)
*/
public class TransmissionKit {
/**
* 服务端是否支持短信服务
*
* @return 支持返回true 否则false
*/
public static boolean isSmsFuncSupport() {
return SMSManager.getInstance().isSMSFuncSupport();
}
/**
* 发送短信
*
* @param baseSmsBody 短信实体
* @return 发送成功返回true 否则false
* @throws Exception
*/
public static boolean sendSms(BaseSmsBody baseSmsBody) throws Exception {
return baseSmsBody.send();
}
/**
* 发送邮件
*
* @param emailBody 邮件实体
* @return 发送成功返回true否则false
* @throws Exception
*/
public static boolean sendEmail(EmailBody emailBody) throws Exception {
EmailManager.getInstance().send(
emailBody.getToAddress(),
emailBody.getCcAddress(),
emailBody.getBccAddress(),
emailBody.getFromAddress(),
emailBody.getSubject(),
emailBody.getBodyContent(),
emailBody.getAttaches(),
emailBody.getFormat(),
emailBody.getContentAttaches(),
emailBody.getSessionId()
);
return true;
}
}

27
src/main/java/com/fanruan/api/util/shell/BaseSmsBody.java

@ -0,0 +1,27 @@
package com.fanruan.api.util.shell;
/**
* 抽象短信体
*
* @author vito
* @date 2019-07-24
*/
public abstract class BaseSmsBody {
private String templateCode;
public String getTemplateCode() {
return templateCode;
}
void setTemplateCode(String templateCode) {
this.templateCode = templateCode;
}
/**
* 发送
*
* @return 发送结果
* @throws Exception 发送异常
*/
public abstract boolean send() throws Exception;
}

94
src/main/java/com/fanruan/api/util/shell/BatchSmsBody.java

@ -0,0 +1,94 @@
package com.fanruan.api.util.shell;
import com.fr.base.sms.SMSManager;
import com.fr.json.JSONArray;
import java.util.List;
/**
* 批量短信体
*
* @author vito
* @date 2019-07-24
*/
public class BatchSmsBody extends BaseSmsBody {
private List<String> mobiles;
private List<String> receivers;
private JSONArray para;
private BatchSmsBody() {
}
public List<String> getMobiles() {
return mobiles;
}
public List<String> getReceivers() {
return receivers;
}
public JSONArray getPara() {
return para;
}
public static Builder newBuilder() {
return new Builder();
}
@Override
public boolean send() throws Exception {
return SMSManager.getInstance().batchSendSMS(
getTemplateCode(),
getMobiles(),
getPara(),
getReceivers());
}
public static final class Builder {
private String templateCode;
private List<String> mobiles;
private List<String> receivers;
private JSONArray para;
private Builder() {
}
public Builder templateCode(String templateCode) {
this.templateCode = templateCode;
return this;
}
public Builder mobiles(List<String> mobiles) {
this.mobiles = mobiles;
return this;
}
public Builder receivers(List<String> receivers) {
this.receivers = receivers;
return this;
}
public Builder para(JSONArray para) {
this.para = para;
return this;
}
public BatchSmsBody build() {
if (templateCode == null) {
throw new IllegalArgumentException("templateCode should not be null");
}
if (mobiles == null) {
throw new IllegalArgumentException("mobiles should not be null");
}
if (para == null) {
throw new IllegalArgumentException("para should not be null");
}
BatchSmsBody batchSmsBody = new BatchSmsBody();
batchSmsBody.setTemplateCode(templateCode);
batchSmsBody.receivers = this.receivers;
batchSmsBody.mobiles = this.mobiles;
batchSmsBody.para = this.para;
return batchSmsBody;
}
}
}

219
src/main/java/com/fanruan/api/util/shell/EmailBody.java

@ -0,0 +1,219 @@
package com.fanruan.api.util.shell;
import com.fr.base.EmailAttachment;
import org.jetbrains.annotations.Nullable;
/**
* 邮件体
*
* @author vito
* @date 2019-07-24
*/
public class EmailBody {
private String toAddress;
private String ccAddress;
private String bccAddress;
private String fromAddress;
private String subject;
private String bodyContent;
private EmailAttachment[] attaches;
private String format;
private EmailAttachment[] contentAttaches;
private String sessionId;
private EmailBody(Builder builder) {
this.toAddress = builder.toAddress;
this.ccAddress = builder.ccAddress;
this.bccAddress = builder.bccAddress;
this.fromAddress = builder.fromAddress;
this.subject = builder.subject;
this.bodyContent = builder.bodyContent;
this.attaches = builder.attaches;
this.format = builder.format;
this.contentAttaches = builder.contentAttaches;
this.sessionId = builder.sessionId;
}
public static Builder newBuilder() {
return new Builder();
}
public String getToAddress() {
return toAddress;
}
public String getCcAddress() {
return ccAddress;
}
public String getBccAddress() {
return bccAddress;
}
public String getFromAddress() {
return fromAddress;
}
public String getSubject() {
return subject;
}
public String getBodyContent() {
return bodyContent;
}
public EmailAttachment[] getAttaches() {
return attaches;
}
public String getFormat() {
return format;
}
public EmailAttachment[] getContentAttaches() {
return contentAttaches;
}
public String getSessionId() {
return sessionId;
}
public static final class Builder {
private String toAddress;
private String ccAddress;
private String bccAddress;
private String fromAddress;
private String subject;
private String bodyContent;
private EmailAttachment[] attaches;
private String format;
private EmailAttachment[] contentAttaches;
private String sessionId;
private Builder() {
}
public EmailBody build() {
if (toAddress == null) {
throw new IllegalArgumentException("toAddress should not be null");
}
if (subject == null) {
throw new IllegalArgumentException("subject should not be null");
}
if (bodyContent == null) {
throw new IllegalArgumentException("bodyContent should not be null");
}
return new EmailBody(this);
}
/**
* 设置收件人地址
*
* @param toAddress 收件人地址
* @return 建造者
*/
public Builder toAddress(String toAddress) {
this.toAddress = toAddress;
return this;
}
/**
* 设置抄送地址
*
* @param ccAddress 抄送地址
* @return 建造者
*/
public Builder ccAddress(@Nullable String ccAddress) {
this.ccAddress = ccAddress;
return this;
}
/**
* 设置密送地址
*
* @param bccAddress 密送地址
* @return 建造者
*/
public Builder bccAddress(@Nullable String bccAddress) {
this.bccAddress = bccAddress;
return this;
}
/**
* 设置发件人地址
*
* @param fromAddress 发件人地址
* @return 建造者
*/
public Builder fromAddress(@Nullable String fromAddress) {
this.fromAddress = fromAddress;
return this;
}
/**
* 设置主题
*
* @param subject 主题
* @return 建造者
*/
public Builder subject(String subject) {
this.subject = subject;
return this;
}
/**
* 设置正文
*
* @param bodyContent 正文
* @return 建造者
*/
public Builder bodyContent(String bodyContent) {
this.bodyContent = bodyContent;
return this;
}
/**
* 设置附件
*
* @param attaches 附件
* @return 建造者
*/
public Builder attaches(@Nullable EmailAttachment[] attaches) {
this.attaches = attaches;
return this;
}
/**
* 设置格式
*
* @param format 格式
* @return 建造者
*/
public Builder format(@Nullable String format) {
this.format = format;
return this;
}
/**
* 设置邮件正文显示的附件
*
* @param contentAttaches 邮件正文显示的附件
* @return 建造者
*/
public Builder contentAttaches(@Nullable EmailAttachment[] contentAttaches) {
this.contentAttaches = contentAttaches;
return this;
}
/**
* 设置报表的session id
*
* @param sessionId 报表的session id
* @return 建造者
*/
public Builder sessionId(@Nullable String sessionId) {
this.sessionId = sessionId;
return this;
}
}
}

162
src/main/java/com/fanruan/api/util/shell/SingleSmsBody.java

@ -0,0 +1,162 @@
package com.fanruan.api.util.shell;
import com.fr.base.sms.SMSManager;
import com.fr.json.JSONObject;
import org.jetbrains.annotations.Nullable;
/**
* 单个短信体
*
* @author vito
* @date 2019-07-24
*/
public class SingleSmsBody extends BaseSmsBody {
private String mobile;
private JSONObject para;
private String receiver;
private boolean needRecord;
private SingleSmsBody() {
}
/**
* 获取收集号码
*
* @return 手机号码
*/
public String getMobile() {
return mobile;
}
/**
* 获取参数
*
* @return 模板参数
*/
public JSONObject getPara() {
return para;
}
/**
* 获取接收者
*
* @return 接收者
*/
@Nullable
public String getReceiver() {
return receiver;
}
/**
* 是否需要记录
*
* @return 是否需要记录
*/
public boolean isNeedRecord() {
return needRecord;
}
public static Builder newBuilder() {
return new Builder();
}
@Override
public boolean send() throws Exception {
return SMSManager.getInstance().sendSMS(
getTemplateCode(),
getMobile(),
getPara(),
getReceiver(),
isNeedRecord());
}
public static final class Builder {
private String templateCode;
private String mobile;
private JSONObject para;
private String receiver;
private boolean needRecord;
private Builder() {
}
/**
* 设置模板代码
*
* @param templateCode 模板代码
* @return builder
*/
public Builder templateCode(String templateCode) {
this.templateCode = templateCode;
return this;
}
/**
* 设置手机号码
*
* @param mobile 手机号码
* @return builder
*/
public Builder mobile(String mobile) {
this.mobile = mobile;
return this;
}
/**
* 设置模板参数
*
* @param para 模板参数
* @return builder
*/
public Builder para(JSONObject para) {
this.para = para;
return this;
}
/**
* 设置接受对象可不传
*
* @param receiver 接受对象
* @return builder
*/
public Builder receiver(@Nullable String receiver) {
this.receiver = receiver;
return this;
}
/**
* 设置是否需要记录
*
* @param needRecord 需要记
* @return builder
*/
public Builder needRecord(boolean needRecord) {
this.needRecord = needRecord;
return this;
}
/**
* 构建
*
* @return 单个短信体
*/
public SingleSmsBody build() {
if (templateCode == null) {
throw new IllegalArgumentException("templateCode should not be null");
}
if (mobile == null) {
throw new IllegalArgumentException("mobile should not be null");
}
if (para == null) {
throw new IllegalArgumentException("para should not be null");
}
SingleSmsBody singleSmsBody = new SingleSmsBody();
singleSmsBody.setTemplateCode(templateCode);
singleSmsBody.para = this.para;
singleSmsBody.receiver = this.receiver;
singleSmsBody.needRecord = this.needRecord;
singleSmsBody.mobile = this.mobile;
return singleSmsBody;
}
}
}

31
src/test/java/com/fanruan/api/Prepare.java

@ -1,15 +1,7 @@
package com.fanruan.api;
import com.fr.config.dao.DaoContext;
import com.fr.config.dao.impl.LocalClassHelperDao;
import com.fr.config.dao.impl.LocalEntityDao;
import com.fr.config.dao.impl.LocalXmlEntityDao;
import com.fr.runtime.FineRuntime;
import com.fr.store.StateHubManager;
import com.fr.store.impl.MemoryLock;
import com.fr.store.impl.MemoryStore;
import com.fr.transaction.Configurations;
import com.fr.transaction.LocalConfigurationHelper;
import com.fanruan.api.env.EnvKit;
import com.fanruan.api.env.shell.ModuleShell;
import org.junit.After;
import org.junit.Before;
@ -19,26 +11,19 @@ import org.junit.Before;
* Created by richie on 2019-08-09
*/
public class Prepare {
private ModuleShell module;
@Before
public void start() {
FineRuntime.start();
DaoContext.setEntityDao(new LocalEntityDao());
DaoContext.setClassHelperDao(new LocalClassHelperDao());
DaoContext.setXmlEntityDao(new LocalXmlEntityDao());
Configurations.setHelper(new LocalConfigurationHelper());
StateHubManager.setStorage(new MemoryStore());
StateHubManager.setLock(new MemoryLock());
module = EnvKit.createLocalStartModule("");
module.start();
}
@After
public void stop() {
DaoContext.setEntityDao(null);
DaoContext.setClassHelperDao(null);
DaoContext.setXmlEntityDao(null);
Configurations.setHelper(null);
StateHubManager.setStorage(null);
StateHubManager.setLock(null);
if (module != null) {
module.stop();
}
}
}

49
src/test/java/com/fanruan/api/cal/CalculatorKitEnvTest.java

@ -0,0 +1,49 @@
package com.fanruan.api.cal;
import com.fanruan.api.Prepare;
import com.fr.invoke.Reflect;
import com.fr.log.FineLoggerFactory;
import com.fr.main.impl.WorkBook;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.report.cell.CellElementValueConverterRegistry;
import com.fr.stable.ActorConstants;
import com.fr.stable.ActorFactory;
import com.fr.web.core.ReportSessionIDInfor;
import com.fr.web.core.SessionPoolManager;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* 需要启动模块的算子单元测试
*
* @ClassName CalculatorKitEnvTest
* @Author zack
* @Date 2019/8/23
* @Version 10.0
*/
public class CalculatorKitEnvTest extends Prepare {
@Test
public void testSheetInterval() {
WorkBook tpl = new WorkBook();
Map paraMap = new HashMap(0);
String path = "/com/fanruan/api/report/sheets.cpt";
try {
tpl.readStream(CalculatorKitEnvTest.class.getResourceAsStream(path));
ResultWorkBook resultWorkBook = tpl.execute(paraMap, ActorFactory.getActor(ActorConstants.TYPE_WRITE));
ReportSessionIDInfor sessionIDInfor = new ReportSessionIDInfor(paraMap, path, ActorFactory.getActor(ActorConstants.TYPE_WRITE)).buildResultWorkBook(resultWorkBook);
String sessionId = Reflect.on(SessionPoolManager.class).call("addSessionIDInfor", sessionIDInfor).get();
CellElementValueConverterRegistry.complete();
Assert.assertEquals(111, CalculatorKit.createCalculator(sessionId, null).evalValue("sheet1!A1"));
Assert.assertEquals(222, CalculatorKit.createCalculator(sessionId, null).evalValue("sheet2!A1"));
Assert.assertEquals(333, CalculatorKit.createCalculator(sessionId, null).evalValue("SUM(sheet1!A1,sheet2!A1)"));
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
CellElementValueConverterRegistry.reset();
}
Assert.assertNotNull(tpl.getReport(0));
}
}

40
src/test/java/com/fanruan/api/cal/CalculatorKitTest.java

@ -0,0 +1,40 @@
package com.fanruan.api.cal;
import com.fr.general.FRLogger;
import com.fr.stable.script.CalculatorProvider;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
/**
* @ClassName CalculatorKitTest
* @Author zack
* @Date 2019/8/23
* @Version 10.0
*/
public class CalculatorKitTest {
@Test
public void testCalculatorCreate() {
CalculatorProvider calculator = CalculatorKit.createCalculator();
try {
Assert.assertEquals(3, calculator.evalValue("sum(1,2)"));
} catch (Exception e) {
FRLogger.getLogger().error(e.getMessage(), e);
}
}
@Test
public void testCalculatorCreateWithPara() {
Map paraMap = new HashMap();
paraMap.put("a", 1);
paraMap.put("b", 2);
CalculatorProvider calculator = CalculatorKit.createCalculator(paraMap);
try {
Assert.assertEquals(3, calculator.evalValue("sum(a,b)"));
} catch (Exception e) {
FRLogger.getLogger().error(e.getMessage(), e);
}
}
}

18
src/test/java/com/fanruan/api/cal/FormulaKitTest.java

@ -2,17 +2,17 @@ package com.fanruan.api.cal;
import com.fanruan.api.Prepare;
import com.fanruan.api.err.KitError;
import com.fr.base.Formula;
import com.fr.base.ParameterMapNameSpace;
import com.fr.script.Calculator;
import com.fr.stable.script.CalculatorProvider;
import com.fr.stable.script.NameSpace;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
/**
* @author richie
@ -43,4 +43,18 @@ public class FormulaKitTest extends Prepare {
Assert.fail();
}
}
@Test
public void testCheckFormulaContent() {
assertEquals(true, FormulaKit.checkFormulaContent(new Formula("")));
assertEquals(true, FormulaKit.checkFormulaContent(new Formula("SUM(1,1)")));
assertEquals(true, FormulaKit.checkFormulaContent(""));
assertEquals(false, FormulaKit.checkFormulaContent(("=SUM(1,1)")));
assertEquals(true, FormulaKit.checkFormulaContent(("SUM(1,1)")));
assertEquals(true, FormulaKit.checkFormulaContent(new Formula("=")));
assertEquals(false, FormulaKit.checkFormulaContent("="));
}
}

46
src/test/java/com/fanruan/api/function/FunctionKitTest.java

@ -0,0 +1,46 @@
package com.fanruan.api.function;
import com.fanruan.api.Prepare;
import com.fanruan.api.function.shell.FineFunc;
import com.fr.script.Calculator;
import com.fr.stable.UtilEvalError;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
/**
* @ClassName FunctionKitTest
* @Author zack
* @Date 2019/8/23
* @Version 10.0
*/
public class FunctionKitTest extends Prepare {
@Test
public void testFuncAdd() {
FunctionKit.removeFunc("com.fanruan.api.function.TestFunc");
FunctionKit.addFunc(new FineFunc("TestFunc", "com.fanruan.api.function.TestFunc"));
try {
assertEquals("OK", Calculator.createCalculator().evalValue("TESTFUNC()"));
} catch (UtilEvalError utilEvalError) {
}
}
@Test
public void testFuncRemove() {
FunctionKit.removeFunc("com.fanruan.api.function.TestFunc");
FunctionKit.addFunc(new FineFunc("TestFunc", "com.fanruan.api.function.TestFunc"));
FunctionKit.removeFunc("com.fr.sdk.FuncTest");
String result = "ERROR";
try {
result = Calculator.createCalculator().evalValue("TESTFUNC()").toString();
} catch (Throwable e) {
}
assertNotEquals("OK", result);
}
}

10
src/test/java/com/fanruan/api/function/TestFunc.java

@ -0,0 +1,10 @@
package com.fanruan.api.function;
import com.fr.script.AbstractFunction;
public class TestFunc extends AbstractFunction {
@Override
public Object run(Object[] objects) {
return "OK";
}
}

31
src/test/java/com/fanruan/api/report/analy/AnalyKitTest.java

@ -0,0 +1,31 @@
package com.fanruan.api.report.analy;
import com.fanruan.api.Prepare;
import com.fanruan.api.report.analy.data.TreeNode;
import com.fr.log.FineLoggerFactory;
import com.fr.main.impl.WorkBook;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.stable.ActorConstants;
import com.fr.stable.ActorFactory;
import org.junit.Assert;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
public class AnalyKitTest extends Prepare {
@Test
public void testTree() {
WorkBook tpl = new WorkBook();
Map<Integer, TreeNode> nodeMap = new HashMap<Integer, TreeNode>(0);
try {
tpl.readStream(AnalyKitTest.class.getResourceAsStream("/com/fanruan/api/report/tree.cpt"));
ResultWorkBook resultWorkBook = tpl.execute(java.util.Collections.EMPTY_MAP, ActorFactory.getActor(ActorConstants.TYPE_ANALYSIS));
nodeMap = AnalyKit.generateResultBookTree(resultWorkBook, 0);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
Assert.assertEquals(nodeMap.toString(), "{0=0#-1#[-1,1,3,8,14,19,25,31], 1=1#0#[-1,2], 3=3#0#[-1,4,5,6,7], 19=19#0#[-1,20,21,22,23,24], 8=8#0#[-1,9,10,11,12,13], 25=25#0#[-1,26,27,28,29,30], 14=14#0#[-1,15,16,17,18], 31=31#0#[-1,32,33,34,35,36,37,38,39]}");
}
}

27
src/test/java/com/fanruan/api/util/TransmissionKitTest.java

@ -0,0 +1,27 @@
package com.fanruan.api.util;
import com.fanruan.api.util.shell.BatchSmsBody;
import com.fanruan.api.util.shell.SingleSmsBody;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* @ClassName TransmissionKitTest
* @Author zack
* @Date 2019/8/23
* @Version 10.0
*/
public class TransmissionKitTest {
@Test
public void testSmsBody() {
try {
SingleSmsBody.newBuilder().mobile("").para(null).build();
BatchSmsBody.newBuilder().mobiles(null).build();
fail();
} catch (Exception e) {
assertTrue(true);
}
}
}

72
src/test/resources/com/fanruan/api/report/sheets.cpt

@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<WorkBook xmlVersion="20170720" releaseVersion="10.0.0">
<Report class="com.fr.report.worksheet.WorkSheet" name="sheet1">
<ReportPageAttr>
<HR/>
<FR/>
<HC/>
<FC/>
</ReportPageAttr>
<ColumnPrivilegeControl/>
<RowPrivilegeControl/>
<RowHeight defaultValue="723900">
<![CDATA[723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900]]></RowHeight>
<ColumnWidth defaultValue="2743200">
<![CDATA[2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200]]></ColumnWidth>
<CellElementList>
<C c="0" r="0">
<O t="I">
<![CDATA[111]]></O>
<PrivilegeControl/>
<Expand/>
</C>
</CellElementList>
<ReportAttrSet>
<ReportSettings headerHeight="0" footerHeight="0">
<PaperSetting/>
<Background name="ColorBackground" color="-1"/>
</ReportSettings>
</ReportAttrSet>
<PrivilegeControl/>
</Report>
<Report class="com.fr.report.worksheet.WorkSheet" name="sheet2">
<ReportPageAttr>
<HR/>
<FR/>
<HC/>
<FC/>
</ReportPageAttr>
<ColumnPrivilegeControl/>
<RowPrivilegeControl/>
<RowHeight defaultValue="723900">
<![CDATA[723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900]]></RowHeight>
<ColumnWidth defaultValue="2743200">
<![CDATA[2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200]]></ColumnWidth>
<CellElementList>
<C c="0" r="0">
<O t="I">
<![CDATA[222]]></O>
<PrivilegeControl/>
<Expand/>
</C>
</CellElementList>
<ReportAttrSet>
<ReportSettings headerHeight="0" footerHeight="0">
<PaperSetting/>
<Background name="ColorBackground" color="-1"/>
</ReportSettings>
</ReportAttrSet>
<PrivilegeControl/>
</Report>
<ReportParameterAttr>
<Attributes showWindow="true" delayPlaying="true" windowPosition="1" align="0" useParamsTemplate="true"/>
<PWTitle>
<![CDATA[参数]]></PWTitle>
</ReportParameterAttr>
<StyleList/>
<DesignerVersion DesignerVersion="KAA"/>
<PreviewType PreviewType="0"/>
<TemplateIdAttMark class="com.fr.base.iofile.attr.TemplateIdAttrMark">
<TemplateIdAttMark TemplateId="fbd148d4-72d8-4df8-957f-c99fee3ca9dc"/>
</TemplateIdAttMark>
</WorkBook>

247
src/test/resources/com/fanruan/api/report/tree.cpt

@ -0,0 +1,247 @@
<?xml version="1.0" encoding="UTF-8"?>
<WorkBook xmlVersion="20170720" releaseVersion="10.0.0">
<TableDataMap>
<TableData name="ds1" class="com.fr.data.impl.EmbeddedTableData">
<Parameters/>
<DSName>
<![CDATA[]]></DSName>
<ColumnNames>
<![CDATA[部门ID,,.,,上级ID,,.,,部门名称]]></ColumnNames>
<ColumnTypes>
<![CDATA[java.lang.String,java.lang.String,java.lang.String]]></ColumnTypes>
<RowData ColumnTypes="java.lang.String,java.lang.String,java.lang.String">
<![CDATA[?'/Dg_Cu[YYIf;5:]AK8_h86Z%"/nKu1SQ!.J;HWbkJs3/fC!!jHE*0RfCq;gI?q%#O=%*ar_
l-4Tu:V]AM`ZEuB_48NTTm6sSUEe5+e:6r?0T@s]At/n@s$(>&F.>LRf]A0MJBQQ"KZHgQo8EMn
@7Hs(LfRWKV((C<qe'q-:2S6?6LEq8-phC*cB]AWX`SX$OCbkp2a8k;&iRqnp/&dg8NVY<Q`Y
pc7n\tWRUq2\O&;jh-4l5CL0p>!-'"\IYO1394-67'^A,&J*BPY$tY:*s+7EK'XR4959PkQa
-MJK'B<hp2i^n?mQ0X0!=WRR7Uf$EU86.Y\7r@Y^S+T>.-h@+"Lk%jc3KmJ1K;M[I;_Ze`8`
E#*u'-WX$SVu6f~
]]></RowData>
</TableData>
<TableData name="Tree1" class="com.fr.data.impl.EmbeddedTableData">
<Parameters/>
<DSName>
<![CDATA[]]></DSName>
<ColumnNames>
<![CDATA[部门ID,,.,,上级ID,,.,,部门名称,,.,,FR_GEN_0,,.,,FR_GEN_1,,.,,FR_GEN_2]]></ColumnNames>
<ColumnTypes>
<![CDATA[java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String]]></ColumnTypes>
<RowData ColumnTypes="java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String">
<![CDATA[?'=YO_Cu\C5F8i^gPsf(U+F(b0Rt&e0b=Na!14$a3rck:\ohrM\YYR+ZK0luF7/i]Ah'0k]A1p
>Z[/8@QbMcc[;mbOAMAZ:E-bT]Ar`0YH#$D`bg'@npmN;JkUIYbSDj]ASjZRrk$=B/?jp7jY2+
qcnjdN=Q<?^-9N8A:6cR7WUA$3HiTTOBh+[^7j*Kkd\`"&4l5JLQ0pk_;)[Wgbj6-JEd0,@.
KLS3!PI@?(*?J]ASbk.WJh#6;Wmn'k,6UhDN?8M8El!8t.R>aN'#B`0CHe*XmCkRB7@ni<nPW
KZV6/:rO""DhW(!U&D#>-'(k((1bLt0<A'CkS<-VkK@nuF5ln452+Cd^>IXa+Y'e#`pddA+O
AiC#1J.qQtQC7]AKlE8;tbMa*_<!#1P$1J81A%U`p8-(mdJb&]AO8AkfI8aV@S^+0i\&@(%b>@
tVW13!Oj@[6Uf]Am^>'3aS$(+s1MVqXY)YhY[B~
]]></RowData>
</TableData>
<TableData name="Tree2" class="com.fr.data.impl.EmbeddedTableData">
<Parameters/>
<DSName>
<![CDATA[]]></DSName>
<ColumnNames>
<![CDATA[部门ID,,.,,上级ID,,.,,部门名称,,.,,FR_GEN_0,,.,,FR_GEN_1,,.,,FR_GEN_2]]></ColumnNames>
<ColumnTypes>
<![CDATA[java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String]]></ColumnTypes>
<RowData ColumnTypes="java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String,java.lang.String">
<![CDATA[?'=YO_Cu\C5F8i^gPsf(U+F(b0Rt&e0b=Na!14$a3rck:\ohrM\YYR+ZK0luF7/i]Ah'0k]A1p
>Z[/8@QbMcc[;mbOAMAZ:E-bT]Ar`0YH#$D`bg'@npmN;JkUIYbSDj]ASjZRrk$=B/?jp7jY2+
qcnjdN=Q<?^-9N8A:6cR7WUA$3HiTTOBh+[^7j*Kkd\`"&4l5JLQ0pk_;)[Wgbj6-JEd0,@.
KLS3!PI@?(*?J]ASbk.WJh#6;Wmn'k,6UhDN?8M8El!8t.R>aN'#B`0CHe*XmCkRB7@ni<nPW
KZV6/:rO""DhW(!U&D#>-'(k((1bLt0<A'CkS<-VkK@nuF5ln452+Cd^>IXa+Y'e#`pddA+O
AiC#1J.qQtQC7]AKlE8;tbMa*_<!#1P$1J81A%U`p8-(mdJb&]AO8AkfI8aV@S^+0i\&@(%b>@
tVW13!Oj@[6Uf]Am^>'3aS$(+s1MVqXY)YhY[B~
]]></RowData>
</TableData>
</TableDataMap>
<Report class="com.fr.report.worksheet.WorkSheet" name="sheet1">
<ReportPageAttr>
<HR/>
<FR/>
<HC/>
<FC/>
</ReportPageAttr>
<ColumnPrivilegeControl/>
<RowPrivilegeControl/>
<RowHeight defaultValue="723900">
<![CDATA[723900,723900,723900,723900,723900,723900,723900,723900,723900,723900,723900]]></RowHeight>
<ColumnWidth defaultValue="2743200">
<![CDATA[7772400,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200,2743200]]></ColumnWidth>
<CellElementList>
<C c="0" r="0" s="0">
<O t="DSColumn">
<Attributes dsName="Tree1" columnName="FR_GEN_0"/>
<Complex/>
<RG class="com.fr.report.cell.cellattr.core.group.FunctionGrouper"/>
<Parameters/>
</O>
<PrivilegeControl/>
<CellGUIAttr/>
<CellPageAttr/>
<Widget class="com.fr.report.web.button.form.TreeNodeToggleButton">
<WidgetAttr description="">
<PrivilegeControl/>
</WidgetAttr>
<Text>
<![CDATA[null]]></Text>
</Widget>
<Present class="com.fr.base.present.DictPresent">
<Dictionary class="com.fr.data.impl.TableDataDictionary">
<FormulaDictAttr ki="0" vi="2"/>
<TableDataDictAttr>
<TableData class="com.fr.data.impl.NameTableData">
<Name>
<![CDATA[ds1]]></Name>
</TableData>
</TableDataDictAttr>
</Dictionary>
</Present>
<Expand dir="0"/>
</C>
<C c="0" r="1" s="1">
<O t="DSColumn">
<Attributes dsName="Tree1" columnName="FR_GEN_1"/>
<Complex/>
<RG class="com.fr.report.cell.cellattr.core.group.FunctionGrouper"/>
<Parameters/>
</O>
<PrivilegeControl/>
<CellGUIAttr/>
<CellPageAttr/>
<Widget class="com.fr.report.web.button.form.TreeNodeToggleButton">
<WidgetAttr description="">
<PrivilegeControl/>
</WidgetAttr>
<Text>
<![CDATA[null]]></Text>
</Widget>
<HighlightList>
<Highlight class="com.fr.report.cell.cellattr.highlight.DefaultHighlight">
<Name>
<![CDATA[条件属性1]]></Name>
<Condition class="com.fr.data.condition.FormulaCondition">
<Formula>
<![CDATA[len($$$) = 0]]></Formula>
</Condition>
<HighlightAction class="com.fr.report.cell.cellattr.highlight.RowHeightHighlightAction"/>
</Highlight>
</HighlightList>
<Present class="com.fr.base.present.DictPresent">
<Dictionary class="com.fr.data.impl.TableDataDictionary">
<FormulaDictAttr ki="0" vi="2"/>
<TableDataDictAttr>
<TableData class="com.fr.data.impl.NameTableData">
<Name>
<![CDATA[ds1]]></Name>
</TableData>
</TableDataDictAttr>
</Dictionary>
</Present>
<Expand dir="0" leftParentDefault="false" left="A1"/>
</C>
<C c="0" r="2" s="2">
<O t="DSColumn">
<Attributes dsName="Tree1" columnName="FR_GEN_2"/>
<Complex/>
<RG class="com.fr.report.cell.cellattr.core.group.FunctionGrouper"/>
<Parameters/>
</O>
<PrivilegeControl/>
<CellGUIAttr/>
<CellPageAttr/>
<Widget class="com.fr.report.web.button.form.TreeNodeToggleButton">
<WidgetAttr description="">
<PrivilegeControl/>
</WidgetAttr>
<Text>
<![CDATA[null]]></Text>
</Widget>
<HighlightList>
<Highlight class="com.fr.report.cell.cellattr.highlight.DefaultHighlight">
<Name>
<![CDATA[条件属性1]]></Name>
<Condition class="com.fr.data.condition.FormulaCondition">
<Formula>
<![CDATA[len($$$) = 0]]></Formula>
</Condition>
<HighlightAction class="com.fr.report.cell.cellattr.highlight.RowHeightHighlightAction"/>
</Highlight>
</HighlightList>
<Present class="com.fr.base.present.DictPresent">
<Dictionary class="com.fr.data.impl.TableDataDictionary">
<FormulaDictAttr ki="0" vi="2"/>
<TableDataDictAttr>
<TableData class="com.fr.data.impl.NameTableData">
<Name>
<![CDATA[ds1]]></Name>
</TableData>
</TableDataDictAttr>
</Dictionary>
</Present>
<Expand dir="0" leftParentDefault="false" left="A2"/>
</C>
</CellElementList>
<ReportAttrSet>
<ReportSettings headerHeight="0" footerHeight="0">
<PaperSetting/>
<Background name="ColorBackground" color="-1"/>
</ReportSettings>
<Header reportPageType="0">
<Background name="NullBackground"/>
<LeftList/>
<CenterList/>
<RightList/>
</Header>
<Footer reportPageType="0">
<Background name="NullBackground"/>
<LeftList/>
<CenterList/>
<RightList/>
</Footer>
</ReportAttrSet>
<PrivilegeControl/>
</Report>
<ReportParameterAttr>
<Attributes showWindow="true" delayPlaying="true" windowPosition="1" align="0" useParamsTemplate="false"/>
<PWTitle>
<![CDATA[参数]]></PWTitle>
</ReportParameterAttr>
<StyleList>
<Style imageLayout="1">
<FRFont name="SimSun" style="0" size="72"/>
<Background name="ColorBackground" color="-6697729"/>
<Border>
<Top style="1" color="-13382452"/>
<Bottom style="1" color="-13382452"/>
<Left style="1" color="-13382452"/>
<Right style="1" color="-13382452"/>
</Border>
</Style>
<Style horizontal_alignment="0" imageLayout="1">
<FRFont name="SimSun" style="0" size="72"/>
<Background name="ColorBackground" color="-3342388"/>
<Border>
<Top style="1" color="-13382452"/>
<Bottom style="1" color="-13382452"/>
<Left style="1" color="-13382452"/>
<Right style="1" color="-13382452"/>
</Border>
</Style>
<Style horizontal_alignment="4" imageLayout="1">
<FRFont name="SimSun" style="0" size="72"/>
<Background name="ColorBackground" color="-52"/>
<Border>
<Top style="1" color="-13382452"/>
<Bottom style="1" color="-13382452"/>
<Left style="1" color="-13382452"/>
<Right style="1" color="-13382452"/>
</Border>
</Style>
</StyleList>
<DesignerVersion DesignerVersion="KAA"/>
<PreviewType PreviewType="2"/>
<TemplateIdAttMark class="com.fr.base.iofile.attr.TemplateIdAttrMark">
<TemplateIdAttMark TemplateId="f5d5a206-30a6-4709-8400-49dd95b5c57d"/>
</TemplateIdAttMark>
</WorkBook>
Loading…
Cancel
Save