From bfab2994854c125cfd8a7f702fc9d952aabdea0e Mon Sep 17 00:00:00 2001 From: zzs Date: Fri, 7 Mar 2025 09:53:13 +0800 Subject: [PATCH] Revert "feat: bookmark replace" This reverts commit 856275d3c8e937c1f7ad1d55bdb6fab7493660f4. --- .../farmwork/word/core/BookmarkExec.java | 1138 ++--------------- .../wmyun/farmwork/word/wordx/HttpUtils.java | 222 ---- .../java/com/wmyun/farmwork/word/wordx/U.java | 304 ----- 3 files changed, 129 insertions(+), 1535 deletions(-) delete mode 100644 wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/HttpUtils.java delete mode 100644 wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/U.java diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/BookmarkExec.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/BookmarkExec.java index 514aa1c..d9443fa 100644 --- a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/BookmarkExec.java +++ b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/core/BookmarkExec.java @@ -3,35 +3,22 @@ package com.wmyun.farmwork.word.core; import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.file.FileNameUtil; -import cn.hutool.log.Log; -import cn.hutool.log.LogFactory; +import com.wmyun.farmwork.word.core.enums.BookmarkType; import com.wmyun.farmwork.word.core.model.BookmarkReplaceDataModel; +import com.wmyun.farmwork.word.core.model.ext.PictureExData; import com.wmyun.farmwork.word.core.model.ext.TextExData; -import com.wmyun.farmwork.word.wordx.HttpUtils; -import com.wmyun.farmwork.word.wordx.U; import lombok.extern.slf4j.Slf4j; +import org.apache.poi.openxml4j.exceptions.InvalidFormatException; +import org.apache.poi.util.Units; +import org.apache.poi.xwpf.usermodel.*; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark; import org.springframework.stereotype.Component; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.ls.DOMImplementationLS; -import org.w3c.dom.ls.LSSerializer; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; import java.io.*; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.nio.file.Files; -import java.util.*; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; /** @@ -46,1013 +33,146 @@ public class BookmarkExec { public final static String tmpDir = System.getProperty("java.io.tmpdir") + File.separator; - private static int debug = 0; - // 等宽填充 - private static Pattern regEW = Pattern.compile("_EW\\b"); - // 最大宽 - private static Pattern regW = Pattern.compile("_(\\d+)W\\b"); - // 单选框 - private static Pattern regRadio = Pattern.compile("_(\\d+)_Radio$"); - // 复选框 - private static Pattern regCheck = Pattern.compile("_Check$"); - // 格式化 - private static Pattern regFmt = Pattern.compile("_Fmt$"); - // 整型变枚举 - private static Pattern regEnum = Pattern.compile("_Enum$"); - // List循环 min最少要循环的次数 max最多只能循环的次数 offset从第几行开始(首行为0) - private static Pattern regList = Pattern.compile("_(\\d*)List(\\d*)_(\\d*)(Copy|Fill)_([^_]+)$"); - // 图片 - private static Pattern regImg = Pattern.compile("_Img$"); - // 删除 - private static Pattern regDelete = Pattern.compile("^X_Delete(_Last)?$"); - // 解释枚举字符串 - private static Pattern regParseEnum = Pattern.compile("^\\d+"); + public static File replace(List data, byte[] word, File file) { + Map dataMap = data.stream() + .collect(Collectors.toMap(BookmarkReplaceDataModel::getName, b -> b)); + try (XWPFDocument doc = new XWPFDocument(IoUtil.toStream(word))) { + // 收集所有段落 - private static final Log log = LogFactory.get(BookmarkExec.class); + // 1. 正文中的段落 + List allParagraphs = new ArrayList<>(doc.getParagraphs()); - public static File replace(List repData, byte[] word, File file) throws Exception { - Map dataMap = repData.stream() - .filter(d -> d.getExtData() instanceof TextExData) - .collect(Collectors.toMap(BookmarkReplaceDataModel::getName, b -> b.getExtData().getValue())); - File outFile = FileUtil.newFile(tmpDir + "gen/" + FileNameUtil.getName(file)); - File parentDir = outFile.getParentFile(); - if (!parentDir.exists()) { - parentDir.mkdirs(); - } - try (FileOutputStream out = new FileOutputStream(outFile)) { - out.write(parse(IoUtil.toStream(word), new Entity(), dataMap)); - } - return outFile; - } - - public static class Entity { - public int sex; - } - - private static class ListInfo { - public List listData; - public int index; - public String type; - public String itemName; - public Object item; - public List listNode; - public HashMap bookmarkMap; - public int min; - public int max; - public int offset; - public int count = -1; - - public void next() { - if (index >= listData.size()) { - index++; - item = null; - return; - } - item = listData.get(index++); - out("%s 循环 index=%d", itemName, index); - } - - public boolean isEnd() { - if (listData == null) { - return true; - } - if (count == -1) { - count = Math.max(min + offset, listData.size()); - if (max > 0) { - - count = Math.min(max + offset, count); - } - } - if (index > count) { - out("index%d>count%d", index, count); - } - return index > count; - } - } - - private static class Context { - LinkedHashMap fileMap; - org.w3c.dom.Document doc; - org.w3c.dom.Document docRel; - Object entity; - Object obj; - int relationMaxId = 0; - Map relationMap; - Map relationUseMap; - Map> enumsMap; - Map dataMap; - ListInfo listInfo; - } - - public static byte[] parse(File f, Object entity, Map dataMap) { - FileInputStream is; - try { - is = new FileInputStream(f); - } catch (FileNotFoundException e) { - throw new RuntimeException(e); - } - return parse(is, entity, dataMap); - } - - public static byte[] parse(InputStream is, Object entity, Map dataMap) { - LinkedHashMap fileMap = U.unzip(is); - byte[] data = fileMap.get("word/document.xml"); - ByteArrayInputStream bis = new ByteArrayInputStream(data); - try { - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder = factory.newDocumentBuilder(); - org.w3c.dom.Document doc = builder.parse(bis); - Node root = doc.getElementsByTagName("w:document").item(0); - // - Context context = new Context(); - context.fileMap = fileMap; - context.doc = doc; - context.dataMap = dataMap; - context.entity = entity; - context.enumsMap = new HashMap<>(); - context.relationUseMap = new HashMap<>(); - getRelationships(context); - // - parseOne(root, context); - // - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - Transformer former = TransformerFactory.newInstance().newTransformer(); - former.transform(new DOMSource(doc), new StreamResult(bos)); - U.close(is, bos); - fileMap.put("word/document.xml", bos.toByteArray()); - // - if (!context.relationMap.isEmpty()) { - bos = new ByteArrayOutputStream(); - former = TransformerFactory.newInstance().newTransformer(); - former.transform(new DOMSource(context.docRel), new StreamResult(bos)); - U.close(is, bos); - fileMap.put("word/_rels/document.xml.rels", bos.toByteArray()); - } - // - bos = new ByteArrayOutputStream(); - U.zip(bos, fileMap); - return bos.toByteArray(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private static void getRelationships(Context context) { - byte[] data = context.fileMap.get("word/_rels/document.xml.rels"); - ByteArrayInputStream bis = new ByteArrayInputStream(data); - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); - DocumentBuilder builder; - org.w3c.dom.Document docRel; - try { - builder = factory.newDocumentBuilder(); - docRel = builder.parse(bis); - } catch (Throwable e) { - throw new RuntimeException(e); - } - context.relationMap = new HashMap<>(); - NodeList ships = docRel.getElementsByTagName("Relationship"); - for (int i = 0; i < ships.getLength(); i++) { - Element ship = (Element) ships.item(i); - String id = ship.getAttribute("Id"); - int intId = Integer.parseInt(id.substring(3)); - if (intId > context.relationMaxId) { - context.relationMaxId = intId; - } - if (ship.getAttribute("Type").endsWith("/image")) { - context.relationMap.put(id, ship); - } - } - U.close(bis); - context.docRel = docRel; - } - - private static void parseOne(Node root, Context context) { - try { - org.w3c.dom.Document doc = root.getOwnerDocument(); - Object[] box = getBookmark(root); - ArrayList listAll = (ArrayList) box[0]; - HashMap bookmarkMap = (HashMap) box[1]; - out("listAll.size=%d", listAll.size()); - for (int k = 0; k < listAll.size(); k++) { - Node start = listAll.get(k); - Node end = bookmarkMap.get(start); - - String tagName = start.getNodeName(); - if (!"w:bookmarkStart".equals(tagName)) { - continue; - } - String startName = getAttribute(start, "w:name"); - if ("_GoBack".equals(startName)) { - continue; - } - if (end == null) { - out("没有匹配的End start=%s", nodeString(start)); - continue; - } - out("解释标记 %s", startName); - String startId = getAttribute(start, "w:id"); - String endId = getAttribute(end, "w:id"); - // - startName = startName.replaceAll("_\\d+$", ""); - String value; - // - context.obj = context.entity; - if (context.listInfo != null) { - if (context.listInfo.index == 3 && startName.equals("ShipName_EW")) { - startName = startName + ""; - } - if (startName.startsWith(context.listInfo.itemName)) { - context.obj = context.listInfo.item; - startName = startName.substring(context.listInfo.itemName.length()); + // 2. 正文中表格内的段落 + for (XWPFTable table : doc.getTables()) { + for (XWPFTableRow row : table.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + allParagraphs.addAll(cell.getParagraphs()); } } - if (context.listInfo == null) { - Matcher match = regList.matcher(startName); - if (match.find()) { - moveNodeForLoop(listAll, start, end); - // - context.listInfo = new ListInfo(); - context.listInfo.type = match.group(4); - context.listInfo.itemName = match.group(5) + "_"; - String str = match.group(1); - if (!str.isEmpty()) { - context.listInfo.min = Integer.parseInt(str); + } + + // 3. 页眉中的段落及页眉内表格中的段落 + for (XWPFHeader header : doc.getHeaderList()) { + allParagraphs.addAll(header.getParagraphs()); + for (XWPFTable table : header.getTables()) { + for (XWPFTableRow row : table.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + allParagraphs.addAll(cell.getParagraphs()); } - str = match.group(2); - if (!str.isEmpty()) { - context.listInfo.max = Integer.parseInt(str); + } + } + } + + // 4. 页脚中的段落及页脚内表格中的段落 + for (XWPFFooter footer : doc.getFooterList()) { + allParagraphs.addAll(footer.getParagraphs()); + for (XWPFTable table : footer.getTables()) { + for (XWPFTableRow row : table.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + allParagraphs.addAll(cell.getParagraphs()); } - str = match.group(3); - if (!str.isEmpty()) { - context.listInfo.offset = Integer.parseInt(str); - } - startName = match.replaceAll(""); - out("循环 listInfo=%s", U.toJSON(context.listInfo)); - context.listInfo.listData = (List) getValue(context, startName, null); - box = findBookmarkRange(start, end); - context.listInfo.listNode = (List) box[0]; - int lastIndex = (int) box[1]; - start.getParentNode().removeChild(start); - end.getParentNode().removeChild(end); - if (context.listInfo.listData == null) { - log.info("list==null " + startName); - } else { - Node lastNode = context.listInfo.listNode.get(lastIndex); - Node ref = lastNode.getNextSibling(); - if (ref == null) { - out("lastNode=%s", nodeString(lastNode)); - } - if (ref != null && ref.getNodeName().startsWith("w:bookmark")) { - ref = context.listInfo.listNode.get(context.listInfo.listNode.size() - 1) - .getNextSibling(); - } - out("开始之前listNode.size=%d; ref=%s; lastNode=%s", context.listInfo.listNode.size(), - nodeString(ref), nodeString(lastNode)); - Node parentNode = lastNode.getParentNode(); - // - Node p0 = start.getOwnerDocument().createElement("w:p"); // 制造假的循环根元素 - for (Node n : context.listInfo.listNode) { - if (n.getParentNode() == null) { - continue; - } - Node n2 = n.getParentNode().removeChild(n); - p0.appendChild(n2); - } - // - int ii = 0; - context.listInfo.index = context.listInfo.offset; - while (true) { - ii++; - context.listInfo.next(); - if (context.listInfo.isEnd()) { - break; - } - out("listInfo.item=%s", U.toJSON(context.listInfo.item)); - Node root2 = p0.cloneNode(true); - startName = getAttribute(start, "w:name"); - startId = getAttribute(start, "w:id"); - out("循环 %d 开始 tagName=%s; startName=%s,startId=%s", ii, start.getNodeName(), startName, - startId); - parseOne(root2, context); - out("循环 %d 结束 tagName=%s; startName=%s,startId=%s", ii, end.getNodeName(), startName, - startId); - if (ref != null && parentNode != ref.getParentNode()) { - out("父=%s; 引父=%s; 引=%s", nodeString(parentNode), nodeString(ref.getParentNode()), - nodeString(ref)); - } - while (root2.hasChildNodes()) { - Node n = root2.removeChild(root2.getFirstChild()); - if (n.getNodeName().startsWith("w:bookmark")) { - continue; - } - parentNode.insertBefore(n, ref); - } - } - p0 = null; - // - // 跳到list end处 - while (start != end) { - k++; - start = listAll.get(k); - } - out("成功跳到list end处"); - } - context.listInfo = null; + } + } + } + + for (XWPFParagraph paragraph : allParagraphs) { + List runs = paragraph.getRuns(); + List bookmarkStartList = paragraph.getCTP().getBookmarkStartList(); + for (CTBookmark bookmark : bookmarkStartList) { + String name = bookmark.getName(); + if (!dataMap.containsKey(name)) { continue; } - } - // - boolean nobody = startName.startsWith("X_Delete"); - ArrayList nodes = findNodes(start, end, "w:r", true, true); - if (!nobody && nodes.size() == 0) { - U.log("name=%s; not find w:r", startName); - continue; - } - ArrayList nodes2 = findNodes(start, end, "w:t", true, true); - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < nodes.size(); i++) { - Element n = (Element) nodes.get(i); - sb.append(n.getTextContent()); - if (i > 0) { - n.getParentNode().removeChild(n); - } - } - String format = sb.toString(); - Element t = null; - if (!nodes.isEmpty()) { - t = (Element) nodes.get(0).getLastChild(); - if (nodes.size() > 1 && !nodes2.isEmpty()) { - if (!"w:t".equals(t.getNodeName())) { - t = (Element) nodes2.get(0); - } - t.setTextContent(sb.toString()); - } - t.setAttribute("xml:space", "preserve"); - } - - value = null; - // - Matcher match = regEW.matcher(startName); - boolean isEW = false; - boolean isSetValue = false; - if (match.find()) { - startName = match.replaceAll(""); - isEW = true; - } - match = regW.matcher(startName); - int maxLen = 0; - if (match.find()) { - maxLen = Integer.parseInt(match.group(1)); - startName = match.replaceAll(""); - } - match = regRadio.matcher(startName); // □ F0A3 F052 163 82 - if (match.find()) { - startName = startName.substring(0, match.start()); - value = getStringValue(context, startName, format); - String value2 = match.group(1); - if ("00".equals(value2)) { - if (format.contains(value)) { - Element r = (Element) t.getParentNode(); - if (format.contains("□")) { - Element run = (Element) r.cloneNode(true); - Node t2 = run.getElementsByTagName("w:t").item(0); - Element sym = createCheckedBox(doc); - run.replaceChild(sym, t2); - Node parent = r.getParentNode(); - if (format.trim().startsWith("□")) { - parent.insertBefore(run, r); - } else { - parent.insertBefore(run, r.getNextSibling()); - } - // - value = format.replace("□", ""); - t.setTextContent(value); - out("preserve:%s", nodeString(t)); - } else { - NodeList arr = r.getElementsByTagName("w:sym"); - if (arr.getLength() > 0) { - Element t2 = (Element) arr.item(0); - t2.setAttribute("w:char", "F052"); + XWPFRun run = null; + int idx = 0; + boolean doR = false; + for (int i = 0; i < runs.size(); i++) { + Node previousSibling = runs.get(i).getCTR().getDomNode().getPreviousSibling(); + if (previousSibling != null) { + String nodeName = previousSibling.getNodeName(); + if ("w:bookmarkEnd".equals(nodeName)) { + // end前一个是start + Node bookmarkStartNode = previousSibling.getPreviousSibling(); + if (bookmarkStartNode != null) { + Node nameAttribute = bookmarkStartNode.getAttributes().getNamedItem("w:name"); + // 获取书签名称,确保同一行内多个书签情况能正确处理 + if (nameAttribute != null && name.equals(nameAttribute.getNodeValue())) { + idx = i - 1; + doR = true; + break; + } } } } - } else if (value.equals(value2)) { - Node r = t.getParentNode(); - Element sym = createCheckedBox(doc); - r.replaceChild(sym, t); } - continue; - } - match = regCheck.matcher(startName); - if (match.find()) { - startName = match.replaceAll(""); - value = getStringValue(context, startName, format); - if (!"0".equals(value) && !U.isNullOrEmpty(value)) { - Node r = t.getParentNode(); - Element sym = createCheckedBox(doc); - r.replaceChild(sym, t); - } - continue; - } - match = regEnum.matcher(startName); - if (match.find()) { - startName = startName.substring(0, match.start()); - Integer intValue = (Integer) getValue(context, startName, format); - value = ""; - if (intValue != null) { - value = getEnumItem(context, startName, intValue); - } - isSetValue = true; - } - match = regImg.matcher(startName); - if (match.find()) { - processImg(context, t, match, startName, format); - continue; - } - match = regDelete.matcher(startName); - if (match.find()) { - if (U.isNullOrEmpty(match.group(1))) { - box = findBookmarkRange(start, end); - ArrayList list = (ArrayList) box[0]; - out("删除 list.size=%s", list.size()); - for (Node n : list) { - out("删除 %s", n.getTextContent()); - n.getParentNode().removeChild(n); + if (idx < runs.size() && doR) { + if (idx < 0) {// 如果是-1,说明这一段的开头有书签 + // 在本段开头位置插入新的run + run = paragraph.insertNewRun(0); + // 并复制原有开头的run的所有内容,后续只修改文本内容,不改变样式 + run.getCTR().set(runs.get(0).getCTR().copy()); + } else { + run = runs.get(idx); + } + } else if (!runs.isEmpty()){ + // 处理一段末尾的书签(一般不存在这种情况) + run = runs.get(runs.size() - 1); + } else { + run = paragraph.createRun(); + } + if (run == null) { + continue; + } + BookmarkReplaceDataModel model = dataMap.get(name); + if (model.getExtData() instanceof TextExData textExData) { + BookmarkType type = textExData.getType(); + + // 处理文本 + if (BookmarkType.TEXT.equals(type)) { + run.setText(textExData.getValue()); } - } else if (context.listInfo != null && context.listInfo.index == context.listInfo.count) { - Node r = t.getParentNode(); - r.getParentNode().removeChild(r); } - continue; - } - // 普通字段 - if (!isSetValue) { - value = getStringValue(context, startName, format); - } - if (value != null) { - String oldValue = t.getTextContent(); - if (maxLen > 0) { - value = U.stringCut(value, maxLen); - } - if (isEW) { - int count = U.length(oldValue) - U.length(value); - if (count > 0) { - int left = count / 2; - int rigth = count - left; - value = U.paddingLeft("", " ", left) + value + U.paddingRight("", " ", rigth); + if (model.getExtData() instanceof PictureExData pictureData) { + BookmarkType type = pictureData.getType(); + // 处理图片,以嵌入式插入图片 + if (BookmarkType.PICTURE.equals(type)) { + try { + run.addPicture(new ByteArrayInputStream(pictureData.readAsByteArray()), pictureData.readPictureType(), pictureData.getPictureName(), Units.toEMU(pictureData.getWidth()), Units.toEMU(pictureData.getHeight())); + } catch (InvalidFormatException e) { + log.error(e.getMessage(), e); + throw new RuntimeException(e); + } + } + } + } + + for (XWPFRun run : runs) { + List pictures = run.getEmbeddedPictures(); + for (XWPFPicture picture : pictures) { + String description = picture.getDescription(); + if (dataMap.containsKey(description)) { + BookmarkReplaceDataModel model = dataMap.get(description); + if (model.getExtData() instanceof PictureExData pic) { + String picId = doc.addPictureData(pic.readAsByteArray(), pic.readPictureType()); + picture.getCTPicture().getBlipFill().getBlip().setEmbed(picId); + } } } - out("     %s=%s; old=%s; tagName=%s", startName, value, oldValue, - t.getNodeName()); - t.setTextContent(value); - } else { - out("     %s没有value; t=[%s]", startName, t.getTextContent()); } } - } catch (Exception e) { + + File outFile = FileUtil.newFile(tmpDir + "gen/" + FileNameUtil.getName(file)); + File parentDir = outFile.getParentFile(); + if (!parentDir.exists()) { + parentDir.mkdirs(); + } + try (FileOutputStream out = new FileOutputStream(outFile)) { + doc.write(out); + } + return outFile; + } catch (IOException | InvalidFormatException e) { throw new RuntimeException(e); } } - - private static Object[] getBookmark(Node root) { - HashMap map = new HashMap(); - HashMap map2 = new HashMap(); - ArrayList list = findNodes( - root, - null, - "w:bookmarkStart;w:bookmarkEnd", - true, false); - out("bookmarkCount=%d", list.size()); - for (int i = 0; i < list.size(); i++) { - Element node = (Element) list.get(i); - String id = node.getAttribute("w:id"); - String tagName = node.getNodeName(); - if ("w:bookmarkStart".equals(tagName)) { - boolean nearLoop = false;// 是否紧挨着循环标记 - Element n = node; - while (true) { - n = (Element) n.getNextSibling(); - if (n == null || !n.getTagName().startsWith("w:bookmark")) { - break; - } - String name = n.getAttribute("w:name"); - if (regList.matcher(name).find()) { - nearLoop = true; - break; - } - } - if (nearLoop) { - list.remove(i); - i--; - continue; - } - map2.put(id, node); - map.put(node, null); - } else { - Node start = map2.get(id); - map.put(start, node); - map.put(node, start); - } - } - return new Object[] { list, map }; - } - - private static String getStringValue( - Context context, - String key, - String format) { - Object value = getValue(context, key, format); - if (value == null) { - if (U.isNullOrEmpty(format)) { - return ""; - } - return format.replaceAll("\\.", " "); - } - return value.toString(); - } - - private static Object getValue( - Context context, - String key, - String format) { - Matcher match = regFmt.matcher(key); - if (match.find()) { - key = key.substring(0, match.start()); - out("格式化: %s; format=%s", key, format); - } else { - format = null; - } - Object value = null; - if (context.listInfo != null && "ListIndex".equals(key)) { - if (context.listInfo.index > context.listInfo.listData.size()) { - return ""; - } - value = context.listInfo.index; - } - if (value == null && context.dataMap != null) { - value = context.dataMap.get(key); - } - if (value == null && context.obj != null) { - if (context.obj instanceof Map) { - Map map = (Map) context.obj; - value = map.get(key); - } else { - Class clz = context.obj.getClass(); - Field f = null; - try { - f = clz.getField(key); - value = f.get(context.obj); - } catch (Exception e) { - try { - String key2 = U.toFirstLowerCase(key); - f = clz.getField(key2); - value = f.get(context.obj); - } catch (Exception e1) { - try { - String key3 = U.toFirstUpperCase(key); - Method method = clz.getMethod("get" + key3); - value = method.invoke(context.obj); - } catch (Exception e2) { - e.printStackTrace(); - } - } - } - } - } - if (value != null) { - if (value instanceof Date) { - if (!U.isNullOrEmpty(format)) { - String s = U.parseDateFormat(format, 0, (Date) value); - return s; - } else { - return U.formatDate((Date) value); - } - } else if (format != null) { - if (!format.contains("%")) { - format = "%" + format; - } - value = String.format(format, value); - } - return value; - } else if (format != null) { - return format.replaceAll(".", " "); - } - return null; - } - - private static ArrayList findNodes(Node start, Node end, String filter, boolean isTree, boolean findBrother) { - ArrayList> list = new ArrayList<>(); - String[] arr1 = filter.split(";|,"); - for (String item1 : arr1) { - HashMap map = new HashMap<>(); - String[] arr2 = item1.split(" "); - for (String item2 : arr2) { - String[] arr3 = item2.split("="); - if (arr3.length == 2) { - map.put(arr3[0], arr3[1]); - } else if (!arr3[0].isEmpty()) { - map.put("tagName", arr3[0]); - } - } - list.add(map); - } - boolean isAnd = filter.indexOf(",") > 0; - return findNodes(start, end, list, isTree, findBrother, isAnd).list; - } - - private static class FindResult { - ArrayList list = new ArrayList<>();; - boolean isEnd = false; - } - - private static FindResult findNodes(Node start, Node end, ArrayList> filter, - boolean isTree, boolean findBrother, boolean isAnd) { - FindResult result = new FindResult(); - if (start == null) { - return result; - } - if (start == end) { - result.isEnd = true; - return result; - } - // - Node node = start; - boolean isFirst = true; - while (true) { - if (!isFirst) { - node = node.getNextSibling(); - } - isFirst = false; - if (node == null) { - break; - } - // out("NodeName=%s", node.getNodeName()); - if (node == end) { - result.isEnd = true; - return result; - } - boolean match = isAnd; - for (HashMap map : filter) { - boolean match2 = true; - for (Map.Entry e : map.entrySet()) { - if ("tagName".equals(e.getKey())) { - String tagName = node.getNodeName(); - if (!tagName.equals(e.getValue())) { - match2 = false; - break; - } - } else { - String attr = getAttribute(node, e.getKey());// node.getAttributes().getNamedItem(e.getKey()); - if (attr == null || !attr.equals(e.getValue())) { - match2 = false; - break; - } - } - } - if (!match2 && isAnd) { - match = false; - break; - } - if (match2 && !isAnd) { - match = true; - break; - } - } - if (match) { - result.list.add(node); - } - if (isTree && node.hasChildNodes()) { - FindResult r2 = findNodes(node.getFirstChild(), end, filter, isTree, true, isAnd); - result.list.addAll(r2.list); - result.isEnd = r2.isEnd; - if (result.isEnd) { - return result; - } - } - if (!findBrother) { - break; - } - } - // - return result; - } - - private static String getAttribute(Node node, String name) { - if (node != null) { - NamedNodeMap attrs = node.getAttributes(); - if (attrs != null) { - Node attr = attrs.getNamedItem(name); - if (attr != null) { - return attr.getNodeValue(); - } - } - } - return null; - } - - private static Object[] findBookmarkRange(Node start, Node end) { - if (end == null) { - out("New找范围 none end. start=%s", getAttribute(start, "w:name")); - } - out("找范围 start=%s; end=%s", nodeString(start), nodeString(end)); - // 附近的End标记 - ArrayList listOtherEnd = new ArrayList<>(); - Node n = end; - while (true) { - n = n.getPreviousSibling(); - if (n == null || !n.getNodeName().startsWith("w:bookmarkEnd")) { - break; - } - listOtherEnd.add(n); - } - // 从End开始往上找Start - boolean isClear = false;// 结果集是否清空过 - Element eStart = (Element) start; - Element eEnd = (Element) end; - String startId = getAttribute(start, "w:id"); - String filter = "tagName=w:bookmarkStart,w:id=" + startId; - ArrayList result = new ArrayList<>(); - n = end; - Node pre; - boolean addParent = false; - while (true) { - out("加加n=%s。", n.getTextContent()); - result.add(n); - // out("查找结果添加:%s", nodeString(n)); - ArrayList list = findNodes(n, null, filter, true, false); - if (!list.isEmpty()) { - if (result.size() == 1) { - Node n2 = n; - while (true) { - pre = n2; - n2 = n2.getLastChild(); - if (n2 != null) { - list = findNodes(n2, null, filter, true, false); - } - if (n2 == null || list.isEmpty()) { - result.remove(n); - result.add(pre); - break; - } - } - } - break; - } - pre = n; - n = n.getPreviousSibling(); - while (n == null) { - out("查找结果清空"); - for (int i = 0; i < result.size() && !addParent; i++) { - if (result.get(i).getNodeName().equals("w:r")) { - addParent = true; - break; - } - } - result.clear(); - isClear = true; - pre = pre.getParentNode(); - if (addParent) { - result.add(pre); - isClear = false; - } - n = pre.getPreviousSibling(); - } - } - result.remove(end); - result.remove(start); - // Start是否在结果的第一个子元素中,如果不在,减少范围。 - if (result.size() == 1) { - n = result.get(0); - ArrayList list = findNodes(n, start.getParentNode(), "w:p", true, false); - if (!list.isEmpty()) { - result.clear(); - isClear = true; - n = n.getLastChild(); - do { - list = findNodes(n, null, filter, true, false); - result.add(n); - n = n.getPreviousSibling(); - } while (n != null && list.size() <= 0); - } - } - // - Collections.reverse(result); - int lastIndex = result.size() - 1; // 最后一个有效标记位置。因为后面会追加许多End标记 - if (isClear && !listOtherEnd.isEmpty()) { - Collections.reverse(listOtherEnd); - result.addAll(listOtherEnd); - } - for (int i = 0; i < result.size(); i++) { - out("New 查找范围结果 %d:%s", i, result.get(i).getTextContent()); - } - // out("New lastIndex= %d", lastIndex); - // - return new Object[] { result, lastIndex }; - } - - private static String nodeString(Node node) { - if (node == null) { - return "null"; - } - DOMImplementationLS lsImpl = (DOMImplementationLS) node.getOwnerDocument().getImplementation().getFeature("LS", - "3.0"); - LSSerializer lsSerializer = lsImpl.createLSSerializer(); - String xml = lsSerializer.writeToString(node); - int p = xml.indexOf("\n"); - if (p > 0) { - xml = xml.substring(p + 1); - } - return xml; - } - - private static String getEnumItem(Context context, - String type, int key) { - Map map = context.enumsMap.get(type); - String value = null; - if (map != null) { - value = map.get(key); - } else { - String s = (String) context.dataMap.get(type + "Enum"); - if (s != null) { - map = stringToEnum(s); - context.enumsMap.put(type, map); - value = map.get(key); - } - } - if (value == null) { - value = key + ""; - } - return value; - } - - private static Map stringToEnum(String s) { - String[] arr = s.split(" "); - Map map = new HashMap<>(); - for (String item : arr) { - item = item.trim(); - Matcher match = regParseEnum.matcher(item); - if (match.find()) { - int key = Integer.parseInt(match.group()); - String value = item.substring(match.end()); - map.put(key, value); - } - } - return map; - } - - private static Element createCheckedBox(Document doc) { - Element sym = doc.createElement("w:sym"); - sym.setAttribute("w:font", "Wingdings 2"); - sym.setAttribute("w:char", "F052"); - return sym; - } - - private static void moveNodeForLoop(ArrayList listAll, Node start, Node end) { - Node parent = start.getParentNode(); - Node temp; - // 循环开始标记后的w:bookmarkEnd向上移出循环 - // .....可以不处理 - // 循环开始记前的w:bookmarkStart向下移入循环 - int startIndex = listAll.indexOf(start); - Node n = start; - while (true) { - n = n.getPreviousSibling(); - if (n == null || !n.getNodeName().startsWith("w:bookmark")) { - break; - } - if (n.getNodeName().equals("w:bookmarkStart")) { - listAll.remove(n); - startIndex--; - listAll.add(startIndex + 1, n); - temp = n.getNextSibling(); - n = parent.removeChild(n); - parent.insertBefore(n, start.getNextSibling()); - n = temp; - } - } - // 循环结束标记后的w:bookmarkEnd向上移入循环 - parent = end.getParentNode(); - // - int endIndex = listAll.indexOf(end); - n = end; - while (true) { - n = n.getNextSibling(); - if (n == null || !n.getNodeName().startsWith("w:bookmark")) { - break; - } - if (n.getNodeName().equals("w:bookmarkEnd")) { - listAll.remove(n); - listAll.add(endIndex, n); - endIndex++; - temp = n.getPreviousSibling(); - n = parent.removeChild(n); - out("移动n=%s; end=%s", nodeString(n), nodeString(end)); - parent.insertBefore(n, end); - n = temp; - } - } - // 循环结束标记前的w:bookmarkStart向下移出循环 - endIndex = listAll.indexOf(end); - n = end; - while (true) { - n = n.getPreviousSibling(); - if (n == null || !n.getNodeName().startsWith("w:bookmark")) { - break; - } - if (n.getNodeName().equals("w:bookmarkStart")) { - listAll.remove(n); - endIndex--; - listAll.add(endIndex + 1, n); - temp = n.getNextSibling(); - n = parent.removeChild(n); - parent.insertBefore(n, end.getNextSibling()); - n = temp; - } - } - } - - private static void out(String format, Object... args) { - if (debug == 1) { - U.out(format, args); - } - } - - private static void processImg( - Context context, - Element t, - Matcher match, - String startName, - String format) { - startName = startName.substring(0, match.start()); - Object value = getValue(context, startName, format); - String url = null; - if (value instanceof String) { - url = (String) value; - if (url.isEmpty()) { - value = null; - } - } - if (value == null) { - U.logError("%s 没有属性值", startName); - return; - } - out("startName=%s; value=%s;", startName, value); - String relId = null; - NodeList list = t.getElementsByTagName("v:imagedata"); - Element useElement = null; - String attrName = null; - if (list.getLength() > 0) { - useElement = (Element) list.item(0); - relId = useElement.getAttribute("r:id"); - attrName = "r:id"; - } else { - list = t.getElementsByTagName("a:blip"); - if (list.getLength() > 0) { - useElement = (Element) list.item(0); - relId = useElement.getAttribute("r:embed"); - attrName = "r:embed"; - } - } - if (relId != null) { - if (context.relationUseMap.get(relId) != null) { // 重复使用的图片 - Element ref = (Element) context.relationMap.get(relId); - Element e = (Element) ref.cloneNode(true); - ref.getParentNode().insertBefore(e, ref); - context.relationMaxId++; - relId = "rId" + context.relationMaxId; - e.setAttribute("Id", relId); - e.setAttribute("Target", ref.getAttribute("Target").replaceAll("\\d+", context.relationMaxId + "")); - // - useElement.setAttribute(attrName, relId); - context.relationMap.put(relId, e); - } - context.relationUseMap.put(relId, 1); - byte[] data = new byte[0]; - if (url != null) { - if (url.startsWith("http")) { - HttpUtils.SimpleResponse resp = HttpUtils.doGetBase(url, null); - if (resp.data != null && resp.data.length > 0) { - data = resp.data; - } else { - U.logError("下载失败: %s", url); - } - } else { - try { - data = Files.readAllBytes(new File(url).toPath()); - } catch (Exception e) { - U.logError("读取失败: %s", url); - } - } - } else if (value instanceof byte[]) { - data = (byte[]) value; - } - Element e = context.relationMap.get(relId); - String target = e.getAttribute("Target"); - target = "word/" + target; - context.fileMap.put(target, data); - } else { - U.logError("%s 没找到图片引用Id", startName); - } - } } diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/HttpUtils.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/HttpUtils.java deleted file mode 100644 index 5abc6c4..0000000 --- a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/HttpUtils.java +++ /dev/null @@ -1,222 +0,0 @@ -package com.wmyun.farmwork.word.wordx; - -import cn.hutool.log.Log; -import cn.hutool.log.LogFactory; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * @Description: TODO - * @Date: 2025/3/6 18:07 - * @Created: by ZZSLL - */ - -public class HttpUtils { - - private static final Log log = LogFactory.get(HttpUtils.class); - - public static class SimpleResponse { - public byte[] data; - public Map> header; - - public String getHead(String name) { - if (header != null && header.containsKey(name)) { - return header.get(name).get(0); - } - return null; - } - } - - public static String doGet(String url, HashMap headerMap) { - SimpleResponse rsp = doGetBase(url, headerMap); - if (rsp.data != null) { - String result = new String(rsp.data); - return result; - } - return ""; - } - - /** - * 向指定URL发送GET方法的请求 - * - * @param url - * 发送请求的URL - * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 - * @return URL 所代表远程资源的响应结果 - */ - public static SimpleResponse doGetBase(String url, HashMap headerMap) { - SimpleResponse result = new SimpleResponse(); - byte[] data = null; - InputStream is = null; - try { - String urlNameString = url; - URL realUrl = new URL(urlNameString); - // 打开和URL之间的连接 - HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection(); - // 设置通用的请求属性 - connection.setRequestProperty("accept", "*/*"); - connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); - if (headerMap != null) { - for (Map.Entry e : headerMap.entrySet()) { - connection.setRequestProperty(e.getKey(), e.getValue()); - } - } - // 建立实际的连接 - connection.connect(); - // 获取所有响应头字段 - Map> map = connection.getHeaderFields(); - result.header = map; - // 遍历所有的响应头字段 - if (connection.getResponseCode() != 200) { - for (String key : map.keySet()) { - log.info(key + "--->" + map.get(key)); - } - } - if (connection.getResponseCode() == 200) { - if (map.containsKey("Content-Length")) { - int len = Integer.parseInt(map.get("Content-Length").get(0)); - data = new byte[len]; - int offset = 0; - is = connection.getInputStream(); - while (true) { - int len2 = is.read(data, offset, len - offset); - if (len2 == -1 || offset + len2 >= len) { - break; - } - offset += len2; - } - result.data = data; - } else if ("chunked".equals(map.get("Transfer-Encoding").get(0))) { - data = chunked(connection.getInputStream()); - result.data = data; - } - } - } catch (Exception e) { - U.out("访问失败:%s", url); - throw new RuntimeException(e); - } finally { - try { - if (is != null) { - is.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - return result; - } - - /** - * 向指定 URL 发送POST方法的请求 - * - * @param url - * 发送请求的 URL - * @param param - * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 - * @return 所代表远程资源的响应结果 - */ - public static String doPost(String url, HashMap header, String param) { - PrintWriter out = null; - BufferedReader in = null; - String result = ""; - try { - URL realUrl = new URL(url); - // 打开和URL之间的连接 - HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection(); - // 设置通用的请求属性 - conn.setRequestProperty("accept", "*/*"); - conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); - if (header != null && !header.isEmpty()) { - for (Map.Entry entry : header.entrySet()) { - conn.setRequestProperty(entry.getKey(), entry.getValue()); - } - } - // 发送POST请求必须设置如下两行 - conn.setDoOutput(true); - conn.setDoInput(true); - // 获取URLConnection对象对应的输出流 - out = new PrintWriter(conn.getOutputStream()); - // 发送请求参数 - out.print(param); - // flush输出流的缓冲 - out.flush(); - // - if (conn.getResponseCode() != 200) { - U.out("响应code=%d", conn.getResponseCode()); - return null; - } - // 定义BufferedReader输入流来读取URL的响应 - in = new BufferedReader(new InputStreamReader(conn.getInputStream())); - String line; - while ((line = in.readLine()) != null) { - result += line; - } - } catch (Exception e) { - throw new RuntimeException(e); - } - // 使用finally块来关闭输出流、输入流 - finally { - try { - if (out != null) { - out.close(); - } - if (in != null) { - in.close(); - } - } catch (IOException ex) { - ex.printStackTrace(); - } - } - return result; - } - - public static byte[] chunked(InputStream in) throws Exception { - ByteArrayOutputStream tmpos = new ByteArrayOutputStream(4); - ByteArrayOutputStream bytes = new ByteArrayOutputStream(); - int data = -1; - int[] aaa = new int[2]; - byte[] aa = null; - - while ((data = in.read()) >= 0) { - aaa[0] = aaa[1]; - aaa[1] = data; - if (aaa[0] == 13 && aaa[1] == 10) { - aa = tmpos.toByteArray(); - int num = 0; - try { - num = Integer.parseInt(new String(aa, 0, aa.length - 1) - .trim(), 16); - } catch (Exception e) { - log.info("aa.length:" + aa.length); - e.printStackTrace(); - } - - if (num == 0) { - - in.read(); - in.read(); - return bytes.toByteArray(); - } - aa = new byte[num]; - int sj = 0, ydlen = num, ksind = 0; - while ((sj = (in.read(aa, ksind, ydlen))) < ydlen) { - ydlen -= sj; - ksind += sj; - } - - bytes.write(aa); - in.read(); - in.read(); - tmpos.reset(); - } else { - tmpos.write(data); - } - } - return tmpos.toByteArray(); - } -} diff --git a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/U.java b/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/U.java deleted file mode 100644 index 31d05d8..0000000 --- a/wmyun-framework/wmyun-spring-boot-starter-word/src/main/java/com/wmyun/farmwork/word/wordx/U.java +++ /dev/null @@ -1,304 +0,0 @@ -package com.wmyun.farmwork.word.wordx; - -import cn.hutool.log.Log; -import cn.hutool.log.LogFactory; - -import java.io.*; -import java.lang.reflect.Method; -import java.text.SimpleDateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.LinkedHashMap; -import java.util.Map.Entry; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.zip.ZipEntry; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipOutputStream; - -public class U { - private static final SimpleDateFormat fDate = new SimpleDateFormat("yyyy-MM-dd"); - - private static final Log logger = LogFactory.get(U.class); - - public static String formatDate(Date date) { - if (date == null) { - return ""; - } - return fDate.format(date); - } - - public static boolean isNullOrEmpty(String... str) { - String s; - for (String string : str) { - s = string; - if (s == null || s.isEmpty()) { - return true; - } - } - return false; - } - - public static void out(String format, Object... args) { - log(format, args); - } - - public static String toFirstLowerCase(String s) { - if (U.isNullOrEmpty(s)) { - return ""; - } - String s2; - if (s.length() > 1) { - s2 = (s.charAt(0) + "").toLowerCase() + s.substring(1); - } else { - s2 = s.toLowerCase(); - } - return s2; - } - - public static String toFirstUpperCase(String s) { - if (U.isNullOrEmpty(s)) { - return ""; - } - String s2; - if (s.length() > 1) { - s2 = (s.charAt(0) + "").toUpperCase() + s.substring(1); - } else { - s2 = s.toUpperCase(); - } - return s2; - } - - public static String padding0(int code, int len) { - return String.format("%0" + len + "d", code); - } - - public static void close(Object... objects) { - for (Object obj : objects) { - if (obj != null) { - Class c = obj.getClass(); - try { - Method method = c.getMethod("close"); - method.invoke(obj); - } catch (Exception e) { - e.printStackTrace(); - } - } - } - } - - public static int length(String s) { - if (U.isNullOrEmpty(s)) { - return 0; - } - int count = 0; - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - if (c <= 255) { - count++; - } else { - count += 2; - } - } - return count; - } - - public static String stringCut(String s, int len) { - if (U.isNullOrEmpty(s)) { - return ""; - } - int count = 0; - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < s.length(); i++) { - char c = s.charAt(i); - int w = c <= 255 ? 1 : 2; - count += w; - if (count > len) { - return sb.toString(); - } - sb.append(c); - } - return sb.toString(); - } - - public static String paddingLeft(String s, String sign, int len) { - while (s.length() < len) { - s = sign + s; - } - return s; - } - - public static String paddingRight(String s, String sign, int len) { - while (s.length() < len) { - s = s + sign; - } - return s; - } - - // 2006-01-02 15:04:05 009 - private static Pattern regDateFormat = Pattern.compile("(20)?06|01|02|15|04|05|0*9"); - - public static String parseDateFormat(String format, int number) { - Date date = new Date(); - return parseDateFormat(format, number, date); - } - - public static String parseDateFormat(String format, int number, Date date) { - Calendar cal = Calendar.getInstance(); - if (date != null) { - cal.setTime(date); - } - StringBuilder sb = new StringBuilder(); - int code; - Matcher match = regDateFormat.matcher(format); - int p = format.length(); - if (match.find()) { - p = match.start(); - } - for (int i = 0; i < format.length(); i++) { - if (i == p) { - i = match.end() - 1; - String s = match.group(); - switch (s) { - case "2006": - code = cal.get(Calendar.YEAR); - sb.append(code); - break; - case "06": - code = cal.get(Calendar.YEAR); - sb.append(code % 100); - break; - case "01": - code = cal.get(Calendar.MONTH) + 1; - sb.append(U.padding0(code, 2)); - break; - case "02": - code = cal.get(Calendar.DATE); - sb.append(U.padding0(code, 2)); - break; - case "15": - code = cal.get(Calendar.HOUR_OF_DAY); - sb.append(U.padding0(code, 2)); - break; - case "04": - code = cal.get(Calendar.MINUTE); - sb.append(U.padding0(code, 2)); - break; - case "05": - code = cal.get(Calendar.SECOND); - sb.append(U.padding0(code, 2)); - break; - default: - if (Pattern.matches("^0*9$", s)) { - sb.append(U.padding0(number, s.length())); - } else { - U.out("奇怪format=%s, s=%s", format, s); - } - } - } else { - char c = format.charAt(i); - switch (c) { - case '\\': - if (i + 1 < format.length()) { - i++; - sb.append(format.charAt(i)); - } - break; - default: - sb.append(c); - } - } - if (i >= p) { - if (match.find()) { - p = match.start(); - } else { - p = format.length(); - } - } - } - return sb.toString(); - } - - public static LinkedHashMap unzip(File file) { - FileInputStream is; - try { - is = new FileInputStream(file); - } catch (Throwable e) { - throw new RuntimeException(e); - } - return unzip(is); - } - - public static LinkedHashMap unzip(InputStream is) { - try { - LinkedHashMap map = new LinkedHashMap<>(); - ZipInputStream zis = new ZipInputStream(is); - ZipEntry entry = null; - while ((entry = zis.getNextEntry()) != null) { - if (entry.isDirectory()) { - map.put(entry.getName(), null); - } else { - - byte[] data = new byte[(int) entry.getSize()]; - int count = 0; - while (count < entry.getSize()) { - int len = zis.read(data, count, data.length - count); - if (len == -1) { - break; - } - count += len; - } - zis.closeEntry(); - map.put(entry.getName(), data); - } - } - zis.close(); - is.close(); - return map; - } catch (Throwable e) { - throw new RuntimeException(e); - } - } - - public static void zip(File file, LinkedHashMap map) { - FileOutputStream os; - try { - os = new FileOutputStream(file); - } catch (Throwable e) { - throw new RuntimeException(e); - } - zip(os, map); - } - - public static void zip(OutputStream os, LinkedHashMap map) { - try { - ZipOutputStream zos = new ZipOutputStream(os); - for (Entry pair : map.entrySet()) { - ZipEntry entry = new ZipEntry(pair.getKey()); - zos.putNextEntry(entry); - if (pair.getValue() != null) { - zos.write(pair.getValue()); - } - } - zos.close(); - os.close(); - } catch (Throwable e) { - throw new RuntimeException(e); - } - } - - public static void log(String format, Object... args) { - logger.info(String.format(format, args)); - } - - public static void logError(String format, Object... args) { - log(format, args); - } - - public static String toJSON(Object obj) { - if (obj == null) { - return null; - } - return obj.toString(); - } -}