FormulaUtils.java 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
  1. package com.mixsmart.utils;
  2. import cn.hutool.log.StaticLog;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.jfireel.expression.Expression;
  6. import org.apache.poi.hssf.usermodel.HSSFDataFormatter;
  7. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  8. import org.apache.poi.ss.usermodel.*;
  9. import java.awt.Color;
  10. import org.jfree.chart.ChartFactory;
  11. import org.jfree.chart.ChartPanel;
  12. import org.jfree.chart.ChartUtils;
  13. import org.jfree.chart.JFreeChart;
  14. import org.jfree.chart.axis.NumberAxis;
  15. import org.jfree.chart.axis.NumberTickUnit;
  16. import org.jfree.chart.plot.PlotOrientation;
  17. import org.jfree.chart.plot.ValueMarker;
  18. import org.jfree.chart.plot.XYPlot;
  19. import org.jfree.chart.renderer.xy.XYSplineRenderer;
  20. import org.jfree.chart.title.TextTitle;
  21. import org.jfree.data.xy.DefaultXYDataset;
  22. import org.jfree.data.xy.XYSeries;
  23. import org.jfree.data.xy.XYSeriesCollection;
  24. import org.jsoup.Jsoup;
  25. import org.jsoup.nodes.Document;
  26. import org.springblade.core.tool.utils.CollectionUtil;
  27. import org.springblade.core.tool.utils.Func;
  28. import org.springblade.core.tool.utils.IoUtil;
  29. import org.springblade.core.tool.utils.StringPool;
  30. import org.springblade.manager.bean.TableInfo;
  31. import org.springblade.manager.dto.Coords;
  32. import org.springblade.manager.dto.ElementData;
  33. import org.springblade.manager.dto.FormData;
  34. import org.springblade.manager.dto.LocalVariable;
  35. import org.springblade.manager.entity.Formula;
  36. import org.springblade.manager.utils.FileUtils;
  37. import java.awt.*;
  38. import java.awt.Font;
  39. import java.awt.Shape;
  40. import java.awt.geom.Ellipse2D;
  41. import java.io.*;
  42. import java.util.*;
  43. import java.util.List;
  44. import java.util.concurrent.atomic.AtomicInteger;
  45. import java.util.regex.Matcher;
  46. import java.util.regex.Pattern;
  47. import java.util.stream.Collectors;
  48. import java.util.stream.IntStream;
  49. import java.util.stream.Stream;
  50. import static java.util.regex.Pattern.*;
  51. /**
  52. * @author yangyj
  53. * @Date 2022/7/14 15:55
  54. * @description TODO
  55. */
  56. public class FormulaUtils {
  57. public static Map<String,Object> triangleSquare(Object ranges){
  58. Map<String,Object> map =new HashMap<>();
  59. if(StringUtils.isEmpty(ranges)){
  60. //z的默认取值范围
  61. ranges="(0,15)";
  62. }
  63. Matcher m = RegexUtils.matcher("(\\-?\\d+)(\\D)(\\+?\\d+)",ranges.toString());
  64. if(m.find()) {
  65. System.out.println();
  66. int min = StringUtils.handObj2Integer(m.group(1));
  67. int max = StringUtils.handObj2Integer(m.group(3));
  68. Integer[] r = pythagorean(min, max);
  69. map.put("X", String.valueOf(r[0]));
  70. map.put("Y", String.valueOf(r[1]));
  71. map.put("Z", String.valueOf(r[2]));
  72. }
  73. return map;
  74. }
  75. /**
  76. * @Description 字符串相似度
  77. * @Param [s1, s2]
  78. * @return double
  79. * @Author yangyj
  80. * @Date 2023.04.12 18:01
  81. **/
  82. public static double getJaccardSimilarity(String s1, String s2) {
  83. Set<Character> set1 = new HashSet<>();
  84. Set<Character> set2 = new HashSet<>();
  85. for (char c : s1.toCharArray()) {
  86. set1.add(c);
  87. }
  88. for (char c : s2.toCharArray()) {
  89. set2.add(c);
  90. }
  91. Set<Character> intersection = new HashSet<>(set1);
  92. intersection.retainAll(set2);
  93. Set<Character> union = new HashSet<>(set1);
  94. union.addAll(set2);
  95. return (double) intersection.size() / union.size();
  96. }
  97. public static Double similarity(String s1,String s2){
  98. return getJaccardSimilarity(parseItemName(s1),parseItemName(s2));
  99. }
  100. /**
  101. * result[0]^2+result[1]^2=result[2]^2 result[] 元素均为正整数
  102. */
  103. public static Integer[] pythagorean(Integer min,Integer max){
  104. Integer[] result = null;
  105. List<Integer[]> list = new ArrayList<>();
  106. for(int i=1;i<=max;i++){
  107. for(int j=1;j<=max;j++){
  108. double tmp = Math.sqrt(Math.pow(i,2)+Math.pow(j,2));
  109. int z= (int) Math.round(tmp);
  110. if(min<z&&z<=max){
  111. Integer[] arr = new Integer[]{ i,j,z};
  112. list.add(arr);
  113. }
  114. }
  115. }
  116. if(ListUtils.isNotEmpty(list)){
  117. Random rm = new Random();
  118. result = list.get(rm.nextInt(list.size()));
  119. }
  120. return result;
  121. }
  122. /*public static void main(String[] args) {
  123. FormData fd = new FormData();
  124. fd.setEName("1111");
  125. List<ElementData> list = new ArrayList<>();
  126. list.add(new ElementData(1,1,1));
  127. test(fd);
  128. System.out.println(fd.getEName());
  129. }*/
  130. public static void write(FormData fd, Object data,Boolean nullOrBlank ){
  131. if(Func.isEmpty(fd.getValues())){
  132. /*无定位信息不写入*/
  133. return;
  134. }
  135. /*一个单元格且存在多张,全部设置为自动拓展 20230816*/
  136. if(fd.getCoordsList().size()==1&&fd.getValues().size()>1&&fd.getFormula()!=null){
  137. fd.getFormula().setOutm(Formula.FULL);
  138. }
  139. /*写入前清空内容*/
  140. fd.getValues().forEach(t->t.setValue(null));
  141. if(data instanceof List){
  142. List<Object> values = (List<Object>) data;
  143. if(!nullOrBlank){
  144. values=values.stream().filter(StringUtils::isNotEmpty).collect(Collectors.toList());
  145. }
  146. if(values.size()>fd.getValues().size()){
  147. /*当生成的数据超过实际容量的时候,会自动追加页数*/
  148. if(fd.getCoordsList().size()==1){
  149. if(values.stream().filter(CustomFunction::containsZH).anyMatch(e->e.toString().contains("\n"))){
  150. fd.getValues().get(0).setValue(values.stream().filter(Objects::nonNull).map(Object::toString).collect(Collectors.joining()));
  151. }else{
  152. fd.getValues().get(0).setValue(values.stream().map(StringUtils::handleNull).collect(Collectors.joining("、")));
  153. }
  154. }else{
  155. // copy(fd,values);
  156. for(int n=0;n<fd.getValues().size();n++){
  157. fd.getValues().get(n).setValue(values.get(n));
  158. }
  159. List<Object> overList=values.stream().skip(fd.getValues().size()).collect(Collectors.toList());
  160. List<Coords> coordsList = fd.getCoordsList();
  161. int addPage=(int)Math.ceil((double)overList.size()/(double)coordsList.size());
  162. fd.setAddPages(addPage);
  163. ElementData last =fd.getValues().get(fd.getValues().size()-1);
  164. int indexBase=last.getIndex()+1;
  165. List<ElementData> addList= new ArrayList<>();
  166. for(int i=0;i<addPage;i++){
  167. for(int j=0;j<coordsList.size();j++){
  168. /*超页就尽管写进去,格式化阶段再加表*/
  169. Coords coords = coordsList.get(j);
  170. Object v=null;
  171. int st=i*coordsList.size()+j;
  172. if(st<overList.size()){
  173. v= overList.get(st);
  174. }
  175. addList.add(new ElementData(indexBase+i,last.getGroupId(),v,coords.getX(),coords.getY()));
  176. }
  177. }
  178. fd.getValues().addAll(addList);
  179. }
  180. }else{
  181. for(int n=0;n<values.size();n++){
  182. fd.getValues().get(n).setValue(values.get(n));
  183. }
  184. }
  185. }else{
  186. if(Formula.FULL.equals(fd.getFormula().getOutm())){
  187. /*填充策略*/
  188. fd.getValues().forEach(e->e.setValue(data));
  189. }else{
  190. fd.getValues().get(0).setValue(data);
  191. }
  192. }
  193. fd.setUpdate(1);
  194. }
  195. public static List<TableInfo> getTableInfoList(JSONArray dataArray) {
  196. if (dataArray != null && !dataArray.isEmpty()) {
  197. List<TableInfo> result = new ArrayList<>();
  198. for (int m = 0; m < dataArray.size(); m++) {
  199. TableInfo tableInfo = new TableInfo();
  200. JSONObject dataInfo2 = dataArray.getJSONObject(m);
  201. //
  202. tableInfo.setContractId(dataInfo2.getString("contractId"));
  203. tableInfo.setPkeyId(dataInfo2.getString("pkeyId"));
  204. tableInfo.setProjectId(dataInfo2.getString("projectId"));
  205. //huangjn 填报的类型,施工或监理
  206. tableInfo.setClassify(dataInfo2.getString("classify"));
  207. //设置首件信息
  208. setFirstData(dataInfo2, tableInfo);
  209. // //设置日志信息
  210. setTheLogData(dataInfo2, tableInfo);
  211. dataInfo2.fluentRemove("contractId")
  212. .fluentRemove("pkeyId")
  213. .fluentRemove("p_key_id")
  214. .fluentRemove("projectId")
  215. .fluentRemove("classify")
  216. .fluentRemove("pickerKey")
  217. .fluentRemove("id")
  218. .fluentRemove("isFirst")
  219. .fluentRemove("firstNodeId")
  220. .fluentRemove("isTheLog")
  221. .fluentRemove("theLogId")
  222. .fluentRemove("linkTabIds")
  223. .fluentRemove("recordTime")
  224. .fluentRemove("businessId")
  225. .fluentRemove("sourceUrl")
  226. .fluentRemove("pdfUrl")
  227. .fluentRemove("firstFileName")
  228. .fluentRemove("");
  229. // 计算数据
  230. LinkedHashMap<String, List<String>> dataMap = dataInfo2.keySet().stream().filter(e -> e.contains("__")).collect(Collectors.groupingBy(e -> e.split("__")[0], LinkedHashMap<String, List<String>>::new, Collectors.toList()));
  231. LinkedHashMap<String, String> dataMap2 = new LinkedHashMap<>();
  232. // 字段组合
  233. for (String k : dataMap.keySet()) {
  234. if (dataMap.get(k).size() > 1 && !dataMap.get(k).contains("000Z")) {
  235. String[] ziduan = dataMap.get(k).toArray(new String[]{});
  236. String temp = "";
  237. for (int i = 0; i < ziduan.length - 1; i++) {
  238. for (int j = 0; j < ziduan.length - i - 1; j++) {
  239. Integer tr = Integer.parseInt((ziduan[j].split("__")[1]).split("_")[0]);
  240. Integer td = Integer.parseInt(ziduan[j].split("__")[1].split("_")[1]);
  241. Integer tr_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[0]);
  242. Integer td_1 = Integer.parseInt(ziduan[j + 1].split("__")[1].split("_")[1]);
  243. if (tr > tr_1 && td == td_1) { //纵向排序
  244. temp = ziduan[j];
  245. ziduan[j] = ziduan[j + 1];
  246. ziduan[j + 1] = temp;
  247. }
  248. }
  249. }
  250. String lastStr = dataInfo2.getString(ziduan[0]) + "_^_" + ziduan[0].split("__")[1];
  251. for (int i = 1; i < ziduan.length; i++) {
  252. String keyData = dataInfo2.getString(ziduan[i]);
  253. if (!keyData.equals("")) {
  254. lastStr += "☆" + dataInfo2.getString(ziduan[i]) + "_^_" + ziduan[i].split("__")[1];
  255. }
  256. }
  257. dataMap2.put(k, lastStr);
  258. } else {
  259. String dataVal = dataInfo2.getString(dataMap.get(k).get(0));
  260. dataMap2.put(k, dataVal + "_^_" + dataMap.get(k).get(0).split("__")[1]);
  261. }
  262. }
  263. dataMap2.put("p_key_id", tableInfo.getPkeyId());
  264. tableInfo.setDataMap(dataMap2);
  265. result.add(tableInfo);
  266. }
  267. return result;
  268. }
  269. return null;
  270. }
  271. public static void setFirstData(JSONObject dataInfo2, TableInfo tableInfo) {
  272. //huangjn 判断是否是首件
  273. if (dataInfo2.containsKey("isFirst")) {
  274. tableInfo.setIsFirst(dataInfo2.getString("isFirst"));
  275. }
  276. //huangjn 判断是否是首件
  277. //首件资料绑定的节点
  278. if (dataInfo2.containsKey("firstNodeId")) {
  279. tableInfo.setFirstNodeId(dataInfo2.getString("firstNodeId"));
  280. }
  281. //首件ID(编辑时有值,新增时为空)
  282. if (dataInfo2.containsKey("firstId")) {
  283. tableInfo.setFirstId(dataInfo2.getString("firstId"));
  284. }
  285. //源文件
  286. if (dataInfo2.containsKey("sourceUrl")) {
  287. tableInfo.setSourceUrl(dataInfo2.getString("sourceUrl"));
  288. }
  289. //pdfUrl
  290. if (dataInfo2.containsKey("pdfUrl")) {
  291. tableInfo.setPdfUrl(dataInfo2.getString("pdfUrl"));
  292. }
  293. //文件名称
  294. if (dataInfo2.containsKey("firstFileName")) {
  295. tableInfo.setFirstFileName(dataInfo2.getString("firstFileName"));
  296. }
  297. //关联的信息
  298. if (dataInfo2.containsKey("linkProcessList")) {
  299. tableInfo.setLinkProcessList(dataInfo2.getJSONArray("linkProcessList"));
  300. }
  301. }
  302. /**
  303. * 设置日志信息
  304. */
  305. public static void setTheLogData(JSONObject dataInfo2, TableInfo tableInfo) {
  306. //huangjn 判断是否是日志
  307. if (dataInfo2.containsKey("isTheLog")) {
  308. tableInfo.setIsTheLog(dataInfo2.getString("isTheLog"));
  309. }
  310. //huangjn 判断是否是日志
  311. //huangjn 日志ID
  312. if (dataInfo2.containsKey("theLogId")) {
  313. tableInfo.setTheLogId(dataInfo2.getString("theLogId"));
  314. }
  315. //huangjn 日志ID
  316. //huangjn 日志勾选的工序
  317. if (dataInfo2.containsKey("linkTabIds")) {
  318. tableInfo.setLinkTabIds(dataInfo2.getJSONArray("linkTabIds"));
  319. }
  320. //huangjn 日志勾选的工序
  321. //huangjn 日志所选时间
  322. if (dataInfo2.containsKey("recordTime")) {
  323. tableInfo.setRecordTime(dataInfo2.getString("recordTime"));
  324. }
  325. //huangjn 日志所选时间
  326. //huangjn 每份填报数据的id,目前日志专用
  327. if (dataInfo2.containsKey("id")) {
  328. tableInfo.setBusinessId(dataInfo2.getString("id"));
  329. }
  330. //huangjn 每份填报数据的id,目前日志专用
  331. }
  332. /**从元素名称中解析项目名称,细化项目匹配用*/
  333. public static String parseItemName(String eName){
  334. if (StringUtils.isEmpty(eName)) {
  335. return eName;
  336. }
  337. String str = eName.replaceAll("\\s", "");
  338. Pattern pattern = compile("[((_]");
  339. String[] candidate = pattern.split(str);
  340. String regex = "[^\\u4e00-\\u9fa5]+";
  341. Pattern p = compile(regex);
  342. return Arrays.stream(candidate)
  343. .filter(s -> !isContainKeywords(s))
  344. .map(s -> filterString(s, p))
  345. .collect(Collectors.joining());
  346. }
  347. /*A15检查内容专用*/
  348. public static String checkItemName(String eName){
  349. if (StringUtils.isEmpty(eName)) {
  350. return eName;
  351. }
  352. /*分割字符串,选取第一个匹配的子串*/
  353. String str = eName.replaceAll("\\s", "");
  354. Pattern pattern = compile("[((_]");
  355. String[] candidate = pattern.split(str);
  356. String regex = "[^\\u4e00-\\u9fa5]+";
  357. return Arrays.stream(candidate).map(s->s.replaceAll(regex,"")).distinct().filter(StringUtils::isNotEmpty).filter(s->!isContainKeywords2(s)).findFirst().orElse("");
  358. }
  359. private static String filterString(String s, Pattern p) {
  360. s=s.replaceAll("【[^【】]+】","");
  361. Matcher matcher = p.matcher(s);
  362. return matcher.replaceAll("").replaceAll(getRegex(), "").replaceAll("(设计|合格).*","");
  363. }
  364. private static String getRegex() {
  365. return "(在合格标准内|满足设计要求|质量评定|评定|判定|项目|总数|抽测|实测|偏差|尺量)";
  366. }
  367. private static boolean isContainKeywords(String s) {
  368. List<String> keywords = Arrays.asList( ":", "个","附录","抽查","测","求","小于","大于","检查","仪","按","不","各","记录","且","规定","值或实");
  369. return keywords.stream().anyMatch(s::contains);
  370. }
  371. private static boolean isContainKeywords2(String s) {
  372. List<String> keywords = Arrays.asList( "实测项目");
  373. return keywords.stream().anyMatch(s::contains);
  374. }
  375. public static List<String> itemNames =Arrays.asList(
  376. ""
  377. ,"压 实 度 (%)下路床 特重、极重交通荷载等级 设计值"
  378. ,"1△_压 实 度 (%)_下路床_轻、中及重交通 荷载等级_0.3m~0.8m_≧96_≧95_≧94_实测值或实测偏差值"
  379. ,"1△_压 实 度 (%)_下路提_轻、中及重交通 荷载等级_&gt;1.5m_≧93_≧92_≧90_实测值或实测偏差值"
  380. ,"1△_压 实 度 (%)_上路提_轻、中及重交通 荷载等级_0.8m~1.5m_≧94_≧94_≧93_实测值或实测偏差值"
  381. ,"压 实 度 (%)下路提 轻、中及重交通荷载等级 设计值"
  382. ,"压 实 度 (%)下路床 特重、极重交通荷载等级 合格率"
  383. ,"压 实 度 (%)下路提 轻、中及重交通荷载等级\t合格率"
  384. ,"5△_保护层 厚度 (mm)_基础、锚碇、墩台身、墩柱_±10_实测值或实测偏差值"
  385. ,"钢筋骨架尺寸宽、高或直径 (mm)_尺量:按骨架总数30%抽测_±5_实测值或实测偏差值"
  386. ,"钢筋骨架尺寸长 (mm)_±10_尺量:按骨架总数30%抽测_实测值或实测偏差值"
  387. , "受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑 设计值"
  388. ,"受力钢筋间距 (mm)同排 梁、板、拱肋及拱上建筑 合格率"
  389. ," 箍筋、构造钢筋、螺旋筋间距(mm) 设计值"
  390. ,"箍筋、构造钢筋、螺旋筋间距(mm) 合格率"
  391. ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格判定"
  392. ,"实测项目_桩位 (mm)_群桩_≤100_实测值或实测偏差值"
  393. ,"实测项目_桩位 (mm)_排架桩_实测值或实测偏差值"
  394. ,"实测项目_桩位 (mm)_排架桩_质量评定_合格判定"
  395. ,"实测项目_桩位 (mm)_群桩_≤100_质量评定_合格率(%)"
  396. ,"实测项目_桩位 (mm)_排架桩_质量评定_合格率(%)"
  397. ,"3△_支座高程(mm)_满足设计要求;设 计未要求时±5_水准仪:测每支座中心线_实测值或实测偏差值"
  398. ,"基底承载力(KPa)_不小于设计_直观或动力触探试验_实测值或实测偏差值"
  399. ,"实 测 项 目_花卉数量_满足设计要求_实测值或实测偏差值"
  400. ,"实 测 项 目_2△_草坪、草本地被覆盖率(%)_取弃土场绿 地_≥90_实测值或实测偏差值"
  401. ,"轴线偏位(mm)_全站仪:20m检查3点_实测值或实测偏差值"
  402. ,"1△_基材混合物喷射厚度(mm)_设计厚度±10_实测值或实测偏差值"
  403. ,"1△_混凝土强度 (MPA)_在合格标准内_按附录D检查_实测值或实测偏差值"
  404. ,"边坡坡度_不陡于设计值_水准仪:每200m测2点,且不少于5点_实测值或实测偏差值"
  405. ,"几何尺寸(mm)_±50_尺量:长、宽、高、壁厚各2点_实测值或实测偏差值"
  406. ,"4△_桩长(mm)_不小于设计_查施工记录_实测值或偏差值"
  407. ,"单桩每延米喷粉 (浆)量_不小于设计_查施工记录_实测值或偏差值"
  408. ,"搭接宽度(mm)_≥150【纵向】_尺量:抽查2%_实测值或实测偏差值",
  409. "搭接宽度(mm)_≥50(横向)_尺量:抽查2%_实测值或实测偏差值"
  410. ,"竖直度(mm)_挖孔桩_0.5%桩长,且≤200_铅锤线:每桩检测_实测值或实测偏差值"
  411. , "2△_压浆压力值 (Mpa)_满足施工技术 规范规定_查油压表读书;每管道检查_实测值或实测偏差值"
  412. , "基底承载力(KPa)_不小于设计_实测值或实测偏差值"
  413. ,"1△_受力钢筋间距 (mm)_两排以上间距_±5_实测值或实测偏差值"
  414. );
  415. /* public static void main(String[] args) {
  416. // itemNames.stream().map(FormulaUtils::parseItemName).forEach(System.out::println);
  417. itemNames.stream().map(FormulaUtils::checkItemName).forEach(System.out::println);
  418. }*/
  419. /**
  420. * @Description 深度拷贝
  421. * @Param [originalList]
  422. * @return java.util.List<T>
  423. * @Author yangyj
  424. * @Date 2023.04.28 14:18
  425. **/
  426. public static <T extends Serializable> List<T> copyList(List<T> originalList) {
  427. try {
  428. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  429. ObjectOutputStream oos = new ObjectOutputStream(baos);
  430. oos.writeObject(originalList);
  431. oos.close();
  432. ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
  433. ObjectInputStream ois = new ObjectInputStream(bais);
  434. @SuppressWarnings("unchecked")
  435. List<T> copiedList = (List<T>) ois.readObject();
  436. ois.close();
  437. return copiedList;
  438. } catch (Exception e) {
  439. e.printStackTrace();
  440. }
  441. return null;
  442. }
  443. public static Object getValue(Cell cell) {
  444. if (cell != null) {
  445. switch (cell.getCellTypeEnum()) {
  446. case STRING:
  447. return cell.getStringCellValue() == null ? null : cell.getStringCellValue().trim();
  448. case NUMERIC:
  449. HSSFDataFormatter dataFormatter = new HSSFDataFormatter();
  450. return dataFormatter.formatCellValue(cell);
  451. case BOOLEAN:
  452. return cell.getBooleanCellValue();
  453. case ERROR:
  454. return cell.getErrorCellValue();
  455. case FORMULA:
  456. try {
  457. return cell.getStringCellValue();
  458. } catch (IllegalStateException e) {
  459. return cell.getNumericCellValue();
  460. }
  461. default:
  462. cell.setCellType(CellType.STRING);
  463. return cell.getStringCellValue() == null ? null : cell.getStringCellValue().trim();
  464. }
  465. }
  466. return null;
  467. }
  468. public static List<ElementData> getElementDataList(String coords,String values){
  469. if(StringUtils.isNotEmpty(coords,values)){
  470. List<Coords> coordsList = Stream.of(coords).flatMap(s -> Arrays.stream(s.split(";"))).map(s -> {
  471. String[] xy = s.split("_");
  472. return new Coords(xy[1], xy[0]);
  473. }).collect(Collectors.toList());
  474. return str2ElementData(values,coordsList,null,null);
  475. }
  476. return Collections.emptyList();
  477. }
  478. public static List<ElementData> str2ElementData(String pg, List<Coords> coordsList ,String code,Integer index){
  479. List<ElementData> eds = new ArrayList<>();
  480. if(StringUtils.isNotEmpty(pg)&&ListUtils.isNotEmpty(coordsList)) {
  481. if(code==null){
  482. code="code";
  483. }
  484. if(index==null){
  485. index=1;
  486. }
  487. String[] val = pg.split("☆");
  488. Map<String, Object> tmpMap = new LinkedHashMap<>();
  489. for (String s : val) {
  490. String[] t = s.split("_\\^_");
  491. String[] c = t[1].split("_");
  492. tmpMap.put(StringUtils.join(code, 0, index, Func.toInt(c[1]), Func.toInt(c[0]), StringPool.AT), t[0]);
  493. }
  494. for (Coords c : coordsList) {
  495. Object data = null;
  496. String key = StringUtils.join(code, 0, index, c.getX(), c.getY(), StringPool.AT);
  497. if (tmpMap.containsKey(key)) {
  498. data = tmpMap.get(key);
  499. }
  500. eds.add(new ElementData(index, 0, data, c.getX(), c.getY()));
  501. }
  502. }
  503. return eds;
  504. }
  505. /**
  506. * @Description Poi 动态执行公式 测试
  507. * @Param [url]
  508. * @Author yangyj
  509. * @Date 2023.05.05 14:28
  510. **/
  511. public static void evaluateFormulaCell(String url) {
  512. try {
  513. url="C:/Users/yangyj/Desktop/test.xlsx";
  514. Workbook workbook = WorkbookFactory.create(new File(url));
  515. Sheet sheet = workbook.getSheetAt(0);
  516. Cell cell = sheet.getRow(0).getCell(0);
  517. FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator();
  518. CellType cellType = evaluator.evaluateFormulaCellEnum(cell);
  519. if (cellType == CellType.NUMERIC) {
  520. double value = cell.getNumericCellValue();
  521. System.out.println("公式计算结果:" + value);
  522. } else if (cellType == CellType.STRING) {
  523. String value = cell.getStringCellValue();
  524. System.out.println("公式计算结果:" + value);
  525. }
  526. cell.setCellFormula("B1+C1+D1");
  527. evaluator.clearAllCachedResultValues();
  528. cellType = evaluator.evaluateFormulaCellEnum(cell);
  529. if (cellType == CellType.NUMERIC) {
  530. double value = cell.getNumericCellValue();
  531. System.out.println("公式计算结果:" + value);
  532. } else if (cellType == CellType.STRING) {
  533. String value = cell.getStringCellValue();
  534. System.out.println("公式计算结果:" + value);
  535. }
  536. }catch (IOException | InvalidFormatException e){
  537. e.printStackTrace();
  538. }
  539. }
  540. public static Map<String, String> getElementCell(String uri){
  541. return getElementCell(uri,null);
  542. }
  543. public static Map<String, String> getElementCell(String uri,String key) {
  544. try {
  545. InputStream inputStreamByUrl = FileUtils.getInputStreamByUrl(uri);
  546. String filter=" [keyname]";
  547. if(Func.isNotBlank(key)){
  548. filter="[keyname^="+key+"__]";
  549. }
  550. Document document=Jsoup.parse(IoUtil.readToString(inputStreamByUrl));
  551. Map<String,String> result= document
  552. .select("table").first()
  553. .select(filter).stream()
  554. .map(d -> d.attr("keyname")).filter(StringUtils::isNotEmpty).map(e -> e.split("__"))
  555. .collect(
  556. Collectors.toMap(
  557. b -> b[0],
  558. b -> b[1],
  559. (v1, v2) -> v1 + ";" + v2
  560. )
  561. );
  562. if(result.size()>0){
  563. for(Map.Entry<String,String> entry:result.entrySet()){
  564. entry.setValue(FormulaUtils.coordsSorted(entry.getValue()));
  565. }
  566. }
  567. return result;
  568. }catch (Exception e){
  569. e.printStackTrace();
  570. return new HashMap<>();
  571. }
  572. }
  573. /* public static void main(String[] args) {
  574. Map<String,String> map=getElementCell("/www/wwwroot/Users/hongchuangyanfa/Desktop/privateUrl/1688447882195107840.html","key_31");
  575. System.out.println(map);
  576. }*/
  577. /**
  578. * @Description 定位信息排序
  579. * @Param [coords]
  580. * @return java.lang.String
  581. * @Author yangyj
  582. * @Date 2023.07.11 15:39
  583. **/
  584. public static String coordsSorted(String coords){
  585. if(StringUtils.isNotEmpty(coords)){
  586. List<String> dataList=Arrays.asList(coords.split(";"));
  587. if(dataList.size()>2){
  588. LinkedList<Integer> list=dataList.stream().map(e->e.split("_")[1]).distinct().map(Integer::parseInt).sorted(Comparator.comparingInt(e->e)).collect(Collectors.toCollection(LinkedList::new));
  589. if(list.getLast()-list.getFirst()>list.size()-1){
  590. coords=dataList.stream()
  591. .sorted(Comparator.comparingInt((String str) -> Integer.parseInt(str.split("_")[1]))
  592. .thenComparingInt(str -> Integer.parseInt(str.split("_")[0])))
  593. .collect(Collectors.joining(";"));
  594. }
  595. }
  596. }
  597. return coords;
  598. }
  599. public static String coordsSorted2(String coords){
  600. if(StringUtils.isNotEmpty(coords)){
  601. List<String> dataList=Arrays.asList(coords.split(";"));
  602. if(dataList.size()>2){
  603. /*判断分区:根据行列长度*/
  604. List<Integer> row =dataList.stream().map(e->e.split("_")[0]).distinct().map(Integer::parseInt).collect(Collectors.toList());
  605. List<Integer> column=dataList.stream().map(e->e.split("_")[1]).distinct().map(Integer::parseInt).collect(Collectors.toList());
  606. if(row.size()>=column.size()){
  607. /*纵向*/
  608. if(column.size()>1){
  609. List<List<Integer>> consecutiveGroups = IntStream.range(0, column.size())
  610. .boxed()
  611. .collect(Collectors.collectingAndThen(
  612. Collectors.groupingBy(
  613. i -> i - column.get(i),
  614. LinkedHashMap::new,
  615. Collectors.mapping(column::get, Collectors.toList())
  616. ),
  617. map -> new ArrayList<>(map.values())
  618. ));
  619. }
  620. }
  621. /* 确定区内方向:*/
  622. }
  623. }
  624. return coords;
  625. }
  626. /* public static void main(String[] args) {
  627. List<Integer> column = Arrays.asList(1, 2, 3, 5, 6, 7, 9, 11, 17);
  628. List<List<Integer>> consecutiveGroups = IntStream.range(0, column.size())
  629. .boxed()
  630. .collect(Collectors.collectingAndThen(
  631. Collectors.groupingBy(
  632. i -> i - column.get(i),
  633. LinkedHashMap::new,
  634. Collectors.mapping(column::get, Collectors.toList())
  635. ),
  636. map -> new ArrayList<>(map.values())
  637. ));
  638. AtomicInteger i = new AtomicInteger(column.get(0));
  639. List<List<Integer>> consecutiveGroups2= new ArrayList<>(column.stream().collect(Collectors.groupingBy(e -> e - i.getAndSet(e) > 1, LinkedHashMap::new, Collectors.toList())).values());
  640. System.out.println();
  641. }*/
  642. public static List<Object> slice(List<LocalVariable> local, String formula){
  643. int min =0;
  644. List<Object> result = new ArrayList<>();
  645. try {
  646. pretreatment(local,formula);
  647. List<Object> r= local.stream().map(e-> {
  648. /*所有依赖元素的内容必须非空才进行计算,否则返回空值*/
  649. return e.hasEmptyElementValue()?"": Expression.parse(e.getFormula()).calculate(e.getCurrentMap()).toString();
  650. }).collect(Collectors.toList());
  651. if(CollectionUtil.isNotEmpty(r)&&r.stream().anyMatch(StringUtils::isNotEmpty)){
  652. result.addAll(r);
  653. }
  654. }catch (Exception e){
  655. StaticLog.error("公式:{},执行出错",formula);
  656. }
  657. return result;
  658. }
  659. public static void pretreatment(List<LocalVariable> local,String formula){
  660. formula=StringUtils.removeMultiSpace(formula);
  661. if(formula.contains("LIST")){
  662. Matcher m=RegexUtils.matcher("\\(([^)]*)\\)/LIST",formula);
  663. while (m.find()){
  664. List<String> codes=getCodeList(m.group(1).replaceAll("[+-]",","));
  665. local=local.stream().peek(e->{
  666. @SuppressWarnings("unckecked")
  667. Map<String,Object> map = (Map<String, Object>) e.getCurrentMap().getOrDefault("E",new HashMap<>());
  668. int listSize=(int)codes.stream().filter(c->StringUtils.isNotEmpty(map.get(c))).count();
  669. if(listSize<=0||listSize>codes.size()){
  670. listSize=codes.size();
  671. }
  672. map.put("LIST",listSize);
  673. }).collect(Collectors.toList());
  674. }
  675. }
  676. }
  677. /*从方法参数中获取全部code*/
  678. public static List<String> getCodeList(String param){
  679. List<String> list = new ArrayList<>();
  680. if(StringUtils.isNotEmpty(param)){
  681. Arrays.stream(param.split(",")).forEach(s->{
  682. list.add(s.replaceAll("[E\\[\\]']",""));
  683. });
  684. }
  685. return list;
  686. }
  687. public static FormData createFormDataFast(String name,String code,String values,String coords){
  688. if(StringUtils.isNotEmpty(code,name)){
  689. //String[] arr=code.split(":");
  690. // String coords = tec.getCoordinateMap().get(arr[0]).get(arr[1]);
  691. if(StringUtils.isNotEmpty(coords)) {
  692. /*定位信息存在才合法*/
  693. List<Coords> coordsList = Stream.of(coords).flatMap(s -> Arrays.stream(s.split(";"))).map(s -> {
  694. String[] xy = s.split("_");
  695. return new Coords(xy[1], xy[0]);
  696. }).collect(Collectors.toList());
  697. List<ElementData> eds = new ArrayList<>();
  698. if (StringUtils.isNotEmpty(values)) {
  699. String[] pages = values.split(";;");
  700. for (int index = 0; index < pages.length; index++) {
  701. String pg = pages[index];
  702. if (Func.isNotBlank(pg)) {
  703. String[] val = pg.split("☆");
  704. Map<String, Object> tmpMap = new LinkedHashMap<>();
  705. for (String s : val) {
  706. String[] t = s.split("_\\^_");
  707. String[] c = t[1].split("_");
  708. tmpMap.put(StringUtils.join(code, 0, index, Func.toInt(c[1]), Func.toInt(c[0]), StringPool.AT), t[0]);
  709. }
  710. for (Coords c : coordsList) {
  711. Object data = null;
  712. String key = StringUtils.join(code, 0, index, c.getX(), c.getY(), StringPool.AT);
  713. if (tmpMap.containsKey(key)) {
  714. data = tmpMap.get(key);
  715. }
  716. eds.add(new ElementData(index, 0, data, c.getX(), c.getY()));
  717. }
  718. }
  719. }
  720. } else {
  721. eds = coordsList.stream().map(c -> new ElementData(0, 0, null, c.getX(), c.getY())).collect(Collectors.toList());
  722. }
  723. FormData one = new FormData(code, eds, null, coords);
  724. one.setEName(name);
  725. return one;
  726. }
  727. }
  728. return null;
  729. }
  730. public static void mainT(String[] args) throws IOException {
  731. XYSeries series = new XYSeries("Data Series");
  732. series.add(10.2, 1.82);
  733. series.add(11.9, 1.86);
  734. series.add(15.9, 1.87);
  735. series.add(19.3, 1.85);
  736. series.add(20.3, 1.80);
  737. XYSeriesCollection dataset = new XYSeriesCollection();
  738. dataset.addSeries(series);
  739. JFreeChart chart = ChartFactory.createXYLineChart(
  740. "测试散点图", // 标题
  741. "X", // 横轴标题
  742. "Y", // 纵轴标题
  743. dataset, // 数据集
  744. PlotOrientation.VERTICAL, // 图表方向
  745. true, // 是否显示图例
  746. false, // 是否生成工具提示
  747. false // 是否生成URL链接
  748. );
  749. // 设置字体
  750. Font titleFont = new Font("SimSun", Font.PLAIN, 18); // 指定使用宋体字体
  751. Font axisFont = new Font("SimSun", Font.PLAIN, 12); // 指定使用宋体字体
  752. // 设置标题字体
  753. TextTitle title = chart.getTitle();
  754. title.setFont(titleFont);
  755. XYPlot plot = (XYPlot) chart.getPlot();
  756. XYSplineRenderer renderer = new XYSplineRenderer();
  757. plot.setRenderer(renderer);
  758. plot.setBackgroundPaint(Color.WHITE);
  759. // Set the line stroke and shape for the renderer
  760. renderer.setSeriesStroke(0, new BasicStroke(2.0f));
  761. Shape circle = new Ellipse2D.Double(-3, -3, 6, 6);
  762. renderer.setSeriesShape(0, circle);
  763. renderer.setSeriesPaint(0, Color.BLUE);
  764. // 自定义 X 轴刻度
  765. NumberAxis domainAxis = (NumberAxis) plot.getDomainAxis();
  766. domainAxis.setTickUnit(new NumberTickUnit(5)); // 设置刻度间隔
  767. domainAxis.setRange(0.0, 25); // 设置轴的范围
  768. // 自定义 Y 轴刻度
  769. NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
  770. rangeAxis.setTickUnit(new NumberTickUnit(0.01)); // 设置刻度间隔
  771. rangeAxis.setRange(1.79, 1.90); // 设置轴的范围
  772. // 添加横杠
  773. for(int i=175;i<190;i++){
  774. ValueMarker marker = new ValueMarker((double) i /100);
  775. marker.setPaint(Color.BLUE); // 横杠的颜色
  776. plot.addRangeMarker(marker);
  777. }
  778. ChartPanel chartPanel = new ChartPanel(chart);
  779. chartPanel.setPreferredSize(new Dimension(500, 400));
  780. // 保存图表为图片
  781. int width = 800;
  782. int height = 600;
  783. ChartUtils.saveChartAsPNG(new File("C:/Users/yangyj/Desktop/Swap_space/poi_statistics.png"), chart, width, height);
  784. }
  785. /* public static void main(String[] args) {
  786. JSONObject job = new JSONObject();
  787. JSONObject job2 = new JSONObject();
  788. job2.put("K","K");
  789. job.fluentPut("A",1).fluentPut("B",2).fluentPut("C","bird").fluentPut("job",job2);
  790. job.forEach((k,v)->{
  791. // System.out.println(k);
  792. System.out.println(v);
  793. });
  794. }*/
  795. }