From 13d5bc4b23bb031452f213ac4c1331de58555e50 Mon Sep 17 00:00:00 2001 From: wangjinlei <751475802@qq.com> Date: Sun, 22 Dec 2024 17:10:48 +0800 Subject: [PATCH] 1 --- pom.xml | 20 +- .../ts_obj/config/MyContentPolicy.java | 91 ++ .../ts_obj/config/MyParagraphRenderData.java | 57 ++ .../ts_obj/controller/TypesetController.java | 800 ++++++++++++++++-- .../example/ts_obj/entity/TypesetInfo.java | 22 + 5 files changed, 930 insertions(+), 60 deletions(-) create mode 100644 src/main/java/com/example/ts_obj/config/MyContentPolicy.java create mode 100644 src/main/java/com/example/ts_obj/config/MyParagraphRenderData.java diff --git a/pom.xml b/pom.xml index 1040ed6..362ffca 100644 --- a/pom.xml +++ b/pom.xml @@ -128,19 +128,33 @@ jai-imageio-core 1.4.0 - + + com.twelvemonkeys.imageio + imageio-tiff + 3.9.4 + org.swinglabs swingx 1.6.1 - + + org.freehep + freehep-graphicsio-emf + 2.4 + + + org.freehep + freehep-graphicsio + 2.4 + e-iceblue spire.doc.free - 3.9.0 + + 5.3.2 diff --git a/src/main/java/com/example/ts_obj/config/MyContentPolicy.java b/src/main/java/com/example/ts_obj/config/MyContentPolicy.java new file mode 100644 index 0000000..56d6b85 --- /dev/null +++ b/src/main/java/com/example/ts_obj/config/MyContentPolicy.java @@ -0,0 +1,91 @@ +package com.example.ts_obj.config; + +import com.deepoove.poi.data.*; +import com.deepoove.poi.data.style.ParagraphStyle; +import com.deepoove.poi.plugin.comment.CommentRenderData; +import com.deepoove.poi.policy.AbstractRenderPolicy; +import com.deepoove.poi.policy.ParagraphRenderPolicy; +import com.deepoove.poi.render.RenderContext; +import com.deepoove.poi.util.ParagraphUtils; +import com.deepoove.poi.util.StyleUtils; +import com.deepoove.poi.xwpf.XWPFParagraphWrapper; +import org.apache.poi.xwpf.usermodel.XWPFParagraph; +import org.apache.poi.xwpf.usermodel.XWPFRun; + +import java.util.Iterator; +import java.util.List; +import java.util.Objects; + +public class MyContentPolicy extends AbstractRenderPolicy { + public MyContentPolicy() { + } + + protected boolean validate(MyParagraphRenderData data) { + return null != data && !data.getContents().isEmpty(); + } + + protected void afterRender(RenderContext context) { + this.clearPlaceholder(context, false); + } + + public void doRender(RenderContext context) throws Exception { +// MyParagraphRenderPolicy.Helper.renderParagraph(context.getRun(), (MyParagraphRenderData)context.getData()); + MyContentPolicy.Helper.renderParagraph(context.getRun(), (MyParagraphRenderData)context.getData()); + } + + public static class Helper { + public Helper() { + } + + public static void renderParagraph(XWPFRun run, MyParagraphRenderData data) throws Exception { + renderParagraph(run, data, (List)null); + } + + public static void renderParagraph(XWPFRun run, MyParagraphRenderData data, List defaultControlStyles) throws Exception { + List contents = data.getContents(); + XWPFParagraph paragraph = (XWPFParagraph)run.getParent(); + styleParagraphWithDefaultStyle(paragraph, defaultControlStyles); + StyleUtils.styleParagraph(paragraph, data.getParagraphStyle()); + XWPFParagraphWrapper parentContext = new XWPFParagraphWrapper(paragraph); + Iterator var6 = contents.iterator(); + while(var6.hasNext()) { + RenderData content = (RenderData)var6.next(); + +// String name = content.getClass().getSimpleName(); +// System.out.println(name); + XWPFRun fragment = parentContext.insertNewRun(ParagraphUtils.getRunPos(run)); + StyleUtils.styleRun(fragment, run); + if (content instanceof TextRenderData) { + styleRunWithDefaultStyle(fragment, defaultControlStyles); + StyleUtils.styleRun(fragment, null == data.getParagraphStyle() ? null : data.getParagraphStyle().getDefaultTextStyle()); + com.deepoove.poi.policy.TextRenderPolicy.Helper.renderTextRun(fragment, content); + } else if (content instanceof PictureRenderData) { + com.deepoove.poi.policy.PictureRenderPolicy.Helper.renderPicture(fragment, (PictureRenderData)content); + } else if (content instanceof CommentRenderData) { + com.deepoove.poi.plugin.comment.CommentRenderPolicy.Helper.renderComment(fragment, (CommentRenderData)content); + } else if (content instanceof TableRenderData) { + com.deepoove.poi.policy.TableRenderPolicy.Helper.renderTable(fragment, (TableRenderData)content); + } + } + + } + + private static void styleRunWithDefaultStyle(XWPFRun fragment, List defaultControlStyles) { + if (null != defaultControlStyles) { + defaultControlStyles.stream().filter(Objects::nonNull).forEach((style) -> { + StyleUtils.styleRun(fragment, style.getDefaultTextStyle()); + }); + } + + } + + private static void styleParagraphWithDefaultStyle(XWPFParagraph paragraph, List defaultControlStyles) { + if (null != defaultControlStyles) { + defaultControlStyles.stream().filter(Objects::nonNull).forEach((style) -> { + StyleUtils.styleParagraph(paragraph, style); + }); + } + + } + } +} diff --git a/src/main/java/com/example/ts_obj/config/MyParagraphRenderData.java b/src/main/java/com/example/ts_obj/config/MyParagraphRenderData.java new file mode 100644 index 0000000..8318f8b --- /dev/null +++ b/src/main/java/com/example/ts_obj/config/MyParagraphRenderData.java @@ -0,0 +1,57 @@ +package com.example.ts_obj.config; + +import com.deepoove.poi.data.*; +import com.deepoove.poi.data.style.ParagraphStyle; + +import java.util.ArrayList; +import java.util.List; + +public class MyParagraphRenderData extends ParagraphRenderData { + + private static final long serialVersionUID = 1L; + private List contents = new ArrayList(); + private ParagraphStyle paragraphStyle; + + public MyParagraphRenderData() { + } + + public ParagraphRenderData addText(TextRenderData text) { + this.contents.add(text); + return this; + } + + public ParagraphRenderData addText(String text) { + this.contents.add(Texts.of(text).create()); + return this; + } + + public ParagraphRenderData addPicture(PictureRenderData picture) { + this.contents.add(picture); + return this; + } + + public ParagraphRenderData addTable(TableRenderData table){ + this.contents.add(table); + return this; + } + + public List getContents() { + return this.contents; + } + + public void setContents(List contents) { + this.contents = contents; + } + + public ParagraphStyle getParagraphStyle() { + return this.paragraphStyle; + } + + public void setParagraphStyle(ParagraphStyle style) { + this.paragraphStyle = style; + } + + public String toString() { + return "ParagraphRenderData [contents=" + this.contents + "]"; + } +} diff --git a/src/main/java/com/example/ts_obj/controller/TypesetController.java b/src/main/java/com/example/ts_obj/controller/TypesetController.java index 1173614..a6e85c1 100644 --- a/src/main/java/com/example/ts_obj/controller/TypesetController.java +++ b/src/main/java/com/example/ts_obj/controller/TypesetController.java @@ -2,21 +2,23 @@ package com.example.ts_obj.controller; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; +import com.deepoove.poi.data.style.*; +import com.deepoove.poi.data.style.BorderStyle; +import com.deepoove.poi.data.style.ParagraphStyle; +import com.deepoove.poi.data.style.Style; import com.example.ts_obj.Util.*; +import com.example.ts_obj.config.MyContentPolicy; +import com.example.ts_obj.config.MyParagraphRenderData; import com.example.ts_obj.entity.*; import com.spire.doc.*; import com.spire.doc.Document; -import com.spire.doc.collections.CellCollection; -import com.spire.doc.collections.RowCollection; -import com.spire.doc.collections.SectionCollection; -import com.spire.doc.collections.TableCollection; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; import com.alibaba.fastjson.JSON; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.data.*; -import com.deepoove.poi.data.style.Style; import com.deepoove.poi.policy.ParagraphRenderPolicy; import com.example.ts_obj.bean.ReturnCodeAndMsgEnum; import com.example.ts_obj.bean.ReturnValue; @@ -24,15 +26,18 @@ import com.example.ts_obj.service.TypesetService; import com.example.ts_obj.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; -import jdk.nashorn.internal.runtime.regexp.joni.Regex; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.openxml4j.util.ZipSecureFile; -import org.apache.poi.util.Units; +import org.apache.poi.util.IOUtils; import org.apache.poi.xwpf.usermodel.*; -import org.apache.xmlbeans.XmlCursor; -import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; +import org.freehep.graphicsio.emf.EMFHeader; +import org.freehep.graphicsio.emf.EMFInputStream; +import org.freehep.graphicsio.emf.EMFRenderer; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblBorders; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcBorders; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -41,11 +46,14 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; import java.text.SimpleDateFormat; import java.util.*; import java.util.List; @@ -59,10 +67,15 @@ public class TypesetController { private final static Logger logger = LoggerFactory.getLogger(UserController.class); - // private String BASE_DIR = "E:/"; -// private static String IMG_DIR = "E:/"; private String BASE_DIR = "/home/wwwroot/ts.tmrjournals.com/upload/"; + private String IMG_BASE_DIR = "/home/wwwroot/api.tmrjournals.com/public/articleImage/"; private String IMG_DIR = "/home/wwwroot/ts.tmrjournals.com/upload/pictures/"; + + +// private String BASE_DIR = "/home/wwwroot/ts.tmrjournals.com/upload/"; +// private String IMG_BASE_DIR = "D:/phpstudy_pro/WWW/tougao/public/articleImage/"; + + @Autowired private TypesetService typesetservice; @@ -272,6 +285,81 @@ public class TypesetController { return new ReturnValue(ReturnCodeAndMsgEnum.Success, al); } + @PostMapping("/readDocx") + public ReturnValue readDocx(String fileRoute,Integer article_id){ + ArrayList al = new ArrayList(); + ArrayList flagImages = new ArrayList<>(); + try { + InputStream inputStream = FileDownloadUtil.getInputStream(fileRoute); + XWPFDocument xdoc = new XWPFDocument(inputStream); + List bodyElements = xdoc.getBodyElements(); + int randomNumber = (int) (Math.random() * 9000) + 1000; + int imgNum = 0; + for (int i=0;i < bodyElements.size(); i++) { + IBodyElement element = bodyElements.get(i); + if (element instanceof XWPFParagraph) { + XWPFParagraph paragraph = (XWPFParagraph) element; + String text = paragraph.getText(); + if (text != null && !text.isEmpty()) {//处理段落或正文 + String cache = ""; + List runs = paragraph.getRuns(); + for (XWPFRun r : runs) { + String cach = ""; + if (r.getText(0) == null) { + continue; + } + if (r.isItalic() && r.isBold()) { + cach = "" + r.getText(0) + ""; + } else if (r.isItalic()) { + cach = "" + r.getText(0) + ""; + } else if (r.isBold()) { + cach = "" + r.getText(0) + ""; + } else { + cach = r.getText(0); + } + cache += cach; + } + al.add(cache); + } else {// 顺序遍历图片 + List runs = paragraph.getIRuns(); + for (IRunElement run : runs) { + if (run instanceof XWPFRun) { + XWPFRun xWPFRun = (XWPFRun) run; + for (XWPFPicture picture : xWPFRun.getEmbeddedPictures()) { + XWPFPictureData pictureData = picture.getPictureData(); + byte[] imageData = pictureData.getData(); // 获取图片的字节数据 + String imageFileName = pictureData.suggestFileExtension(); // 获取图片的扩展名 + if(imageFileName.equals("jpeg")){ + imageFileName = "jpg"; + } else if (imageFileName.equals("tiff")) { + imageFileName = "tif"; + } + File f = new File("/home/wwwroot/api.tmrjournals.com/public/articleImage/"+article_id+"/"+"image-"+randomNumber + imgNum+"."+imageFileName ); +// File f = new File("D:\\phpstudy_pro\\WWW\\tougao\\public/articleImage/"+article_id+"/"+"image-"+randomNumber + imgNum+"."+imageFileName ); + // 将图片保存为文件 + try (FileOutputStream fos = new FileOutputStream(f) ){ + IOUtils.copy(new ByteArrayInputStream(imageData), fos); + } + flagImages.add("image-"+randomNumber + imgNum+"."+imageFileName); + String img_str = ""; + //存储图片数据到总数组 + al.add(img_str); + imgNum++; + } + } + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + Map> stringListMap = new HashMap<>(); + stringListMap.put("mains",al); + stringListMap.put("images",flagImages); + return new ReturnValue(ReturnCodeAndMsgEnum.Success,stringListMap); + } + @PostMapping("/readPic") public ReturnValue readPicNum(String fileRoute, HttpServletRequest request, HttpServletResponse response) { Integer num = 0; @@ -294,6 +382,134 @@ public class TypesetController { } + + @PostMapping("/markImages") + public ReturnValue markImages(String file,String article_id){ + if(!isImageExist(file)){ + return new ReturnValue(ReturnCodeAndMsgEnum.SYSTEM_ERROR); + } + Map> map = new HashMap<>(); + try { + InputStream inputStream = FileDownloadUtil.getInputStream(file); + XWPFDocument xdoc = new XWPFDocument(inputStream); + List pictures = xdoc.getAllPictures(); + List list = new ArrayList<>(); + int randomNumber = (int) (Math.random() * 9000) + 1000; // 生成一个1000到9999之间的随机数 + int i = 0; + for (XWPFPictureData picture : pictures) { + + byte[] imageData = picture.getData(); // 获取图片的字节数据 + String imageFileName = picture.suggestFileExtension(); // 获取图片的扩展名 + + if(imageFileName.equals("jpeg")){ + imageFileName = "jpg"; + } else if (imageFileName.equals("tiff")) { + imageFileName = "tif"; + } + + + File f = new File("/home/wwwroot/api.tmrjournals.com/public/articleImage/"+article_id+"/"+"image-"+randomNumber + i+"."+imageFileName ); + // 将图片保存为文件 + try (FileOutputStream fos = new FileOutputStream(f) ){ + IOUtils.copy(new ByteArrayInputStream(imageData), fos); + } + list.add("image-"+ randomNumber+ i+"."+imageFileName); + i++; + } + map.put("list",list); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + return new ReturnValue(ReturnCodeAndMsgEnum.Success,map); + } + + + public boolean isImageExist(String imageUrl) { + try { + // 创建 URL 对象 + URL url = new URL(imageUrl); + + // 打开连接 + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); // 使用 GET 请求 + connection.setConnectTimeout(5000); // 设置连接超时时间 + connection.setReadTimeout(5000); // 设置读取超时时间 + + // 获取响应码 + int responseCode = connection.getResponseCode(); + + // 判断响应码是否为 200(OK) + return responseCode == HttpURLConnection.HTTP_OK; + } catch (IOException e) { + // 异常处理,图片不可访问 + return false; + } + } + + @PostMapping("/markTables") + public ReturnValue markTables(@RequestBody Map map){ + String file = map.get("table"); + String filePath = "D://"+file; + List tablesData = new ArrayList<>(); + try (FileInputStream fis = new FileInputStream(filePath); + XWPFDocument document = new XWPFDocument(fis)) { + // 获取文档中的所有表格 + List tables = document.getTables(); + for (int t = 0; t < tables.size(); t++) { + XWPFTable table = tables.get(t); + List> tableData = new ArrayList<>(); + + // 遍历表格的行 + for (XWPFTableRow row : table.getRows()) { + List rowData = new ArrayList<>(); + // 遍历行中的单元格 + for (XWPFTableCell cell : row.getTableCells()) { + rowData.add(cell.getText()); + } + tableData.add(rowData); + } + String tableJson = JSON.toJSONString(tableData); + tablesData.add(tableJson); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return new ReturnValue(ReturnCodeAndMsgEnum.Success,tablesData); + } + + + @PostMapping("/checkWordImg") + public ReturnValue checkWordImg(@RequestBody Map map){ + String fileRoute = map.get("url"); + try { + InputStream inputStream = FileDownloadUtil.getInputStream(fileRoute); + XWPFDocument xdoc = new XWPFDocument(inputStream); + List pictures = xdoc.getAllPictures(); + for (XWPFPictureData picture : pictures) { + int i = 0; + byte[] imageData = picture.getData(); // 获取图片的字节数据 + String imageFileName = picture.suggestFileExtension(); // 获取图片的扩展名 +// System.out.println(picture.getPackagePart().getPartName().getName()); + File f = new File("D://123/"+"image-" + i+"."+imageFileName ); + // 将图片保存为文件 + try (FileOutputStream fos = new FileOutputStream(f) ){ + IOUtils.copy(new ByteArrayInputStream(imageData), fos); +// System.out.println("Image saved as: " + "image-" + picture.getPackagePart().getPartName().getName()); + } + } + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (IOException e) { + throw new RuntimeException(e); + } + + return new ReturnValue(ReturnCodeAndMsgEnum.Success); + } + + @PostMapping("/mytest") public ReturnValue mytest(Long typesetId) { try { @@ -380,7 +596,7 @@ public class TypesetController { } map.put("ye", ti.getStage().substring(0, 4)); // map.put("abstract",ti.getAbstractText().replace("","").replace("","")); - map.put("abstract", this.crowStr(ti.getAbstractText())); + map.put("abstract", crowStr(ti.getAbstractText())); map.put("keywords", ti.getKeywords().replace("", "").replace("", "")); // map.put("img", this.BASE_DIR + "p1.png"); @@ -446,39 +662,303 @@ public class TypesetController { return new ReturnValue(ReturnCodeAndMsgEnum.Success, frag); } - @ApiOperation(value = "ceshi") - @PostMapping("/webtest") - public ReturnValue webtest(@RequestBody TypesetInfo typesetInfo) { + + @PostMapping("/myTest") + public ReturnValue myTest(@RequestBody TypesetInfo typesetInfo) throws IOException { + HashMap frag = new HashMap<>(); + HashMap map = new HashMap<>(); + String main = typesetInfo.getMainText(); + List l = JSON.parseArray(main, String.class); + ArrayList mainArr = new ArrayList(); + for (String s : l) { + Map cache = new HashMap(); +// ParagraphRenderData capd = this.crowStrNew(s); +// cache.put("content", capd); + + mainArr.add(cache); + } + map.put("main", mainArr); + +// Configure config = Configure.builder().bind("content", new ParagraphRenderPolicy()).build(); + Configure config = Configure.builder().bind("content", new MyContentPolicy()).build(); + + String myTemplate = "D:/tt1.docx"; + XWPFTemplate template = XWPFTemplate.compile( myTemplate, config).render(map); + try { + Date date = new Date(); + String dirpath = "D:/" + new SimpleDateFormat("yyyyMMdd").format(date); + //如果不存在,创建文件夹 + File f = new File(dirpath); + if (!f.exists()) { + f.mkdirs(); + } + String goFileName = System.currentTimeMillis() + ".docx"; + template.writeAndClose(new FileOutputStream(dirpath + "/" + goFileName)); + frag.put("file", goFileName); + } catch (IOException e) { + e.printStackTrace(); + } + + return new ReturnValue(ReturnCodeAndMsgEnum.Success,frag); + } + + @PostMapping("/createDocx") + public ReturnValue createDocx(@RequestBody TypesetInfo typesetInfo) throws IOException { + Map frag = new HashMap(); + ZipSecureFile.setMinInflateRatio(-1.0d); + HashMap map = new HashMap<>(); + + //处理基础信息部分 + map.put("type", typesetInfo.getInfo_type().toUpperCase()); + map.put("journaltitle", typesetInfo.getJournal()); + map.put("stage", typesetInfo.getStage()); + Style doi_s = new Style(); + doi_s.setColor("FF0000"); + ParagraphRenderData doi_p = new ParagraphRenderData(); + doi_p.addText(new TextRenderData("input doi", doi_s)); + map.put("doi", doi_p); + map.put("topic", typesetInfo.getTopic()); + ParagraphRenderData peer_p = new ParagraphRenderData(); + Style Italic_sty = new Style(); + Italic_sty.setItalic(true); + peer_p.addText(new TextRenderData(typesetInfo.getJournal(), Italic_sty)); + peer_p.addText(" thanks all "); + peer_p.addText(new TextRenderData("XXXXXXXXXXXXXXXX", doi_s)); + peer_p.addText("anonymous reviewers for their contribution to the peer review of this paper."); + map.put("peer", peer_p); + map.put("articletitle", typesetInfo.getInfo_title().replace("", "").replace("", "").replace("", "").replace("", "")); + String author = typesetInfo.getAuthor(); + String[] s_author = author.split(""); + ParagraphRenderData author_p = new ParagraphRenderData(); + for (int i = 0; i < s_author.length; i++) { + if (s_author[i].equals("")) { + continue; + } + String[] cache_author = s_author[i].split(""); + String au = cache_author[0]; + author_p.addText(au); + if (cache_author.length > 1) { + String bu = cache_author[1]; + Style ca_sty = new Style(); + ca_sty.setVertAlign("superscript"); + author_p.addText(new TextRenderData(bu.replace("", "").replace("", ""), ca_sty)); + } + if (i < s_author.length - 1) { + author_p.addText(", "); + } + } + map.put("author", author_p); + map.put("authoraddress", typesetInfo.getAuthorAddress().replace("", "").replace("", "").replace("", "").replace("", "")); + map.put("corresponding", typesetInfo.getAuthorCorresponding().replace("", "").replace("", "").replace("", "").replace("", "")); + map.put("coremail", typesetInfo.getAuthorCorrespondingEmail().replace("", "").replace("", "").replace("", "").replace("", "")); + map.put("website", typesetInfo.getWebsite()); + if (typesetInfo.getAuthorContribution().equals("")) { + map.put("contributions", false); + } else { + HashMap map1 = new HashMap<>(); + map1.put("author_contribution", typesetInfo.getAuthorContribution()); + map.put("contributions", map1); + } + if (typesetInfo.getAcknowledgment().equals("")) { + map.put("acknowledgment", false); + } else { + HashMap map2 = new HashMap(); + map2.put("acknowledgment_content", typesetInfo.getAcknowledgment()); + map.put("acknowledgment", map2); + } + map.put("abbreviation", typesetInfo.getAbbreviation()); + map.put("citation", (typesetInfo.getLittle_author() + ". " + typesetInfo.getInfo_title() + ". " + typesetInfo.getJabbr() + ". " + typesetInfo.getStage() + ". doi: 10.53388/" + typesetInfo.getDoi() + ".").replace("", "").replace("", "").replace("", "").replace("", "")); + map.put("exeditor", typesetInfo.getUserAccount()); + map.put("received_date", typesetInfo.getReceived_date()); + map.put("accept_date", typesetInfo.getAccepted_date()); + ParagraphRenderData od_p = new ParagraphRenderData(); + od_p.addText(new TextRenderData("input online_date", doi_s)); + map.put("online_date", od_p); + map.put("ye", typesetInfo.getStage().substring(0, 4)); + ParagraphRenderData abstract_p = new ParagraphRenderData(); + abstract_p.addText(new TextRenderData("input abstract", doi_s)); + map.put("abstract", abstract_p); + map.put("keywords", typesetInfo.getKeywords().replace("", "").replace("", "")); + String main = typesetInfo.getMainText(); + List l = JSON.parseArray(main, String.class); + ArrayList mainArr = new ArrayList(); + ArrayList otherArr = new ArrayList(); + for (String s : l) { + Map cache = new HashMap(); + Map otherData = new HashMap(); + MyParagraphRenderData capd = crowStrNew(s,typesetInfo.getTables(),typesetInfo.getImages()); + if(checkImg(s)||s.contains(" refsl = new ArrayList(); for (Object tif : ja) { JSONObject a = (JSONObject) tif; - System.out.println(a.getString("author")); -// String tttt = String.valueOf(tif).replace("", "").replace("", "").replace("", "").replace("", "").trim().toUpperCase(); -// ParagraphRenderData chc_pd = new ParagraphRenderData(); -// -// String tgh_title = String.valueOf(tif).replace("", "").replace("", "").replace("", "").replace("", ""); -// -// String[] split = tgh_title.split("\n"); -// -// Style chch = new Style(); -// chch.setFontFamily("Charis SIL"); -// chch.setFontSize(7.5); -// chc_pd.addText(new TextRenderData(split[0], chch)); -// -// if(split.length>1){ -// chc_pd.addText("\n"); -// Style lstitle = new Style(); -// lstitle.setFontFamily("Charis SIL"); -// lstitle.setFontSize(7.5); -// lstitle.setColor("0082AA"); -// chc_pd.addText(new TextRenderData(split[1],lstitle)); -// } -// refsl.add(chc_pd); + if (a.getString("refer_type").equals("journal")) { + ParagraphRenderData chc_pdd = new ParagraphRenderData(); + Style chch = new Style(); + chch.setFontFamily("Charis SIL"); + chch.setFontSize(7.5); + Style cheche = new Style(); + cheche.setItalic(true); + cheche.setFontFamily("Charis SIL"); + cheche.setFontSize(7.5); + if (a.getString("is_ja").equals("0")) { + cheche.setColor("f98f36"); + } + Style lstitle = new Style(); + lstitle.setFontFamily("Charis SIL"); + lstitle.setFontSize(7.5); + lstitle.setColor("0082AA"); + chc_pdd.addText(new TextRenderData(a.getString("author") + " ", chch)); + chc_pdd.addText(new TextRenderData(a.getString("title") + ". ", chch)); + chc_pdd.addText(new TextRenderData(a.getString("joura") + ". ", cheche)); + chc_pdd.addText(new TextRenderData(a.getString("dateno") + ". Available at:", chch)); + chc_pdd.addText("\n"); + chc_pdd.addText(new TextRenderData(a.getString("doilink"), lstitle)); + refsl.add(chc_pdd); + }else if(a.getString("refer_type").equals("book")){ + ParagraphRenderData chc_pd = new ParagraphRenderData(); + Style chch = new Style(); + chch.setFontFamily("Charis SIL"); + chch.setFontSize(7.5); + chch.setColor("f98f36"); + Style cheche = new Style(); + cheche.setItalic(true); + cheche.setFontFamily("Charis SIL"); + cheche.setFontSize(7.5); + chc_pd.addText(new TextRenderData(a.getString("author") + " ", chch)); + chc_pd.addText(new TextRenderData(a.getString("title") + ". ", chch)); + chc_pd.addText(new TextRenderData(a.getString("dateno") + ". ", chch)); + chc_pd.addText(new TextRenderData(a.getString("isbn"), chch)); + refsl.add(chc_pd); + }else { + ParagraphRenderData chc_pd = new ParagraphRenderData(); + String tgh_title = a.getString("refer_frag").replace("", "").replace("", "").replace("", "").replace("", ""); + String[] split = tgh_title.split("\n"); + Style chch = new Style(); + chch.setFontFamily("Charis SIL"); + chch.setFontSize(7.5); + chch.setColor("f98f36"); + chc_pd.addText(new TextRenderData(split[0], chch)); + if (split.length > 1) { + chc_pd.addText("\n"); + Style lstitle = new Style(); + lstitle.setFontFamily("Charis SIL"); + lstitle.setFontSize(7.5); + lstitle.setColor("0082AA"); + chc_pd.addText(new TextRenderData(split[1], lstitle)); + } + refsl.add(chc_pd); + } } - return new ReturnValue(ReturnCodeAndMsgEnum.Success); + map.put("refs", new NumberingRenderData(NumberingFormat.DECIMAL, refsl)); + //最终生成 + String myTemplate = ""; + //确定使用的模板 + if (typesetInfo.getInfo_type().toUpperCase().equals("COMMENT") || typesetInfo.getInfo_type().toUpperCase().equals("NEWS")) { + myTemplate = "template2.docx"; + } else { +// myTemplate = "template1.docx"; + myTemplate = "template1_1.docx"; + } + + Configure config = Configure.builder().bind("content", new MyContentPolicy()).bind("data",new MyContentPolicy()) + .bind("abstract", new ParagraphRenderPolicy()).bind("author", new ParagraphRenderPolicy()) + .bind("doi", new ParagraphRenderPolicy()).bind("online_date", new ParagraphRenderPolicy()) + .bind("peer", new ParagraphRenderPolicy()) + .build(); + XWPFTemplate template = XWPFTemplate.compile(this.BASE_DIR + myTemplate, config).render(map); +// XWPFTemplate template = XWPFTemplate.compile("D:/tt1.docx", config).render(map); + XWPFDocument document = template.getXWPFDocument(); + List tables = document.getTables(); + for (int i = 1; i < tables.size(); i++) { // 从索引 1 开始,跳过第一个表格 + XWPFTable table = tables.get(i); + setThreeLineTableStyle(table); // 应用三线表样式 + } + try { + Date date = new Date(); + String dirpath = this.BASE_DIR + new SimpleDateFormat("yyyyMMdd").format(date); +// String dirpath = "D:/" + new SimpleDateFormat("yyyyMMdd").format(date); + + //如果不存在,创建文件夹 + File f = new File(dirpath); + if (!f.exists()) { + f.mkdirs(); + } + String goFileName = System.currentTimeMillis() + ".docx"; + template.writeAndClose(new FileOutputStream(dirpath + "/" + goFileName)); + frag.put("file", goFileName); + } catch (IOException e) { + e.printStackTrace(); + } + return new ReturnValue(ReturnCodeAndMsgEnum.Success, frag); } + + @PostMapping("/crossImage") + public ReturnValue crossImage(String url) throws FileNotFoundException { + String fileUrl = IMG_BASE_DIR+url; + File file = new File(fileUrl); + String pngUrl = IMG_BASE_DIR+url.substring(0,url.indexOf("."))+".png"; + File pngFile = new File(pngUrl); + if(file.getName().toLowerCase().endsWith(".tif") || file.getName().toLowerCase().endsWith(".tiff")){ + try (ImageInputStream input = ImageIO.createImageInputStream(file)) { + Iterator readers = ImageIO.getImageReaders(input); + if (!readers.hasNext()) { + throw new IOException("No TIFF reader found"); + } + ImageReader reader = readers.next(); + reader.setInput(input); + BufferedImage image = reader.read(0); + ImageIO.write(image, "png", pngFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + }else if(file.getName().toLowerCase().endsWith(".emf")){ + try ( + + FileInputStream emfInputStream = new FileInputStream(file)) { + // 创建 EMFInputStream + EMFInputStream emfStream = new EMFInputStream(emfInputStream, EMFInputStream.DEFAULT_VERSION); + + // 读取 EMF 文件头信息 + EMFHeader header = emfStream.readHeader(); + + // 使用 EMFHeader 的边界信息获取宽度和高度 + int width = (int) header.getBounds().getWidth(); + int height = (int) header.getBounds().getHeight(); + + // 创建 EMFRenderer + EMFRenderer renderer = new EMFRenderer(emfStream); + + // 创建 BufferedImage + BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + + // 渲染 EMF 到 BufferedImage + renderer.paint(image.createGraphics()); + + // 保存为 PNG + ImageIO.write(image, "png", pngFile); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + HashMap flag = new HashMap<>(); + flag.put("file",url.substring(0,url.indexOf("."))+".png"); + return new ReturnValue(ReturnCodeAndMsgEnum.Success,flag); + } + + + @ApiOperation(value = "网上专用获取生成的docx") @PostMapping("/webGetDocx") public ReturnValue webGetDocx(@RequestBody TypesetInfo typesetInfo) throws IOException { @@ -494,7 +974,6 @@ public class TypesetController { ParagraphRenderData doi_p = new ParagraphRenderData(); doi_p.addText(new TextRenderData("input doi", doi_s)); map.put("doi", doi_p); -// map.put("doi", typesetInfo.getDoi()); map.put("topic", typesetInfo.getTopic()); //peer ParagraphRenderData peer_p = new ParagraphRenderData(); @@ -561,7 +1040,6 @@ public class TypesetController { ParagraphRenderData abstract_p = new ParagraphRenderData(); abstract_p.addText(new TextRenderData("input abstract", doi_s)); map.put("abstract", abstract_p); -// map.put("abstract", this.crowStr(typesetInfo.getAbstractText())); map.put("keywords", typesetInfo.getKeywords().replace("", "").replace("", "")); Configure config = Configure.builder().bind("content", new ParagraphRenderPolicy()) @@ -569,13 +1047,6 @@ public class TypesetController { .bind("doi", new ParagraphRenderPolicy()).bind("online_date", new ParagraphRenderPolicy()) .bind("peer", new ParagraphRenderPolicy()) .build(); -// Configure config = Configure.builder().bind("content", new ParagraphRenderPolicy()) -// .bind("abstract", new ParagraphRenderPolicy()).bind("author", new ParagraphRenderPolicy()) -// .bind("table1", new CustomTableRenderPolicy()) -// .bind("table2", new CustomTableRenderPolicy()).bind("table3", new CustomTableRenderPolicy()) -// .bind("table4", new CustomTableRenderPolicy()).bind("table5", new CustomTableRenderPolicy()) -// .bind("table6", new CustomTableRenderPolicy()).bind("table7", new CustomTableRenderPolicy()) -// .bind("table8", new CustomTableRenderPolicy()).bind("table9", new CustomTableRenderPolicy()).build(); String main = typesetInfo.getMainText(); List l = JSON.parseArray(main, String.class); ArrayList mainArr = new ArrayList(); @@ -593,10 +1064,6 @@ public class TypesetController { List refsl = new ArrayList(); for (Object tif : ja) { JSONObject a = (JSONObject) tif; -// System.out.println(a.getString("author")); -// String tttt = String.valueOf(tif).replace("", "").replace("", "").replace("", "").replace("", "").trim().toUpperCase(); - -// if (!a.getString("title").isEmpty()) { if (a.getString("refer_type").equals("journal")) { ParagraphRenderData chc_pdd = new ParagraphRenderData(); Style chch = new Style(); @@ -617,7 +1084,7 @@ public class TypesetController { lstitle.setColor("0082AA"); chc_pdd.addText(new TextRenderData(a.getString("author") + " ", chch)); chc_pdd.addText(new TextRenderData(a.getString("title") + ". ", chch)); - chc_pdd.addText(new TextRenderData(a.getString("joura") + " ", cheche)); + chc_pdd.addText(new TextRenderData(a.getString("joura") + ". ", cheche)); chc_pdd.addText(new TextRenderData(a.getString("dateno") + ". Available at:", chch)); chc_pdd.addText("\n"); chc_pdd.addText(new TextRenderData(a.getString("doilink"), lstitle)); @@ -686,8 +1153,6 @@ public class TypesetController { } String goFileName = System.currentTimeMillis() + ".docx"; template.writeAndClose(new FileOutputStream(dirpath + "/" + goFileName)); - String filePath = addPic1(typesetInfo.getFilename(), dirpath + "/" + goFileName); -// frag.put("file", filePath); frag.put("file", goFileName); } catch (IOException e) { e.printStackTrace(); @@ -695,7 +1160,6 @@ public class TypesetController { return new ReturnValue(ReturnCodeAndMsgEnum.Success, frag); } - private ParagraphRenderData crowStr(String s) { ParagraphRenderData p = new ParagraphRenderData(); if (s.indexOf("") >= 0) { @@ -791,6 +1255,228 @@ public class TypesetController { return p; } + + private MyParagraphRenderData crowStrNew(String s,Map> map,Map> images) throws IOException { + MyParagraphRenderData p = new MyParagraphRenderData(); + + if(isImgTag(s)){ + String regex = "imageId='(\\d+)'"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(s); + int image_id = 0; + if (matcher.find()) { + image_id= Integer.valueOf(matcher.group(1)); + } + Map stringStringMap = images.get(image_id); + String imagePath = stringStringMap.get("image"); + BufferedImage image = ImageIO.read(new File(IMG_BASE_DIR+imagePath)); + PictureRenderData pictureRenderData = new PictureRenderData(image.getWidth(), image.getHeight(),IMG_BASE_DIR+imagePath); + PictureStyle pictureStyle = new PictureStyle(); + pictureStyle.setAlign(PictureStyle.PictureAlign.CENTER); + pictureRenderData.setPictureStyle(pictureStyle); + p.addPicture(pictureRenderData); + ParagraphStyle paragraphStyle = new ParagraphStyle(); + paragraphStyle.setAlign(ParagraphAlignment.CENTER); + paragraphStyle.setSpacing(Double.valueOf(10)); + p.setParagraphStyle(paragraphStyle); + String note = stringStringMap.get("note"); + textRenderCreate(note,p); + return p; + } + + + if(s.contains(" stringStringMap = map.get(tableId); + String title_table = stringStringMap.get("title"); + String note_table = stringStringMap.get("note"); + textRenderCreate(title_table,p); + ArrayList>> tableData = JSON.parseObject(stringStringMap.get("table_data"), new TypeReference>>>() {}); + TableRenderData tableRenderData = new TableRenderData(); + for (ArrayList> row:tableData){ + RowRenderData rowRenderData = new RowRenderData(); + for (Map rowBean:row){ + CellRenderData cellRenderData = new CellRenderData(); + ParagraphRenderData paragraphRenderData = new ParagraphRenderData(); + ParagraphRenderData text = crowStrNew(rowBean.get("text"), map,images); + List plist = new ArrayList<>(); + plist.add(text); + plist.add(paragraphRenderData); + cellRenderData.setParagraphs(plist); + rowRenderData.addCell(cellRenderData); + } + tableRenderData.addRow(rowRenderData); + } + p.addTable(tableRenderData); + ParagraphStyle paragraphStyle = new ParagraphStyle(); + paragraphStyle.setAlign(ParagraphAlignment.CENTER); + paragraphStyle.setSpacing(Double.valueOf(12)); + textRenderCreate(note_table,p); + return p; + } + if(s.isEmpty()){ + p.addText(s); + } + textRenderCreate(s,p); + return p; + } + + + private void textRenderCreate(String s,MyParagraphRenderData p){ + while (!s.isEmpty()){ + String s1 = determineNextTag(s); + if(s1.equals("no")){ + p.addText(s); + s = ""; + }else{ + int beginTag = s.indexOf("<"+s1+">"); + int endTag = s.indexOf(""); + if(beginTag>0){ + p.addText(s.substring(0,beginTag)); + } + String now = s.substring(beginTag,endTag + s1.length() + 3); + Style style = new Style(); + List textRenderData = new ArrayList<>(); + getTextRenderData(now,s1,style,textRenderData); + s = s.substring(endTag+s1.length()+3); + for (TextRenderData t:textRenderData){ + p.addText(t); + } + } + } + } + + public boolean isImgTag(String str) { + // 定义正则表达式,用于匹配 标签 + String imgTagPattern = "<\\s*img\\s+[^>]*\\s*\\/?>"; + + // 编译正则表达式 + Pattern pattern = Pattern.compile(imgTagPattern, Pattern.CASE_INSENSITIVE); + + // 创建 Matcher 对象 + Matcher matcher = pattern.matcher(str); + + // 如果匹配成功,返回 true,表示是 标签 + return matcher.matches(); + } + + private void getTextRenderData(String now,String tag,Style style,List textRenderData){ + addStyle(style,tag); + String content = now.substring(tag.length() + 2, now.length()-(tag.length()+3)); + while (!content.equals("")){ + String s = determineNextTag(content); + if(s.equals("no")){ + TextRenderData textRenderData1 = new TextRenderData(content, style); + textRenderData.add(textRenderData1); + content = ""; + }else{ + int beginTag = content.indexOf("<"+s+">"); + int endTag = content.indexOf(""); + if(beginTag>0){ + TextRenderData textRenderData1 = new TextRenderData(content.substring(0, beginTag), style); + textRenderData.add(textRenderData1); + } + String now1 = content.substring(beginTag,endTag + s.length() + 3); + getTextRenderData(now1, s, deepCopy(style), textRenderData); + content = content.substring(endTag+s.length()+3); + } + } + } + + private void setThreeLineTableStyle(XWPFTable table) { + // 遍历表格所有行 + for (int i = 0; i < table.getRows().size(); i++) { + XWPFTableRow row = table.getRow(i); + + for (XWPFTableCell cell : row.getTableCells()) { + // 获取单元格的边框属性 + CTTcPr cellProperties = cell.getCTTc().addNewTcPr(); + CTTcBorders cellBorders = cellProperties.addNewTcBorders(); + + // 设置边框样式 + if (i == 0) { // 第一行(表头行) + cellBorders.addNewTop().setVal(STBorder.SINGLE); // 顶部边框 + cellBorders.addNewBottom().setVal(STBorder.SINGLE); // 表头底部边框 + } else if (i == table.getRows().size() - 1) { // 最后一行 + cellBorders.addNewTop().setVal(STBorder.NONE); // 顶部边框 + cellBorders.addNewBottom().setVal(STBorder.SINGLE); // 底部边框 + } else { // 中间行 + cellBorders.addNewTop().setVal(STBorder.NONE); // 无顶部边框 + cellBorders.addNewBottom().setVal(STBorder.NONE); // 无底部边框 + } + + // 左右边框清除(适用于所有行) + cellBorders.addNewLeft().setVal(STBorder.NONE); // 无左边框 + cellBorders.addNewRight().setVal(STBorder.NONE); // 无右边框 + } + } + } + + private Boolean checkImg(String s) throws IOException { + if(!isImgTag(s)){ + return false; + } + String regex = "articleImage/([^'\"\\s]+\\.[a-zA-Z]{3,4})"; + Pattern pattern = Pattern.compile(regex); + Matcher matcher = pattern.matcher(s); + // 确保在访问捕获组之前找到匹配项 + String imagePath = ""; + if (matcher.find()) { + imagePath = matcher.group(1); + } + BufferedImage image = ImageIO.read(new File(IMG_BASE_DIR+imagePath)); + if(image.getWidth()>320){ + return true; + }else { + return false; + } + } + + private Style deepCopy(Style original) { + Style copy = new Style(); + copy.setBold(original.isBold()); + copy.setItalic(original.isItalic()); + copy.setColor(original.getColor()); + copy.setVertAlign(original.getVertAlign()); + + return copy; + } + private String determineNextTag(String s) { + Pattern pattern = Pattern.compile("<(sup|sub|blue|b|i)>"); // 只匹配开放标签 + Matcher matcher = pattern.matcher(s); + if (matcher.find()) { + return matcher.group(1); // 返回第一个匹配的标签 + } + return "no"; + } + + private void addStyle(Style s , String tag){ + switch (tag){ + case "sup": + s.setVertAlign("superscript"); + break; + case "blue": + s.setColor("0000FF"); + break; + case "sub": + s.setVertAlign("subscript"); + break; + case "b": + s.setBold(true); + break; + case "i": + s.setItalic(true); + break; + } + } + // @ApiOperation(value = "生成图片") // @PostMapping("/addPic") // public ReturnValue addPic(String OldFileName,String newFileName){ diff --git a/src/main/java/com/example/ts_obj/entity/TypesetInfo.java b/src/main/java/com/example/ts_obj/entity/TypesetInfo.java index 944fe20..6849533 100644 --- a/src/main/java/com/example/ts_obj/entity/TypesetInfo.java +++ b/src/main/java/com/example/ts_obj/entity/TypesetInfo.java @@ -1,6 +1,7 @@ package com.example.ts_obj.entity; import java.io.Serializable; +import java.util.Map; /** * u_typeset_info @@ -65,6 +66,11 @@ public class TypesetInfo implements Serializable { private String userAccount; + + private Map> images; + + private Map> tables; + private static final long serialVersionUID = 1L; public Long getTypesetInfoId() { @@ -195,6 +201,22 @@ public class TypesetInfo implements Serializable { return stage; } + public Map> getImages() { + return images; + } + + public void setImages(Map> images) { + this.images = images; + } + + public Map> getTables() { + return tables; + } + + public void setTables(Map> tables) { + this.tables = tables; + } + public void setStage(String stage) { this.stage = stage; }