|
@@ -14,7 +14,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.mixsmart.utils.FormulaUtils;
|
|
|
import com.mixsmart.utils.ListUtils;
|
|
|
import com.mixsmart.utils.RegexUtils;
|
|
|
+import com.spire.xls.ExcelPicture;
|
|
|
import com.spire.xls.FileFormat;
|
|
|
+import com.spire.xls.Worksheet;
|
|
|
+import com.spire.xls.collections.PicturesCollection;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
@@ -65,10 +68,7 @@ import org.springblade.manager.formula.NodeTable;
|
|
|
import org.springblade.manager.formula.impl.TableElementConverter;
|
|
|
import org.springblade.manager.mapper.ExcelTabMapper;
|
|
|
import org.springblade.manager.service.*;
|
|
|
-import org.springblade.manager.utils.FileUtils;
|
|
|
-import org.springblade.manager.utils.PdfAddContextUtils;
|
|
|
-import org.springblade.manager.utils.PdfAddimgUtil;
|
|
|
-import org.springblade.manager.utils.RandomNumberHolder;
|
|
|
+import org.springblade.manager.utils.*;
|
|
|
import org.springblade.manager.vo.*;
|
|
|
import org.springblade.resource.feign.NewIOSSClient;
|
|
|
import org.springblade.system.cache.ParamCache;
|
|
@@ -88,6 +88,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
|
|
|
|
|
import java.io.*;
|
|
|
+import java.net.URL;
|
|
|
import java.nio.file.Files;
|
|
|
import java.text.ParseException;
|
|
|
import java.text.SimpleDateFormat;
|
|
@@ -97,6 +98,7 @@ import java.util.concurrent.CountDownLatch;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
import java.util.function.Function;
|
|
|
import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
import static java.util.stream.Collectors.toMap;
|
|
@@ -130,7 +132,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
private final TableInfoServiceImpl tableInfoService;
|
|
|
private final INodeBaseInfoService nodeBaseInfoService;
|
|
|
private final TrialSelfInspectionRecordClient trialSelfInspectionRecordClient;
|
|
|
-
|
|
|
+ // excel 解析结构
|
|
|
+ private final IExctabCellService exctabCellService;
|
|
|
|
|
|
@Autowired
|
|
|
StringRedisTemplate RedisTemplate;
|
|
@@ -853,7 +856,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
int status = callback.getStatus();
|
|
|
int saved = 0;
|
|
|
//status=6,表示点击保存按钮 2 关闭保存
|
|
|
- /*if (status == 3 || status == 6) //MustSave, Corrupted
|
|
|
+ if (status == 3 || status == 6) //MustSave, Corrupted
|
|
|
{
|
|
|
//获取url
|
|
|
String downloadUri = callback.getUrl();
|
|
@@ -893,6 +896,8 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
excelTab.setHtmlUrl(thmlUrl);
|
|
|
baseMapper.updateById(excelTab);
|
|
|
|
|
|
+ expailHtmlInfo(thmlUrl, excelTab.getId(), excelTab.getTabType() + "");
|
|
|
+
|
|
|
File file2 = new File(dataUrl);
|
|
|
if (file2.exists()) {
|
|
|
file2.delete();
|
|
@@ -902,7 +907,7 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
editCallback.setError(1);
|
|
|
e.printStackTrace();
|
|
|
}
|
|
|
- }*/
|
|
|
+ }
|
|
|
return editCallback;
|
|
|
}
|
|
|
|
|
@@ -5630,4 +5635,595 @@ public class ExcelTabServiceImpl extends BaseServiceImpl<ExcelTabMapper, ExcelTa
|
|
|
}
|
|
|
//
|
|
|
}
|
|
|
+
|
|
|
+ public void expailHtmlInfo(String thmlUrl, Long excelId, String tabType) throws Exception {
|
|
|
+
|
|
|
+ // 读取
|
|
|
+ File file1 = ResourceUtil.getFile(thmlUrl);
|
|
|
+ String htmlString = IoUtil.readToString(new FileInputStream(file1));
|
|
|
+
|
|
|
+ /*
|
|
|
+ 解析
|
|
|
+ 1 解析样式
|
|
|
+ 2 计算坐标
|
|
|
+ 3 计算区域位置
|
|
|
+ */
|
|
|
+ // 样式集合
|
|
|
+ Document doc = Jsoup.parse(htmlString);
|
|
|
+ // 解析 style
|
|
|
+ Map<String, String> styleMap = getHtmlStyle(doc);
|
|
|
+ //解析
|
|
|
+ Element table = doc.select("table").first();
|
|
|
+
|
|
|
+ Elements trs = table.select("tr");
|
|
|
+ Element tableinfo = trs.get(0).parent().parent().attr("style", "border-collapse: collapse;");
|
|
|
+
|
|
|
+ // 获取图片信息
|
|
|
+ Elements imgs = doc.select("img");
|
|
|
+
|
|
|
+
|
|
|
+ // 获取总行列数
|
|
|
+ int maxCol = doc.select("Col").size();
|
|
|
+ String[] rowData = new String[trs.size() + 5]; //本来加一的 害怕出现特殊情况 故意 加 5
|
|
|
+
|
|
|
+ // 行的状态
|
|
|
+ boolean index_state = false;
|
|
|
+ // 区域划分表示
|
|
|
+ int xy_type = 1;
|
|
|
+
|
|
|
+ // 解析 excel元素集合
|
|
|
+ List<ExctabCell> colTitle = new ArrayList<>();
|
|
|
+
|
|
|
+// 标题集合信息
|
|
|
+ List<Map<String, String>> zikey = new ArrayList<>();
|
|
|
+ for (int i = 0; i <= trs.size() - 1; i++) {
|
|
|
+ Element tr = trs.get(i);
|
|
|
+ Elements tds = tr.select("td");
|
|
|
+
|
|
|
+ String xyInof = getTrInfo(tds, styleMap, index_state, xy_type, maxCol, i, zikey);
|
|
|
+
|
|
|
+ xy_type = Integer.parseInt(xyInof.split(",")[0]);
|
|
|
+ tr.attr("xy_type", xyInof);
|
|
|
+ index_state = Boolean.parseBoolean(xyInof.split(",")[1]);
|
|
|
+ boolean isMaxCol = Integer.parseInt(xyInof.split(",")[2]) == maxCol;
|
|
|
+
|
|
|
+ boolean istrue = Boolean.parseBoolean(xyInof.split(",")[3]);
|
|
|
+
|
|
|
+
|
|
|
+ // 计算单元格坐标
|
|
|
+ int x = 0;
|
|
|
+
|
|
|
+ for (int j = 0; j < tds.size(); j++) {
|
|
|
+ {
|
|
|
+ Element data = tds.get(j);
|
|
|
+ Boolean isText = false;
|
|
|
+ //判断高度
|
|
|
+ String style = data.attr("style");
|
|
|
+ if (StringUtils.isNotBlank(style)) {
|
|
|
+ int index = style.lastIndexOf(":");
|
|
|
+ String substring = style.substring(index + 1);
|
|
|
+ String height = substring.substring(0, substring.length() - 3);
|
|
|
+ int i1 = 0;
|
|
|
+ try {
|
|
|
+ i1 = Integer.parseInt(height);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ substring = style.substring(style.lastIndexOf(":", index - 1) + 1);
|
|
|
+ height = substring.substring(0, substring.indexOf("px;"));
|
|
|
+ i1 = Integer.parseInt(height);
|
|
|
+ }
|
|
|
+ if (i1 > 90) {
|
|
|
+ isText = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String trHtml = data.html();
|
|
|
+ int colspan = data.attr("COLSPAN").equals("") ? 0 : Integer.parseInt(data.attr("COLSPAN"));
|
|
|
+ int rowspan = data.attr("ROWSPAN").equals("") ? 0 : Integer.parseInt(data.attr("ROWSPAN"));
|
|
|
+ String keyId = data.attr("class");
|
|
|
+ if (StringUtils.isNotEmpty(keyId)) {
|
|
|
+ String classInfo = styleMap.get(keyId);
|
|
|
+ data.removeAttr("class");
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, String> textObject = new HashMap<>();
|
|
|
+ // 计算
|
|
|
+ int x1 = 0;
|
|
|
+ int x2 = 0;
|
|
|
+ int y1 = 0;
|
|
|
+ int y2 = 0;
|
|
|
+
|
|
|
+ String textInfo = data.text().trim().replaceAll(" ", "");
|
|
|
+
|
|
|
+ y1 = i + 1;
|
|
|
+ //x 移位 算法
|
|
|
+ String getRowInfo = rowData[y1];
|
|
|
+
|
|
|
+ if (getRowInfo != null) {
|
|
|
+ String[] dataInfo2 = getRowInfo.split(",");
|
|
|
+
|
|
|
+ // 排序
|
|
|
+ int lastMax = 0;
|
|
|
+ List<String> datax = Arrays.stream(dataInfo2).sorted((a, b) -> Integer.parseInt(a.split(":")[1]) - Integer.parseInt(b.split(":")[1])).collect(Collectors.toList());
|
|
|
+ List<String> lastdata = new ArrayList<>();
|
|
|
+ //组合
|
|
|
+ for (int h = 0; h < datax.size(); h++) {
|
|
|
+ int mx1 = Integer.parseInt(datax.get(h).split(":")[0]);
|
|
|
+ int mx2 = Integer.parseInt(datax.get(h).split(":")[1]);
|
|
|
+ if (lastdata.size() == 0) {
|
|
|
+ lastdata.add(datax.get(0));
|
|
|
+ } else {
|
|
|
+ if (lastMax + 1 == mx1) {
|
|
|
+ int minVal = Integer.parseInt(lastdata.get(lastdata.size() - 1).split(":")[0]);
|
|
|
+ lastdata.remove(lastdata.size() - 1);
|
|
|
+ lastdata.add(minVal + ":" + mx2);
|
|
|
+ } else {
|
|
|
+ lastdata.add(datax.get(h));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lastMax = mx2;
|
|
|
+ }
|
|
|
+ dataInfo2 = lastdata.stream().toArray(String[]::new);
|
|
|
+
|
|
|
+ // 先逻辑处理 连续时,归一
|
|
|
+ if ((dataInfo2[0].split(":")[0]).equals("1") && j == 0) {
|
|
|
+ x = Integer.parseInt(dataInfo2[0].split(":")[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 ((mx1 - x) == 1 && mx1 > x) {
|
|
|
+ x = mx2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // X 坐标
|
|
|
+
|
|
|
+
|
|
|
+ if (tds.size() == 1) {
|
|
|
+ if (colspan == 0) {
|
|
|
+ x1 = x + 1;
|
|
|
+ x2 = x + 1;
|
|
|
+ } else {
|
|
|
+ if (x == 0) {
|
|
|
+ x1 = 1;
|
|
|
+ x2 = colspan;
|
|
|
+ } else {
|
|
|
+ x1 = x + 1;
|
|
|
+ x2 = x + colspan;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (colspan == 0) {
|
|
|
+ x1 = x + 1;
|
|
|
+ x2 = x + 1;
|
|
|
+ x = x2;
|
|
|
+ } else {
|
|
|
+ x1 = x + 1;
|
|
|
+ x2 = x + colspan;
|
|
|
+ x = x2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //x y 坐标
|
|
|
+ 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 {
|
|
|
+ dataInfo = dataInfo + "," + x1 + ":" + x2;
|
|
|
+ String[] arr = dataInfo.split(",");
|
|
|
+ //排序
|
|
|
+ for (int r = 0; r < arr.length - 1; r++) {
|
|
|
+ for (int q = arr.length - 2; q >= r; q--) {
|
|
|
+ Integer jval = Integer.parseInt(arr[q + 1].split(":")[0]);
|
|
|
+ Integer jval1 = Integer.parseInt(arr[q].split(":")[0]);
|
|
|
+ if (jval < jval1) {
|
|
|
+ String temp = arr[q + 1];
|
|
|
+ arr[q + 1] = arr[q];
|
|
|
+ arr[q] = temp;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //组合
|
|
|
+ String newDataInfo = "";
|
|
|
+ for (int r = 0; r < arr.length; r++) {
|
|
|
+ if (r == 0) {
|
|
|
+ newDataInfo = arr[0];
|
|
|
+ } else {
|
|
|
+ int StrMax = Integer.parseInt(newDataInfo.substring(newDataInfo.lastIndexOf(":") + 1, newDataInfo.length()));
|
|
|
+ Integer nowMin = Integer.parseInt(arr[r].split(":")[0]);
|
|
|
+ Integer nowMax = Integer.parseInt(arr[r].split(":")[1]);
|
|
|
+ if ((StrMax + 1) == nowMin) {
|
|
|
+ String lastStr = "";
|
|
|
+ if (newDataInfo.indexOf(",") >= 0) {
|
|
|
+ lastStr = newDataInfo.substring(newDataInfo.lastIndexOf(",") + 1, newDataInfo.length());
|
|
|
+ newDataInfo = newDataInfo.substring(0, newDataInfo.lastIndexOf(","));
|
|
|
+ } else {
|
|
|
+ lastStr = newDataInfo;
|
|
|
+ newDataInfo = "";
|
|
|
+ }
|
|
|
+ int lastmin = Integer.parseInt(lastStr.split(":")[0]);
|
|
|
+ if (StringUtils.isNotEmpty(newDataInfo)) {
|
|
|
+ newDataInfo = newDataInfo + "," + lastmin + ":" + nowMax;
|
|
|
+ } else {
|
|
|
+ newDataInfo = lastmin + ":" + nowMax;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ newDataInfo = newDataInfo + "," + nowMin + ":" + nowMax;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ dataInfo = newDataInfo;
|
|
|
+ }
|
|
|
+ rowData[k + 2 + i] = dataInfo;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ data.text(textInfo.replaceAll(" ", ""));
|
|
|
+ if (textInfo.indexOf("□") < 0 && !textInfo.isEmpty() && !(textInfo.equals("/") && textInfo.length() < 2) && !(textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) && !textInfo.equals("—") && !textInfo.equals("-")) { // 标题区域
|
|
|
+ Map<String, String> dataInfo = new HashMap<String, String>();
|
|
|
+ dataInfo.put("name", textInfo);
|
|
|
+ dataInfo.put("x1", x1 + "");
|
|
|
+ dataInfo.put("x2", x2 + "");
|
|
|
+ dataInfo.put("y1", y1 + "");
|
|
|
+ dataInfo.put("y2", y2 + "");
|
|
|
+ dataInfo.put("xytype", xy_type + "");
|
|
|
+ if (textInfo.indexOf("/") < 0 || (textInfo.indexOf("/") >= 0 && textInfo.length() > 1)) { // 带/为分割数据
|
|
|
+ zikey.add(dataInfo);
|
|
|
+ }
|
|
|
+ } else { //空行
|
|
|
+ List<Map<String, String>> left = new ArrayList<>();
|
|
|
+ List<Map<String, String>> top = new ArrayList<>();
|
|
|
+ for (int k = 0; k < zikey.size(); k++) {
|
|
|
+ String name = zikey.get(k).get("name");
|
|
|
+ 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"));
|
|
|
+ int xytype2 = Integer.parseInt(zikey.get(k).get("xytype"));
|
|
|
+
|
|
|
+ // 左匹配
|
|
|
+ if (yy1 <= y1 && yy2 >= y2 && xx2 < x1 && xytype2 == xy_type) {
|
|
|
+ left.add(zikey.get(k));
|
|
|
+ }
|
|
|
+
|
|
|
+ //向 上 匹配
|
|
|
+ if (index_state) {
|
|
|
+ if (xx1 <= x1 && xx2 >= x2 && yy2 < y1 && xytype2 == xy_type) {
|
|
|
+ top.add(zikey.get(k));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ String inputText = "";
|
|
|
+ // 特征值赛选 规则
|
|
|
+ for (int k = 0; k < left.size(); k++) { // 左计算
|
|
|
+ String name = left.get(k).get("name");
|
|
|
+ int xx1 = Integer.parseInt(left.get(k).get("x1"));
|
|
|
+ int xx2 = Integer.parseInt(left.get(k).get("x2"));
|
|
|
+ int yy1 = Integer.parseInt(left.get(k).get("y1"));
|
|
|
+ int yy2 = Integer.parseInt(left.get(k).get("y2"));
|
|
|
+
|
|
|
+ if (!StringUtil.isNumeric(name) && name.length() <= 20) { // 数字不匹配
|
|
|
+ if (index_state) { // 正向规则匹配
|
|
|
+ if (istrue) { // 是否空格等于值
|
|
|
+ if (x1 - xx2 <= 1 && y1 == yy2) {
|
|
|
+ inputText = name;
|
|
|
+ } else {
|
|
|
+ inputText += name + "_";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ inputText += name + "_";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (x1 - xx2 <= 1 && y1 == yy2) {
|
|
|
+ inputText = name;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 特征值赛选 规则
|
|
|
+ if (top != null && top.size() >= 1) {
|
|
|
+ for (int k = 0; k < top.size(); k++) { // 向上计算
|
|
|
+ String name = top.get(k).get("name");
|
|
|
+ int xx1 = Integer.parseInt(top.get(k).get("x1"));
|
|
|
+ int xx2 = Integer.parseInt(top.get(k).get("x2"));
|
|
|
+ int yy1 = Integer.parseInt(top.get(k).get("y1"));
|
|
|
+ int yy2 = Integer.parseInt(top.get(k).get("y2"));
|
|
|
+ if (!StringUtil.isNumeric(name) && name.length() <= 20) {
|
|
|
+ inputText += name + "_";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (inputText != null && inputText != "" && inputText.indexOf("_") >= 0) {
|
|
|
+ inputText = inputText.substring(0, inputText.lastIndexOf("_"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 质检表特殊处理匹配
|
|
|
+
|
|
|
+ String parm = i + "," + j + "," + x1 + "," + x2 + "," + y1 + "," + y2 + ",$event";
|
|
|
+ // 设置文本信息
|
|
|
+ ExctabCell exctabCell = new ExctabCell();
|
|
|
+ if ((textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) || inputText.indexOf("日期") >= 0) {
|
|
|
+ if (inputText.indexOf("日期") >= 0) {
|
|
|
+ data.empty().append("<el-date-picker type='date' @keyDowns='dateKeydown()' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + " x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='" + inputText + "'> </el-date-picker>");
|
|
|
+ } else if (textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) {
|
|
|
+ if (inputText.indexOf("专业监理工程师") >= 0) {
|
|
|
+ inputText = "专业监理工程师_年月日";
|
|
|
+ } else if (inputText.indexOf("质检工程师") >= 0) {
|
|
|
+ inputText = "质检工程师_年月日";
|
|
|
+ } else {
|
|
|
+ inputText = "年月日";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ data.empty().append("<el-date-picker @keyDowns='dateKeydown()' type='date' format='YYYY年MM月DD日' value-format='YYYY年MM月DD日' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + " x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder='年月日'> </el-date-picker>");
|
|
|
+ exctabCell.setTextInfo(inputText);
|
|
|
+ exctabCell.setExctabId(excelId);
|
|
|
+ exctabCell.setIsDeleted(0);
|
|
|
+ exctabCell.setXys(i + "_" + j);
|
|
|
+ colTitle.add(exctabCell);
|
|
|
+ data.attr("title", inputText);
|
|
|
+
|
|
|
+ } else if (textInfo.indexOf("□") >= 0) { //多选框
|
|
|
+ exctabCell.setTextInfo(inputText);
|
|
|
+ exctabCell.setExctabId(excelId);
|
|
|
+ exctabCell.setIsDeleted(0);
|
|
|
+ exctabCell.setXys(i + "_" + j);
|
|
|
+ colTitle.add(exctabCell);
|
|
|
+ data.attr("title", inputText);
|
|
|
+ // 添加多选框
|
|
|
+
|
|
|
+ String[] cheText = textInfo.split("□");
|
|
|
+ JSONArray objs = new JSONArray();
|
|
|
+ if (cheText != null && cheText.length >= 1) {
|
|
|
+ int key = 1;
|
|
|
+ for (String keyval : cheText) {
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ if (StringUtils.isNotEmpty(keyval)) {
|
|
|
+ jsonObject.put("key", key);
|
|
|
+ jsonObject.put("name", keyval);
|
|
|
+ objs.add(jsonObject);
|
|
|
+ keyId += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ JSONObject jsonObject = new JSONObject();
|
|
|
+ jsonObject.put("key", "1");
|
|
|
+ jsonObject.put("name", "");
|
|
|
+ objs.add(jsonObject);
|
|
|
+ }
|
|
|
+
|
|
|
+ String checkbox = "<hc-form-checkbox-group @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' :objs='" + objs + "' @change='checkboxGroupChange' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + " x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " placeholder=''> </hc-form-checkbox-group>";
|
|
|
+ data.empty().append(checkbox);
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ if (index_state) { // 区域内
|
|
|
+ if (rowspan >= 1 || isText) {
|
|
|
+ data.empty().append("<el-input type='textarea' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='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' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + " x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
|
|
|
+ }
|
|
|
+ } else if (tabType.equals("100") && i < 2) { //计量特殊添加
|
|
|
+ data.empty().append("<el-input type='text' @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='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) {
|
|
|
+ if (rowspan >= 1 || isText) {
|
|
|
+ data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='textarea' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='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 @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='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() || bforData.html().indexOf("hc-form-checkbox-group") >= 0) {
|
|
|
+ if (rowspan >= 1 || isText) {
|
|
|
+ data.empty().append("<el-input @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='textarea' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='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 @keydown.shift.up='keyupShiftUp' @keydown.shift.down='keyupShiftDown' @keydown.shift.left='keyupShiftLeft' @keydown.shift.right='keyupShiftRight' type='text' @contextmenu.prevent.native='contextmenuClick(" + parm + ")' @mouseup.right='RightClick(" + parm + ")' trIndex=" + i + " tdIndex=" + j + " x1=" + x1 + " x2=" + x2 + " y1=" + y1 + " y2=" + y2 + " style='width:100%;height:100%;' placeholder=''> </el-input>");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!inputText.equals("")) {
|
|
|
+ exctabCell.setExctabId(excelId);
|
|
|
+ exctabCell.setTextInfo(inputText);
|
|
|
+ if (inputText.contains("日期") || inputText.contains("年") || inputText.contains("月") || inputText.contains("日")) {
|
|
|
+ //日期
|
|
|
+ exctabCell.setTextElementType(4);
|
|
|
+ } else if (inputText.indexOf("签字") >= 0) {
|
|
|
+ exctabCell.setTextElementType(6);
|
|
|
+ } else {
|
|
|
+ //字符串
|
|
|
+ exctabCell.setTextElementType(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ exctabCell.setIsDeleted(0);
|
|
|
+ exctabCell.setXys(i + "_" + j);
|
|
|
+ colTitle.add(exctabCell);
|
|
|
+ }
|
|
|
+ data.attr("title", inputText);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //System.out.println(zikey);
|
|
|
+ // 去掉重复的数
|
|
|
+ Map<String, String> groupMap2 = colTitle.stream()
|
|
|
+ .collect(Collectors.groupingBy(ExctabCell::getTextInfo, Collectors.mapping(ExctabCell::getXys, Collectors.joining(","))));
|
|
|
+
|
|
|
+ exctabCellService.DeletExcelByTableId(excelId + "");
|
|
|
+
|
|
|
+ List<ExctabCell> colTitle2 = new ArrayList<>();
|
|
|
+ for (String title : groupMap2.keySet()) {
|
|
|
+ ExctabCell exctabCell = new ExctabCell();
|
|
|
+ exctabCell.setExctabId(excelId);
|
|
|
+ exctabCell.setIsDeleted(0);
|
|
|
+ exctabCell.setTextInfo(title);
|
|
|
+ exctabCell.setCreateTime(new Date());
|
|
|
+
|
|
|
+ if (title.contains("日期") || title.contains("年") || title.contains("月") || title.contains("日")) {
|
|
|
+ //日期
|
|
|
+ exctabCell.setTextElementType(4);
|
|
|
+ } else {
|
|
|
+ //字符串
|
|
|
+ exctabCell.setTextElementType(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ exctabCell.setXys(groupMap2.get(title));
|
|
|
+ colTitle2.add(exctabCell);
|
|
|
+ }
|
|
|
+ exctabCellService.saveBatch(colTitle2);
|
|
|
+
|
|
|
+
|
|
|
+ //对excel 的图片进行操作
|
|
|
+ ExcelTab exceltab = this.getById(excelId);
|
|
|
+ if (exceltab != null) {
|
|
|
+ // 获取excle 的数据
|
|
|
+ String fileUrl = exceltab.getFileUrl();
|
|
|
+ InputStream ossInputStream = CommonUtil.getOSSInputStream(fileUrl);
|
|
|
+ com.spire.xls.Workbook wb = new com.spire.xls.Workbook();
|
|
|
+ wb.loadFromMHtml(ossInputStream);
|
|
|
+ Worksheet sheet = wb.getWorksheets().get(0);
|
|
|
+ PicturesCollection pictures = sheet.getPictures();
|
|
|
+ if (pictures != null && pictures.size() >= 1) {
|
|
|
+ for (int i = 0; i < pictures.size(); i++) {
|
|
|
+ ExcelPicture pic = pictures.get(i);
|
|
|
+ int x = pic.getLeftColumn();
|
|
|
+ int y = pic.getBottomRow();
|
|
|
+ Elements select = doc.select("el-input[x1=" + x + "][y1=" + y + "]");
|
|
|
+ System.out.println("xx=--" + x);
|
|
|
+ System.out.println("yy=--" + y);
|
|
|
+ if (select != null && select.size() >= 1) {
|
|
|
+ Element element = select.get(0);
|
|
|
+ Element elementP = element.parent();
|
|
|
+ element.remove();
|
|
|
+ Element imgele = imgs.get(i);
|
|
|
+ imgele.removeAttr("class");
|
|
|
+ elementP.append(imgele.toString());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ossInputStream.close();
|
|
|
+ }
|
|
|
+ // 移除图片
|
|
|
+ imgs.remove();
|
|
|
+ // 保存
|
|
|
+ exceltab.setIsDeleted(8);
|
|
|
+ this.saveOrUpdate(exceltab);
|
|
|
+ File writefile = new File(thmlUrl);
|
|
|
+ FileUtil.writeToFile(writefile, doc.html(), Boolean.parseBoolean("UTF-8"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取解析样式
|
|
|
+ public static Map<String, String> getHtmlStyle(Document doc) {
|
|
|
+ Map<String, String> styleMap = new HashMap<>();
|
|
|
+ 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));
|
|
|
+ }
|
|
|
+ return styleMap;
|
|
|
+ }
|
|
|
+
|
|
|
+ //计算区域坐标
|
|
|
+ public static String getTrInfo(Elements tds, Map<String, String> styleMap, boolean index_state, Integer xy_type, int maxCol, int y, List<Map<String, String>> zikey) {
|
|
|
+
|
|
|
+ int x_width = 0;
|
|
|
+ int y_width = 0;
|
|
|
+ int text_width = 0;
|
|
|
+ int width = 0;
|
|
|
+
|
|
|
+ int null_count = 0;
|
|
|
+ int val_count = 0;
|
|
|
+
|
|
|
+ boolean istrue = true;
|
|
|
+
|
|
|
+ // 上 tr 长度
|
|
|
+
|
|
|
+ List<Map<String, String>> maxList = zikey.stream().filter(map -> Integer.parseInt(map.get("y1")) <= y && y <= Integer.parseInt(map.get("y2"))).collect(Collectors.toList());
|
|
|
+
|
|
|
+ int top1_max = 0;
|
|
|
+ if (maxList != null && maxList.size() >= 1) {
|
|
|
+ top1_max = maxList.stream().mapToInt(m -> Integer.parseInt(m.get("x2"))).max().getAsInt();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //区域计算
|
|
|
+ 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"));
|
|
|
+ if (colspan == 0) {
|
|
|
+ colspan = data.attr("colspan").equals("") ? 1 : Integer.parseInt(data.attr("colspan"));
|
|
|
+ }
|
|
|
+ String classInfo = styleMap.get(keyId);
|
|
|
+ String textInfo = data.text().trim().replaceAll(" ", "");
|
|
|
+
|
|
|
+ if (classInfo == null) {
|
|
|
+ classInfo = data.attr("style");
|
|
|
+ } else {
|
|
|
+ data.removeAttr("class");
|
|
|
+ data.attr("style", styleMap.get(keyId).replaceAll("break-word", "inherit"));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算线开始
|
|
|
+ if (classInfo.indexOf("border-left-style") >= 0 && classInfo.indexOf("border-top-style") >= 0 && classInfo.indexOf("border-right-style") >= 0) {
|
|
|
+ x_width += colspan;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算结束
|
|
|
+ if (classInfo.indexOf("border-left-style") < 0 && (classInfo.indexOf("border-top-style") < 0 || classInfo.indexOf("border-top-style") >= 0) && classInfo.indexOf("border-bottom-style") < 0 && classInfo.indexOf("border-right-style") < 0) {
|
|
|
+ y_width += colspan;
|
|
|
+ }
|
|
|
+
|
|
|
+ String name = data.text();
|
|
|
+ if (!name.isEmpty()) {
|
|
|
+ text_width += colspan;
|
|
|
+ }
|
|
|
+ width += colspan;
|
|
|
+
|
|
|
+ if (!textInfo.isEmpty() && !(textInfo.equals("/") && textInfo.length() <= 2) && !(textInfo.indexOf("年") >= 0 && textInfo.indexOf("月") >= 0 && textInfo.indexOf("日") >= 0) && !textInfo.equals("—") && !textInfo.equals("-")) { // 标题区域
|
|
|
+ val_count++;
|
|
|
+ } else {
|
|
|
+ null_count++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 在区域内
|
|
|
+ // System.out.println(index_state+"——"+y+"__"+x_width);
|
|
|
+
|
|
|
+ if (index_state) {
|
|
|
+ //是否需要改变
|
|
|
+ if (maxCol == y_width) { // 是否结束区域值
|
|
|
+ index_state = false;
|
|
|
+ xy_type += 1;
|
|
|
+ }
|
|
|
+ if (maxCol == text_width && top1_max != text_width) { // 是否区域开始时
|
|
|
+ xy_type += 1;
|
|
|
+ }
|
|
|
+ } else { // 区域外
|
|
|
+ if (maxCol == x_width) {
|
|
|
+ index_state = true;
|
|
|
+ xy_type += 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 空是否等于值的个数
|
|
|
+ istrue = null_count == val_count && width == maxCol;
|
|
|
+ return xy_type + "," + index_state + "," + width + "," + istrue;
|
|
|
+ }
|
|
|
}
|