Browse Source

excel 数据解析

hongchuangyanfa 2 years ago
parent
commit
4e9e8cd2b5

+ 162 - 0
blade-common/src/main/java/org/springblade/common/utils/MathUtil.java

@@ -0,0 +1,162 @@
+package org.springblade.common.utils;
+
+import java.util.*;
+
+public class MathUtil {
+
+/*    public static void main(String[] args) {
+        String[] array = new String[] {"1","2","3"};
+        List arrayList = Arrays.asList(array);
+        Set<String> resultSet = new HashSet<>();
+        getCombination(arrayList, resultSet);
+        System.out.println("组合数 = " + resultSet.size());
+        System.out.println("所有组合 : " + resultSet);
+    }*/
+
+
+    /**
+     * 循环递归获取给定数组元素(无重复)的全排列
+     *
+     * @param oriList 原始数组
+     * @param oriLen 原始数组size
+     * @param arrayCombResult 数组排列结果集,可传null或空Set
+     * @param preList 记录排列参数,可传null或空List
+     * @return 排列结果
+     */
+    public static Set<String> getArrange(List oriList, int oriLen, Set<String> arrayCombResult, List preList){
+        if (oriList == null){
+            return arrayCombResult;
+        }
+        if (arrayCombResult == null){
+            arrayCombResult = new HashSet<>();
+        }
+        if (preList == null){
+            preList = new ArrayList();
+        }
+        for (int i = 0; i < oriList.size(); i++){
+            while(preList.size() > 0 && oriList.size() + preList.size() > oriLen){
+                preList.remove(preList.size() - 1);
+            }
+            List arrList = new ArrayList(oriList);
+            preList.add(arrList.get(i));
+            arrList.remove(i);
+            if (arrList.isEmpty()){
+                arrayCombResult.add(getStrFromList(preList));
+            }else {
+                getArrange(arrList, oriLen, arrayCombResult, preList);
+            }
+        }
+        return arrayCombResult;
+    }
+    /**
+     * 循环递归获取给定数组元素(无重复)的所有组合
+     *
+     * @param oriList 原始数组
+     * @param resultSet 元素组合结果,可传null或空set
+     * @return 组合结果
+     */
+    public static Set<String> getCombination(List oriList, Set<String> resultSet) {
+        if (oriList == null) {
+            return resultSet;
+        }
+        if (resultSet == null){
+            resultSet = new HashSet<>();
+        }
+        for (int i = 0; i < oriList.size(); i++) {
+            List copyList = new ArrayList(oriList);
+            resultSet.add(getStrFromList(copyList));
+            List removeIList = new ArrayList();
+            copyList.remove(i);
+            removeIList.addAll(copyList);
+            getCombination(removeIList, resultSet);
+        }
+        return resultSet;
+    }
+    /**
+     * 将数组元素转化为逗号分隔的字符串
+     *
+     * @param oriList 原始数组
+     * @return 字符串
+     */
+    public static String getStrFromList(List oriList){
+        StringBuffer result = new StringBuffer();
+        if (oriList == null){
+            return result.toString();
+        } else {
+            for (int i = 0; i < oriList.size(); i++){
+                result.append(oriList.get(i));
+                if (i != (oriList.size() - 1)){
+
+                }
+            }
+        }
+        return result.toString();
+    }
+
+
+
+    /**
+     * @param args
+     */
+    private static int min(int one, int two, int three) {
+        int min = one;
+        if(two < min) {
+            min = two;
+        }
+        if(three < min) {
+            min = three;
+        }
+        return min;
+    }
+
+    public static int ld(String str1, String str2) {
+        int d[][]; //矩阵
+        int n = str1.length();
+        int m = str2.length();
+        int i; //遍历str1的
+        int j; //遍历str2的
+        char ch1; //str1的
+        char ch2; //str2的
+        int temp; //记录相同字符,在某个矩阵位置值的增量,不是0就是1
+        if(n == 0) {
+            return m;
+        }
+        if(m == 0) {
+            return n;
+        }
+        d = new int[n+1][m+1];
+        for(i=0; i<=n; i++) { //初始化第一列
+            d[i][0] = i;
+        }
+        for(j=0; j<=m; j++) { //初始化第一行
+            d[0][j] = j;
+        }
+        for(i=1; i<=n; i++) { //遍历str1
+            ch1 = str1.charAt(i-1);
+            //去匹配str2
+            for(j=1; j<=m; j++) {
+                ch2 = str2.charAt(j-1);
+                if(ch1 == ch2) {
+                    temp = 0;
+                } else {
+                    temp = 1;
+                }
+                //左边+1,上边+1, 左上角+temp取最小
+                d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1, d[i-1][j-1]+temp);
+            }
+        }
+        return d[n][m];
+    }
+
+    public static double sim(String str1, String str2) {
+        int ld = ld(str1, str2);
+        return 1 - (double) ld / Math.max(str1.length(), str2.length());
+    }
+
+/*   public static void main(String[] args) {
+        double data1 =0.19047619047619047;
+        double data2 =0.33333333333333337;
+       // System.out.println("ld="+ld(str1, str2));
+        System.out.println(data1<data2);
+    }*/
+}

+ 6 - 0
blade-service-api/blade-system-api/src/main/java/org/springblade/system/vo/GrantTreeVO.java

@@ -31,10 +31,16 @@ import java.util.List;
 public class GrantTreeVO implements Serializable {
 	private static final long serialVersionUID = 1L;
 
+	// 后管
 	private List<TreeNode> menu;
 
+	// 客户端
+	private List<TreeNode> usermenu;
+
+	//
 	private List<TreeNode> dataScope;
 
+	//api
 	private List<TreeNode> apiScope;
 
 }

+ 251 - 170
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExcelTabController.java

@@ -28,10 +28,12 @@ import javax.validation.Valid;
 
 import lombok.SneakyThrows;
 
+import org.apache.commons.lang.StringUtils;
 import org.jsoup.Jsoup;
 import org.jsoup.nodes.Document;
 import org.jsoup.nodes.Element;
 import org.jsoup.select.Elements;
+import org.springblade.common.utils.MathUtil;
 import org.springblade.common.utils.SnowFlakeUtil;
 import org.springblade.core.log.exception.ServiceException;
 import org.springblade.core.mp.support.Condition;
@@ -42,8 +44,7 @@ import org.springblade.core.secure.BladeUser;
 import org.springblade.core.secure.utils.AuthUtil;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.constant.BladeConstant;
-import org.springblade.core.tool.utils.Func;
-import org.springblade.core.tool.utils.StringPool;
+import org.springblade.core.tool.utils.*;
 import org.springblade.manager.entity.*;
 import org.springblade.manager.service.*;
 import org.springblade.manager.vo.*;
@@ -246,6 +247,8 @@ public class ExcelTabController extends BladeController {
 		detail.setFileType(3); // 表示为清表信息  1 表示祖节点  2 表示为节点信息 3 表示清表
 		detail.setHtmlUrl(thmlUrl);
 		excelTabService.saveOrUpdate(detail);
+		// 解析html
+		explianHtml(thmlUrl);
 		return R.success("上传成功");
 	}
 
@@ -329,45 +332,6 @@ public class ExcelTabController extends BladeController {
 		return R.success("添加成功!");
 	}
 
-	public static String readfile(String filePath){
-		File file = new File(filePath);
-		InputStream input = null;
-		try {
-			input = new FileInputStream(file);
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		}
-		StringBuffer buffer = new StringBuffer();
-		byte[] bytes = new byte[1024];
-		try {
-			for(int n ; (n = input.read(bytes))!=-1 ; ){
-				buffer.append(new String(bytes,0,n,"UTF-8"));
-			}
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-		return buffer.toString();
-	}
-
-
-	private static void saveAsFileWriter(String content ,String filePath) {
-		Writer fwriter = null;
-		try {
-			// true表示不覆盖原来的内容,而是加到文件的后面。若要覆盖原来的内容,直接省略这个参数就好
-			fwriter = new BufferedWriter((new OutputStreamWriter(new FileOutputStream(filePath),"UTF-8")));
-			fwriter.write(content);
-		} catch (IOException ex) {
-			ex.printStackTrace();
-		} finally {
-			try {
-				fwriter.flush();
-				fwriter.close();
-			} catch (IOException ex) {
-				ex.printStackTrace();
-			}
-		}
-	}
-
 	/**
 	 * 关联清表树
 	 */
@@ -395,8 +359,6 @@ public class ExcelTabController extends BladeController {
 		WbsTreePrivate wbsTree = new WbsTreePrivate();
 		wbsTree.setPKeyId(tabId);
 		WbsTreePrivate aPrivate = wbsTreePrivateService.getOne(Condition.getQueryWrapper(wbsTree));
-		aPrivate.setIsLinkTable(1); // 已关联
-		aPrivate.setExcelId(exceTabId);
 
 		UpdateWrapper<WbsTreePrivate> updateWrapper = new UpdateWrapper<>();
 		updateWrapper.in("p_key_id",tabId);
@@ -407,56 +369,245 @@ public class ExcelTabController extends BladeController {
 		// 获取excel 基本信息
 		ExcelTab excelTab = excelTabService.getById(exceTabId);
 		// 解析
+		try {
+			getExcelHtml1(excelTab.getHtmlUrl(),aPrivate.getId()+"");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		return R.success("关联成功");
+	}
 
-		// 获取元素列表
-		WbsFormElement wbsFormElement = new WbsFormElement();
-		QueryWrapper<WbsFormElement> queryWrapper = new QueryWrapper<>();
-		List<WbsFormElement> detail = wbsFormElementService.selectElementListByFid(aPrivate.getId()+"");
-		// 解析html
-		getExcelHtml1(excelTab.getHtmlUrl());
 
-		return R.success("关联成功");
+
+
+	// 匹配
+	public void getExcelHtml1(String thmlUrl,String  TabId) throws IOException{
+		List<WbsFormElement> dataList = wbsFormElementService.selectElementListByFid(TabId);
+
+		File file1 = ResourceUtil.getFile(thmlUrl);
+		FileInputStream fileInputStream = new FileInputStream(file1);
+		String htmlString =   IoUtil.readToString(fileInputStream);
+		Document doc = Jsoup.parse(htmlString);
+		Element table = doc.select("table").first();
+		Elements trs = table.select("tr");
+
+		// 循环解析
+		// 标题坐标
+		List<Map<String,String>> zikey = new ArrayList<>();
+
+		int index_id = 0;
+		// 循环解析
+		for(int i = 0 ;i < trs.size() ;i++) {
+			Element tr = trs.get(i);
+			boolean index_stat = Boolean.parseBoolean(tr.attr("index_stat"));
+
+			if(index_stat && index_id==0){
+				index_id = 1;
+				zikey = new ArrayList<>();
+			}
+
+			if(!index_stat && index_id==1 && zikey.size()>=1){
+				index_id = 2;
+				zikey = new ArrayList<>();
+			}
+
+			Elements tds = tr.select("td");
+			for (int j = 0; j < tds.size(); j++) {
+				Element data = tds.get(j);
+				String textInfo  = data.text();
+				int x1 = Integer.parseInt( data.attr("x1"));
+				int x2 = Integer.parseInt( data.attr("x2"));
+				int y1 = Integer.parseInt( data.attr("y1"));
+				int y2 = Integer.parseInt( data.attr("y2"));
+
+
+				if(!textInfo.isEmpty() && !textInfo.equals("/")){
+					Map<String,String> dataInfo =new HashMap<String,String>();
+					dataInfo.put("name",textInfo);
+					dataInfo.put("x1",data.attr("x1"));
+					dataInfo.put("x2",data.attr("x2"));
+					dataInfo.put("y1",data.attr("y1"));
+					dataInfo.put("y2",data.attr("y2"));
+					zikey.add(dataInfo);
+				}else if(data.html().indexOf("input")>=0){
+
+					List arrayList = new ArrayList<>();
+
+
+					for(int k=zikey.size()-1;k>=0 ;k--){
+						String name = zikey.get(k).get("name").replaceAll("[^\u4E00-\u9FA5]", "");
+						int xx1 = Integer.parseInt( zikey.get(k).get("x1"));
+						int xx2 = Integer.parseInt( zikey.get(k).get("x2"));
+						int yy1 = Integer.parseInt( zikey.get(k).get("y1"));
+						int yy2 = Integer.parseInt( zikey.get(k).get("y2"));
+
+						// 左匹配
+						if( yy1<=y1 && yy2>=y2 && xx2<x1 && StringUtils.isNotEmpty(name)){
+							arrayList.add(name);
+							if(!index_stat){
+								break;
+							}
+						}
+
+						//向 上 匹配
+						if(index_stat){
+							if( xx1<=x1 && xx2 >=x2 && yy2<y1 ){
+								arrayList.add(name);
+							}
+						}
+					}
+
+					Set<String> resultSet = new HashSet<>();
+					MathUtil.getCombination(arrayList, resultSet);
+					double maxInfo = 0;
+					if(!resultSet.isEmpty()){
+
+						for(WbsFormElement wbsFormElement : dataList){
+							for(String bx : resultSet){
+								double dataxx =  MathUtil.sim(bx,wbsFormElement.getEName().replaceAll("[^\u4E00-\u9FA5]", ""));
+								if(maxInfo < dataxx){
+									System.out.println("x1-x2="+x1+","+x2+"y1-y2="+y1+","+y2+bx+"="+dataxx+"_jieh="+resultSet);
+									data.empty().text(bx);
+									maxInfo = dataxx;
+								}
+							}
+						}
+					}
+					System.out.println(maxInfo);
+				}
+			}
+		}
+
+
+		//
+		// for (Map<String,String> d:zikey){
+		// System.out.println(d.get("name")+"x1"+d.get("x1"));
+		//  }
+
+		fileInputStream.close();
+
+		File writefile = new File(thmlUrl);
+		FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+		System.out.println("完成");
+
 	}
 
 
-	public void getExcelHtml1(String thmlUrl) {
 
-		String htmlString =  readfile(thmlUrl);
-		Map<String ,String > styleMap = new HashMap<>();
+	/**
+	 * 清表生成html
+	 */
+	@GetMapping("/get-excel-html")
+	@ApiOperationSupport(order = 15)
+	@ApiOperation(value = "清表生成html", notes = "清表生成html")
+	@ApiImplicitParams(value = {
+			@ApiImplicitParam(name = "excelId", value = "excelId", required = true)
+	})
+	public R getExcelHtml(Long excelId) throws IOException {
+		ExcelTab excelTab = excelTabService.getById(excelId);
+		if(excelTab ==null ){
+			return R.fail("该数据下无此节点!");
+		}
+		if(excelTab.getHtmlUrl()==null){
+			return R.fail("请上传清表!");
+		}
 
+		File file1 = ResourceUtil.getFile(excelTab.getHtmlUrl());
+		FileInputStream fileInputStream = new FileInputStream(file1);
+		String htmlString =   IoUtil.readToString(fileInputStream);
+		// 解析 style
+		Document doc = Jsoup.parse(htmlString);
+		Element table = doc.select("table").first();
+		doc.select("Col").remove();
+		fileInputStream.close();
+		return R.data(table+"");
+	}
+
+
+
+	public static void explianHtml(String htmlURl) throws IOException {
+
+		File file1 = ResourceUtil.getFile(htmlURl);
+		FileInputStream inputStream = new FileInputStream(file1);
+
+		// 测试
+		String htmlString =  IoUtil.readToString(inputStream);
+
+		// 样式集合
+		Map<String ,String > styleMap = new HashMap<>();
 		// 解析 style
 		Document doc = Jsoup.parse(htmlString);
 		Element style = doc.select("style").first();
+
 		Matcher cssMatcher = Pattern.compile("(\\w+)\\s*[{]([^}]+)[}]").matcher(style.html());
 		while (cssMatcher.find()) {
 			styleMap.put(cssMatcher.group(1),cssMatcher.group(2));
 		}
 		// 解析 总行和总列
-		// 解析
 		Element table = doc.select("table").first();
 		Elements trs = table.select("tr");
 
 		// 获取总行列数
 		int maxCol = doc.select("Col").size();
-
-		List<Map<String,String>> textlist = new ArrayList<>() ;
-
 		String [] rowData = new String[trs.size()+1];
 
 		int s_index = 0;
+		boolean index_stat = false;
 		// 横向计算
 		for(int i = 0 ;i < trs.size() ;i++) {
 			Element tr = trs.get(i);
 			Elements tds = tr.select("td");
+
+			int x_width = 0 ;
+			int y_width = 0 ;
+			//区域计算
+			for (int j = 0; j < tds.size(); j++) {
+				Element data = tds.get(j);
+				String keyId = data.attr("class");
+
+				int colspan = data.attr("COLSPAN").equals("") ? 1 : Integer.parseInt(data.attr("COLSPAN"));
+				String classInfo = styleMap.get(keyId);
+				data.removeAttr("class");
+				data.attr("style",styleMap.get(keyId).replaceAll("break-word","inherit"));
+				// 第一列
+				if(j==0 && classInfo.indexOf("border-left-style")>=0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")>=0 && !index_stat){
+					x_width +=colspan;
+				}else if(j == tds.size()-1 && classInfo.indexOf("border-right-style")>=0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")>=0 && !index_stat && j>=1){
+					x_width +=colspan;
+				}else if(classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")>=0 && !index_stat && j>=1){
+					x_width +=colspan;
+				}
+
+				// 计算退出
+				if(j==0 && classInfo.indexOf("border-left-style")<0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")<0 && index_stat && classInfo.indexOf("border-right-style")<0){
+					y_width +=colspan;
+				}else if(j == tds.size()-1 && classInfo.indexOf("border-right-style")<0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")<0 && index_stat && j>=1){
+					y_width +=colspan;
+				}else if(classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")<0 &&index_stat && j>=1){
+					y_width +=colspan;
+				}
+			}
+
+			if(x_width == maxCol && !index_stat && s_index==0){
+				s_index = i + 1;
+				index_stat = true ;
+			}
+
+			if(y_width == maxCol && index_stat && s_index>0){
+				s_index = i + 1;
+				index_stat = false ;
+			}
+
+			tr.attr("index_stat",index_stat+"");
+
 			int x= 0;
 			for (int j = 0; j < tds.size(); j++) {
-				ExctabCell cell = new ExctabCell();
 				Element data = tds.get(j);
+
 				int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
 				int rowspan = data.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(data.attr("ROWSPAN"));
-				Map<String, String> textObject = new HashMap<>();
-
 
+				Map<String, String> textObject = new HashMap<>();
 				// 计算
 				int x1 =0;
 				int x2 =0;
@@ -473,10 +624,9 @@ public class ExcelTabController extends BladeController {
 					x2 = x+colspan;
 					x = x+colspan;
 				}
-
 				String textInfo = data.text().trim();
+
 				// y 坐标
-				textObject.put("text",textInfo);
 				y1=i+1;
 				if(rowspan==0){
 					y2 = i+1;
@@ -525,128 +675,59 @@ public class ExcelTabController extends BladeController {
 				}
 
 
-				String keyId = data.attr("class");
-				if(!keyId.isEmpty()){
-					data.removeAttr("class");
-					data.attr("style",styleMap.get(keyId));
+				// System.out.println(StringUtil.trimAllWhitespace(textInfo)+""+StringUtil.trimAllWhitespace(textInfo).length());
+				data.text(textInfo.replaceAll(" ",""));
 
-					// 封版
-					if(styleMap.get(keyId).indexOf("border-top-style")>=0 && styleMap.get(keyId).indexOf("border-bottom-style")>=0){
-						s_index = y1;
-					}
-					if(styleMap.get(keyId).indexOf("border-top-style")>=0 && styleMap.get(keyId).indexOf("border-bottom-style")<0){
-						s_index = y1;
-					}
-				}
 
-				LinkdataInfo linkdataInfo = new LinkdataInfo();
-				linkdataInfo.setTrIndex(i);
-				linkdataInfo.setTdIndex(j);
-				linkdataInfo.setTabId(Long.parseLong("123456789"));
-				boolean isadd = false;
-				// 组装 html 数据
-				boolean istopVal =false;
-				boolean isleftVal =false;
-				int inputType = 1;  //1 输入框  2 时间
-				if(textInfo.equals("/")|| textInfo.isEmpty() || textInfo.equals("—")){
-					if(i== 0 && j==0 && maxCol==colspan ){ // 第一行为空
-						isadd = false;
-					}else{
-						// 得到 当前位置 获取值
-						for(int k=textlist.size()-1;k>=0;k--){
-							Map<String,String> m = textlist.get(k);
-							int xx1 = Integer.parseInt(m.get("x1"));
-							int xx2 = Integer.parseInt(m.get("x2"));
-							int yy1 = Integer.parseInt(m.get("y1"));
-							int yy2 = Integer.parseInt(m.get("y2"));
-							String kekval = m.get("text");
-
-							if(xx1<=x1 && xx2>=x2 && yy2<y1 && !istopVal && y1>=s_index){ // 向上取值
-								if(!kekval.isEmpty() && !kekval.equals("/") && kekval.indexOf("检验单")<0 && kekval.indexOf("表")<0 && kekval.indexOf("—")<0){
-									if(kekval.indexOf("日期")>=0){
-										inputType=2;
-									}
-									linkdataInfo.setColName(kekval);
-									istopVal = true ;
-									System.out.println(x1 +"-"+x2 +":"+y1+"-"+y2 + "--"+s_index +"val:"+kekval);
-								}
-							}
-							if(yy1<=y1 && yy2>=y2 && xx2<x1 && !isleftVal && y1>=s_index){ // 向左取
-								if(!kekval.isEmpty() && !kekval.equals("/") && kekval.indexOf("检验单")<0 && kekval.indexOf("表")<0&& kekval.indexOf("—")<0){
-									isleftVal = true ;
-									if(kekval.indexOf("日期")>=0){
-										inputType=2;
-									}
-									linkdataInfo.setColName(kekval);
-								//	System.out.println(x1 +"-"+x2 +":"+y1+"-"+y2 + "--"+s_index +"val:"+kekval);
-								}
-							}
-							if(isleftVal || istopVal){
-								isadd = true ;
-							}
-							if (istopVal&&isleftVal){
-								break;
-							}
-						}
-					}
-				}else{
-					isadd = false;
-				}
 
+				// 设置td 属性
+				data.attr("trIndex",i+"");
+				data.attr("tdIndex",j+"");
+				data.attr("x1",x1+"");
+				data.attr("x2",x2+"");
+				data.attr("y1",y1+"");
+				data.attr("y2",y2+"");
+				String parm = i+","+j+","+x1+","+x2+","+y1+","+y2;
+				// 设置文本信息
 				if(textInfo.indexOf("年")>=0 && textInfo.indexOf("月")>=0&& textInfo.indexOf("日")>=0){
-					data.empty().append("<el-date-picker style='width:100%;height:100%'   type='date' format='yyyy 年 MM 月 dd 日' placeholder='请选择时间'> </el-date-picker>");
+					data.empty().append("<el-date-picker style='width:100%;height:100%' trIndex="+i+" tdIndex="+j+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+"  type='date' format='yyyy 年 MM 月 dd 日' placeholder='请选择时间'> </el-date-picker>");
 				}
 
-				if(isadd){
-
-					if(inputType==2){
-						data.empty().append("<el-date-picker  type='date' style='width:100%;height:100%' > </el-date-picker>");
-					}else{
+				if(textInfo.isEmpty() || textInfo.equals("/") || textInfo.equals("-")){
+					if(index_stat){
 						if(rowspan>=1){
-							data.empty().append("<el-input type='textarea' style='width:100%;height:100%'   :rows="+rowspan*2+" placeholder=''> </el-input>");
+							data.empty().append("<el-input type='textarea' @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+i+" tdIndex="+j+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%'   :rows="+rowspan*2+" placeholder=''> </el-input>");
 						}else{
-							data.empty().append("<el-input type='text' style='width:100%;height:100%' placeholder=''> </el-input>");
+							data.empty().append("<el-input type='text' @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+i+" tdIndex="+j+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%' placeholder=''> </el-input>");
+						}
+					}else{
+						if(j==0 ){
+							if(colspan ==maxCol && i>=1 && i<=2){
+								if(rowspan>=1){
+									data.empty().append("<el-input type='textarea' @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+i+" tdIndex="+j+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%'   :rows="+rowspan*2+" placeholder=''> </el-input>");
+								}else{
+									data.empty().append("<el-input type='text' @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+i+" tdIndex="+j+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%' placeholder=''> </el-input>");
+								}
+							}
+						}else{
+							Element bforData = tds.get(j-1);
+							if(!bforData.text().isEmpty()){
+								if(rowspan>=1){
+									data.empty().append("<el-input type='textarea' @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+i+" tdIndex="+j+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%'   :rows="+rowspan*2+" placeholder=''> </el-input>");
+								}else{
+									data.empty().append("<el-input type='text' @contextmenu.prevent.native='RightClick("+parm+")' trIndex="+i+" tdIndex="+j+"  x1="+x1+" x2="+x2+" y1="+y1+" y2="+y2+" style='width:100%;height:100%' placeholder=''> </el-input>");
+								}
+							}
 						}
 					}
-					//linkdataInfoService.save(linkdataInfo);
 				}
-
-				textObject.put("x1",x1+"");
-				textObject.put("x2",x2+"");
-				textObject.put("y1",y1+"");
-				textObject.put("y2",y2+"");
-				textObject.put("rowSpan",rowspan+"");
-				textlist.add(textObject);
 			}
 		}
-		saveAsFileWriter(doc+"",thmlUrl);
-	}
-
 
+		// 写入
 
-	/**
-	 * 清表生成html
-	 */
-	@GetMapping("/get-excel-html")
-	@ApiOperationSupport(order = 15)
-	@ApiOperation(value = "清表生成html", notes = "清表生成html")
-	@ApiImplicitParams(value = {
-			@ApiImplicitParam(name = "excelId", value = "excelId", required = true)
-	})
-	public R getExcelHtml(Long excelId) {
-		ExcelTab excelTab = excelTabService.getById(excelId);
-		if(excelTab ==null ){
-			return R.fail("该数据下无此节点!");
-		}
-
-		if(excelTab.getHtmlUrl()==null){
-			return R.fail("请上传清表!");
-		}
-
-		String htmlString =  readfile(excelTab.getHtmlUrl());
-		// 解析 style
-		Document doc = Jsoup.parse(htmlString);
-		Element table = doc.select("table").first();
-		return R.data(table+"");
+		FileUtil.writeToFile(file1, doc.html(), Boolean.parseBoolean("UTF-8"));
+		inputStream.close();
+		System.out.println("完成");
 	}
 }

+ 388 - 0
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/ExpaileHtml.java

@@ -0,0 +1,388 @@
+package org.springblade.manager.controller;
+
+import com.spire.xls.Workbook;
+import com.spire.xls.Worksheet;
+import org.apache.commons.lang.StringUtils;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.jsoup.nodes.Element;
+import org.jsoup.select.Elements;
+import org.springblade.common.utils.MathUtil;
+import org.springblade.core.tool.utils.FileUtil;
+import org.springblade.core.tool.utils.IoUtil;
+import org.springblade.core.tool.utils.ResourceUtil;
+import org.springblade.manager.entity.WbsFormElement;
+
+import java.io.*;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+public class ExpaileHtml {
+/*
+    public static void main(String[] args) throws IOException {
+        getHtmlInfo();
+        try {
+            Thread.sleep(500);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        //String inHtmlUrl = "/Users/hongchuangyanfa/Desktop/123654.html";
+       getjiexiInfo();
+    }
+*/
+
+
+
+
+
+
+    public static void getjiexiInfo() throws IOException {
+        String inHtmlUrl = "/Users/hongchuangyanfa/Desktop/123654.html";
+        File file = ResourceUtil.getFile(inHtmlUrl);
+        FileInputStream inputStream = new FileInputStream(file);
+        String htmlString =   IoUtil.readToString(inputStream);
+
+        // 获取比对数据
+        List<WbsFormElement> dataList = getWbsInfo();
+
+        String dataInfox = dataList.stream().map(WbsFormElement::getEName).collect(Collectors.joining(","));
+
+        System.out.println(dataInfox);
+        Document doc = Jsoup.parse(htmlString);
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+
+
+        // 标题坐标
+        List<Map<String,String>> zikey = new ArrayList<>();
+
+        int index_id = 0;
+        // 循环解析
+        for(int i = 0 ;i < trs.size() ;i++) {
+            Element tr = trs.get(i);
+            boolean index_stat = Boolean.parseBoolean(tr.attr("index_stat"));
+
+            if(index_stat && index_id==0){
+                index_id = 1;
+                zikey = new ArrayList<>();
+            }
+
+            if(!index_stat && index_id==1 && zikey.size()>=1){
+                index_id = 2;
+                zikey = new ArrayList<>();
+            }
+
+            Elements tds = tr.select("td");
+            for (int j = 0; j < tds.size(); j++) {
+                Element data = tds.get(j);
+                String textInfo  = data.text();
+                int x1 = Integer.parseInt( data.attr("x1"));
+                int x2 = Integer.parseInt( data.attr("x2"));
+                int y1 = Integer.parseInt( data.attr("y1"));
+                int y2 = Integer.parseInt( data.attr("y2"));
+
+
+                if(!textInfo.isEmpty() && !textInfo.equals("/")){
+                    Map<String,String> dataInfo =new HashMap<String,String>();
+                    dataInfo.put("name",textInfo);
+                    dataInfo.put("x1",data.attr("x1"));
+                    dataInfo.put("x2",data.attr("x2"));
+                    dataInfo.put("y1",data.attr("y1"));
+                    dataInfo.put("y2",data.attr("y2"));
+                    zikey.add(dataInfo);
+                }else if(data.html().indexOf("input")>=0){
+
+                    List arrayList = new ArrayList<>();
+
+
+                    for(int k=zikey.size()-1;k>=0 ;k--){
+                        String name = zikey.get(k).get("name").replaceAll("[^\u4E00-\u9FA5]", "");
+                        int xx1 = Integer.parseInt( zikey.get(k).get("x1"));
+                        int xx2 = Integer.parseInt( zikey.get(k).get("x2"));
+                        int yy1 = Integer.parseInt( zikey.get(k).get("y1"));
+                        int yy2 = Integer.parseInt( zikey.get(k).get("y2"));
+
+                        // 左匹配
+                        if( yy1<=y1 && yy2>=y2 && xx2<x1 && StringUtils.isNotEmpty(name)){
+                             arrayList.add(name);
+                            if(!index_stat){
+                                break;
+                            }
+                        }
+
+                        //向 上 匹配
+                        if(index_stat){
+                            if( xx1<=x1 && xx2 >=x2 && yy2<y1 ){
+                                arrayList.add(name);
+                            }
+                        }
+                    }
+
+                    Set<String> resultSet = new HashSet<>();
+                    System.out.println(dataInfox+"==="+arrayList.size());
+                    MathUtil.getCombination(arrayList, resultSet);
+                    double maxInfo = 0;
+                    if(!resultSet.isEmpty()){
+
+                        for(WbsFormElement wbsFormElement : dataList){
+                            for(String bx : resultSet){
+                                double dataxx =  MathUtil.sim(bx,wbsFormElement.getEName());
+                                if(maxInfo < dataxx){
+                                    System.out.println("x1-x2="+x1+","+x2+"y1-y2="+y1+","+y2+bx+"="+dataxx+"_jieh="+resultSet);
+                                    data.empty().text(bx);
+                                    maxInfo = dataxx;
+                                }
+                            }
+                        }
+                    }
+                    System.out.println(maxInfo);
+                }
+            }
+        }
+
+
+        //
+       // for (Map<String,String> d:zikey){
+           // System.out.println(d.get("name")+"x1"+d.get("x1"));
+      //  }
+
+        inputStream.close();
+
+        File writefile = new File(inHtmlUrl);
+        FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+        System.out.println("完成");
+    }
+
+
+    public static List<WbsFormElement> getWbsInfo(){
+        List<WbsFormElement> elementList = new ArrayList<>();
+        WbsFormElement info = new WbsFormElement();
+        info.setEName("承包单位");
+
+        WbsFormElement info1 = new WbsFormElement();
+        info1.setEName("工程名称");
+
+        WbsFormElement info2 = new WbsFormElement();
+        info2.setEName("年月日");
+
+        WbsFormElement info3 = new WbsFormElement();
+        info3.setEName("隧道净高实测");
+
+        WbsFormElement info4 = new WbsFormElement();
+        info3.setEName("基坑尺寸设计值");
+
+
+        elementList.add(info);
+        elementList.add(info1);
+        elementList.add(info2);
+        elementList.add(info3);
+
+        return elementList;
+    }
+
+    public static void getHtmlInfo() throws IOException {
+        String thmlUrl = "/Users/hongchuangyanfa/Desktop/1539066383856304128.html";
+
+        File file = new File("/Users/hongchuangyanfa/Desktop/test001231.xlsx");
+
+        FileInputStream inputStream = new FileInputStream(file);
+        // 解析excel
+        Workbook wb = new Workbook();
+        wb.loadFromMHtml(inputStream);
+        //获取工作表
+        Worksheet sheet = wb.getWorksheets().get(0);
+        sheet.saveToHtml(thmlUrl);
+
+        // 测试
+        File file1 = ResourceUtil.getFile(thmlUrl);
+        String htmlString =  IoUtil.readToString(new FileInputStream(file1));
+
+        // 样式集合
+        Map<String ,String > styleMap = new HashMap<>();
+        // 解析 style
+        Document doc = Jsoup.parse(htmlString);
+        Element style = doc.select("style").first();
+
+        Matcher cssMatcher = Pattern.compile("(\\w+)\\s*[{]([^}]+)[}]").matcher(style.html());
+        while (cssMatcher.find()) {
+            styleMap.put(cssMatcher.group(1),cssMatcher.group(2));
+        }
+        // 解析 总行和总列
+        Element table = doc.select("table").first();
+        Elements trs = table.select("tr");
+
+        // 获取总行列数
+        int maxCol = doc.select("Col").size();
+        String [] rowData = new String[trs.size()+1];
+
+        int s_index = 0;
+        boolean index_stat = false;
+        // 横向计算
+        for(int i = 0 ;i < trs.size() ;i++) {
+            Element tr = trs.get(i);
+            Elements tds = tr.select("td");
+
+            int x_width = 0 ;
+            int y_width = 0 ;
+            //区域计算
+            for (int j = 0; j < tds.size(); j++) {
+                Element data = tds.get(j);
+                String keyId = data.attr("class");
+
+                int colspan = data.attr("COLSPAN").equals("") ? 1 : Integer.parseInt(data.attr("COLSPAN"));
+                String classInfo = styleMap.get(keyId);
+                data.removeAttr("class");
+                data.attr("style",styleMap.get(keyId).replaceAll("break-word","inherit"));
+                // 第一列
+                if(j==0 && classInfo.indexOf("border-left-style")>=0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")>=0 && !index_stat){
+                    x_width +=colspan;
+                }else if(j == tds.size()-1 && classInfo.indexOf("border-right-style")>=0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")>=0 && !index_stat && j>=1){
+                    x_width +=colspan;
+                }else if(classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")>=0 && !index_stat && j>=1){
+                    x_width +=colspan;
+                }
+
+                // 计算退出
+                if(j==0 && classInfo.indexOf("border-left-style")<0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")<0 && index_stat && classInfo.indexOf("border-right-style")<0){
+                    y_width +=colspan;
+                }else if(j == tds.size()-1 && classInfo.indexOf("border-right-style")<0 && classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")<0 && index_stat && j>=1){
+                    y_width +=colspan;
+                }else if(classInfo.indexOf("border-top-style")>=0 && classInfo.indexOf("border-bottom-style")<0 &&index_stat && j>=1){
+                    y_width +=colspan;
+                }
+            }
+
+            if(x_width == maxCol && !index_stat && s_index==0){
+                s_index = i + 1;
+                index_stat = true ;
+            }
+
+            if(y_width == maxCol && index_stat && s_index>0){
+                s_index = i + 1;
+                index_stat = false ;
+            }
+            tr.attr("index_stat",index_stat+"");
+
+            int x= 0;
+            for (int j = 0; j < tds.size(); j++) {
+                Element data = tds.get(j);
+
+                int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
+                int rowspan = data.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(data.attr("ROWSPAN"));
+
+                Map<String, String> textObject = new HashMap<>();
+                // 计算
+                int x1 =0;
+                int x2 =0;
+                int y1 =0;
+                int y2 =0;
+                //x
+                // X 坐标
+                if(colspan==0){
+                    x1 = x+1;
+                    x2 = x+1;
+                    x= x +1;
+                }else{
+                    x1 = x+1;
+                    x2 = x+colspan;
+                    x = x+colspan;
+                }
+                String textInfo = data.text().trim();
+
+                // y 坐标
+                y1=i+1;
+                if(rowspan==0){
+                    y2 = i+1;
+                }else{
+                    y2 = i+rowspan;
+                    for(int k=0;k<rowspan-1;k++){
+                        String dataInfo = rowData[k+2+i];
+                        if(dataInfo==null){
+                            dataInfo = x1+":"+x2;
+                        }else{
+                            String [] dataInfo2 = dataInfo.split(",");
+                            String dataInfo3 = dataInfo2[dataInfo2.length-1];
+                            int mx1 = Integer.parseInt(dataInfo3.split(":")[0]);
+                            int mx2 = Integer.parseInt(dataInfo3.split(":")[1]);
+                            if(mx2+1==x1){
+                                dataInfo = dataInfo+","+mx1+":"+x2;
+                            }else{
+                                dataInfo = dataInfo+","+x1+":"+x2;
+                            }
+                        }
+                        rowData[k+2+i] = dataInfo;
+                    }
+                }
+
+                String getRowInfo = rowData[y1];
+                if(getRowInfo!=null){
+                    String [] dataInfo2 = getRowInfo.split(",");
+                    if(getRowInfo.indexOf("1")>=0 && j==0){
+                        for(int m =0;m<dataInfo2.length ;m++){
+                            int mx1 = Integer.parseInt(dataInfo2[m].split(":")[0]);
+                            int mx2 = Integer.parseInt(dataInfo2[m].split(":")[1]);
+                            x = mx2;
+                        }
+                        x1 = x+x1;
+                        x2 = x+x2;
+                        x = x+1 ; //计算自己
+                    }else{
+                        for(int m =0;m<dataInfo2.length ;m++){
+                            int mx1 = Integer.parseInt(dataInfo2[m].split(":")[0]);
+                            int mx2 = Integer.parseInt(dataInfo2[m].split(":")[1]);
+                            if(x2+1 == mx1){
+                                x = mx2 ;
+                            }
+                        }
+                    }
+                }
+
+
+               // System.out.println(StringUtil.trimAllWhitespace(textInfo)+""+StringUtil.trimAllWhitespace(textInfo).length());
+                data.text(textInfo.replaceAll(" ",""));
+
+
+                // 设置td 属性
+                data.attr("trIndex",i+"");
+                data.attr("tdIndex",j+"");
+                data.attr("x1",x1+"");
+                data.attr("x2",x2+"");
+                data.attr("y1",y1+"");
+                data.attr("y2",y2+"");
+
+
+
+                // 设置文本信息
+               /* if(textInfo.indexOf("年")>=0 && textInfo.indexOf("月")>=0&& textInfo.indexOf("日")>=0){
+                    data.empty().append("<input type='time' style='width:100%;height:100%' placeholder=''> </input>");
+                }*/
+                if(textInfo.isEmpty() || textInfo.equals("/") || textInfo.equals("—") || textInfo.equals("—") || textInfo.equals("-")){
+                    if(index_stat){
+                        data.empty().append("<input type='text' style='width:100%;height:100%' placeholder=''> </input>");
+                    }else{
+                        if(j==0 ){
+                            if(colspan ==maxCol && i>=1 && i<=2){
+                                data.empty().append("<input type='text' style='width:100%;height:100%' placeholder=''> </input>");
+                            }
+                        }else{
+                            Element bforData = tds.get(j-1);
+                            if(!bforData.text().isEmpty()){
+                                data.empty().append("<input type='text' style='width:100%;height:100%' placeholder=''> </input>");
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        // 写入
+        inputStream.close();
+        String inHtmlUrl = "/Users/hongchuangyanfa/Desktop/123654.html";
+        //saveAsFileWriter(doc.html(),inHtmlUrl);
+        File writefile = new File(inHtmlUrl);
+        FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
+    }
+}

+ 33 - 16
blade-service/blade-manager/src/main/java/org/springblade/manager/controller/LinkdataInfoController.java

@@ -27,6 +27,7 @@ import org.springblade.core.mp.support.Condition;
 import org.springblade.core.mp.support.Query;
 import org.springblade.core.tool.api.R;
 import org.springblade.core.tool.utils.Func;
+import org.springblade.manager.service.IWbsFormElementService;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.bind.annotation.RequestParam;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -49,10 +50,11 @@ public class LinkdataInfoController extends BladeController {
 
 	private final ILinkdataInfoService linkdataInfoService;
 
+	private final IWbsFormElementService wbsFormElementService;
 	/**
 	 * 详情
 	 */
-/*	@GetMapping("/detail")
+	@GetMapping("/detail")
 	@ApiOperationSupport(order = 1)
 	@ApiOperation(value = "详情", notes = "传入linkdataInfo")
 	public R<LinkdataInfo> detail(LinkdataInfo linkdataInfo) {
@@ -60,6 +62,8 @@ public class LinkdataInfoController extends BladeController {
 		return R.data(detail);
 	}
 
+
+/*
 	*//**
 	 * 分页 清表解析字段信息
 	 *//*
@@ -80,11 +84,11 @@ public class LinkdataInfoController extends BladeController {
 	public R<IPage<LinkdataInfoVO>> page(LinkdataInfoVO linkdataInfo, Query query) {
 		IPage<LinkdataInfoVO> pages = linkdataInfoService.selectLinkdataInfoPage(Condition.getPage(query), linkdataInfo);
 		return R.data(pages);
-	}
+	}*/
 
-	*//**
+	/**
 	 * 新增 清表解析字段信息
-	 *//*
+	 */
 	@PostMapping("/save")
 	@ApiOperationSupport(order = 4)
 	@ApiOperation(value = "新增", notes = "传入linkdataInfo")
@@ -92,9 +96,9 @@ public class LinkdataInfoController extends BladeController {
 		return R.status(linkdataInfoService.save(linkdataInfo));
 	}
 
-	*//**
+	/**
 	 * 修改 清表解析字段信息
-	 *//*
+	 */
 	@PostMapping("/update")
 	@ApiOperationSupport(order = 5)
 	@ApiOperation(value = "修改", notes = "传入linkdataInfo")
@@ -102,35 +106,48 @@ public class LinkdataInfoController extends BladeController {
 		return R.status(linkdataInfoService.updateById(linkdataInfo));
 	}
 
-	*//**
+	/**
 	 * 新增或修改 清表解析字段信息
-	 *//*
+	 */
 	@PostMapping("/submit")
 	@ApiOperationSupport(order = 6)
 	@ApiOperation(value = "新增或修改", notes = "传入linkdataInfo")
 	public R submit(@Valid @RequestBody LinkdataInfo linkdataInfo) {
+
 		return R.status(linkdataInfoService.saveOrUpdate(linkdataInfo));
-	}*/
+	}
 
 	
 	/**
 	 * 删除 清表解析字段信息
 	 */
-/*	@PostMapping("/remove")
+	@PostMapping("/remove")
 	@ApiOperationSupport(order = 7)
 	@ApiOperation(value = "逻辑删除", notes = "传入ids")
 	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
-		return R.status(linkdataInfoService.deleteLogic(Func.toLongList(ids)));
-	}*/
+		linkdataInfoService.removeByIds(Func.toLongList(ids));
+		return R.success("成功!");
+	}
 
 	/**
-	 *  获取字段信息 下拉框
+	 *  获取excel字段信息 下拉框
 	 */
 	@GetMapping("/getColByTabId")
-	@ApiOperationSupport(order = 7)
-	@ApiOperation(value = "获取字段信息", notes = "传入ids")
-	public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String tabId) {
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "获取excel字段信息", notes = "传入ids")
+	public R getColByTabId(@ApiParam(value = "主键集合", required = true) @RequestParam String tabId) {
 		return R.data(linkdataInfoService.getColSelect(tabId));
 	}
 
+
+	/**
+	 *  获取元素信息通过tableId 下拉框
+	 */
+	@GetMapping("/getElementInfoByTabId")
+	@ApiOperationSupport(order = 8)
+	@ApiOperation(value = "获取excel字段信息", notes = "传入ids")
+	public R getElementInfo(@ApiParam(value = "主键集合", required = true) @RequestParam String tabId) {
+		return R.data(wbsFormElementService.selectElementListByFid(tabId));
+	}
+
 }

+ 2 - 2
blade-service/blade-system/src/main/java/org/springblade/system/mapper/MenuMapper.xml

@@ -250,7 +250,7 @@
         is_deleted = 0 and id IN (
         SELECT parent_id FROM blade_menu
         WHERE ( category = 2 AND id IN ( SELECT menu_id FROM blade_role_menu WHERE role_id IN
-        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+        <foreach collection="param1" index="index" item="item" open="(" separator="," close=")">
             #{item}
         </foreach>
         ) ) )
@@ -272,7 +272,7 @@
         blade_menu
         WHERE
         is_deleted = 0 and  category = 2 AND id IN ( SELECT menu_id FROM blade_role_menu WHERE role_id IN
-        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">
+        <foreach collection="param1" index="index" item="item" open="(" separator="," close=")">
             #{item}
         </foreach>)
         and sys_id =(SELECT id from blade_client where client_id=#{param2})