forked from fanruan/finekit
zack
5 years ago
26 changed files with 1692 additions and 29 deletions
@ -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(); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
|
||||
} |
@ -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(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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(); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
@ -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; |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -1,44 +1,29 @@
|
||||
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; |
||||
|
||||
/** |
||||
* @author richie |
||||
* @version 10.0 |
||||
* Created by richie on 2019-08-09 |
||||
* 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(); |
||||
} |
||||
} |
||||
|
||||
} |
||||
|
@ -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)); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
|
||||
} |
@ -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"; |
||||
} |
||||
} |
@ -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]}"); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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> |
@ -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…
Reference in new issue