diff --git a/pom.xml b/pom.xml index 638ccab..b46ab4a 100644 --- a/pom.xml +++ b/pom.xml @@ -77,6 +77,11 @@ poi-ooxml 4.1.2 + + ch.stegmaier.java2tex + latex + 0.6.8 + org.apache.poi poi-scratchpad 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 c1472a7..c8b1a3f 100644 --- a/src/main/java/com/example/ts_obj/controller/TypesetController.java +++ b/src/main/java/com/example/ts_obj/controller/TypesetController.java @@ -209,20 +209,231 @@ public class TypesetController { return new ReturnValue(ReturnCodeAndMsgEnum.Success); } + +/** + * 将Word文档内容转换为LaTeX格式 + * @param filename 文件名 + * @return ReturnValue 包含LaTeX代码的返回值对象 + */ +@ApiOperation(value = "生成LaTeX排版代码") +@PostMapping("generateLatex") +public ReturnValue generateLatex(String filename) { + System.out.println("Generating LaTeX for file: " + filename); + StringBuilder latexContent = new StringBuilder(); + + try { + // 构建文件路径并打开文件输入流 + File file = new File(this.BASE_DIR + filename); + FileInputStream fis = new FileInputStream(file); + XWPFDocument xdoc = new XWPFDocument(fis); + + // 添加LaTeX文档基本结构 + latexContent.append("\\documentclass{article}\n"); + latexContent.append("\\usepackage[utf8]{inputenc}\n"); + latexContent.append("\\usepackage{graphicx}\n"); + latexContent.append("\\usepackage{amsmath}\n"); + latexContent.append("\\usepackage{amsfonts}\n"); + latexContent.append("\\usepackage{amssymb}\n"); + latexContent.append("\\usepackage{hyperref}\n"); + latexContent.append("\\begin{document}\n\n"); + + // 遍历文档段落,提取文本内容并处理格式标记 + List paragraphs = xdoc.getParagraphs(); + for (int i = 0; i < paragraphs.size(); i++) { + String paragraphText = ""; + List runs = paragraphs.get(i).getRuns(); + + // 处理每个文本运行单元,根据格式添加LaTeX命令 + for (XWPFRun run : runs) { + String formattedText = ""; + if (run.getText(0) == null) { + continue; + } + + String text = run.getText(0); + // 转义LaTeX特殊字符 + text = escapeLatexSpecialChars(text); + + // 根据格式应用LaTeX命令 + if (run.isBold() && run.isItalic()) { + formattedText = "\\textbf{\\textit{" + text + "}}"; + } else if (run.isBold()) { + formattedText = "\\textbf{" + text + "}"; + } else if (run.isItalic()) { + formattedText = "\\textit{" + text + "}"; + } else { + formattedText = text; + } + + // 处理上标和下标(如果可获取) + if (isSuperscript(run)) { + formattedText = "\\textsuperscript{" + text + "}"; + } else if (isSubscript(run)) { + formattedText = "\\textsubscript{" + text + "}"; + } + + paragraphText += formattedText; + } + + // 根据段落样式添加相应的LaTeX命令 + String style = paragraphs.get(i).getStyle(); + if (style != null) { + if (style.contains("Heading1")) { + latexContent.append("\\section{").append(paragraphText).append("}\n\n"); + } else if (style.contains("Heading2")) { + latexContent.append("\\subsection{").append(paragraphText).append("}\n\n"); + } else if (style.contains("Heading3")) { + latexContent.append("\\subsubsection{").append(paragraphText).append("}\n\n"); + } else { + latexContent.append(paragraphText).append("\n\n"); + } + } else { + latexContent.append(paragraphText).append("\n\n"); + } + } + + // 处理表格(如果需要) + List tables = xdoc.getTables(); + for (XWPFTable table : tables) { + latexContent.append(convertTableToLatex(table)).append("\n\n"); + } + + // 结束文档 + latexContent.append("\\end{document}"); + + fis.close(); + xdoc.close(); + + } catch (Exception e) { + e.printStackTrace(); + return new ReturnValue(ReturnCodeAndMsgEnum.SYSTEM_ERROR, "生成LaTeX代码失败: " + e.getMessage()); + } + + Map result = new HashMap<>(); + result.put("latex", latexContent.toString()); + return new ReturnValue(ReturnCodeAndMsgEnum.Success, result); +} + +/** + * 转义LaTeX特殊字符 + * @param text 原始文本 + * @return 转义后的文本 + */ +private String escapeLatexSpecialChars(String text) { + if (text == null) return null; + + return text.replace("\\", "\\textbackslash{}") + .replace("{", "\\{") + .replace("}", "\\}") + .replace("$", "\\$") + .replace("&", "\\&") + .replace("#", "\\#") + .replace("^", "\\textasciicircum{}") + .replace("_", "\\_") + .replace("~", "\\textasciitilde{}") + .replace("%", "\\%"); +} + + +public ReturnValue myGenerateLatex(String filename) { + + + + + + return new ReturnValue(ReturnCodeAndMsgEnum.Success); +} + + +/** + * 检查是否为上标格式(需要根据实际API调整实现) + * @param run XWPFRun对象 + * @return 是否为上标 + */ +private boolean isSuperscript(XWPFRun run) { + // 这里需要根据实际的API来判断上标格式 + // 目前Apache POI可能没有直接的方法检查上标 + // 可能需要通过其他方式判断,例如字体位置等 + return false; +} + +/** + * 检查是否为下标格式(需要根据实际API调整实现) + * @param run XWPFRun对象 + * @return 是否为下标 + */ +private boolean isSubscript(XWPFRun run) { + // 这里需要根据实际的API来判断下标格式 + // 目前Apache POI可能没有直接的方法检查下标 + // 可能需要通过其他方式判断,例如字体位置等 + return false; +} + +/** + * 将Word表格转换为LaTeX表格 + * @param table XWPFTable对象 + * @return LaTeX表格代码 + */ +private String convertTableToLatex(XWPFTable table) { + StringBuilder latexTable = new StringBuilder(); + + latexTable.append("\\begin{tabular}{|"); + + // 确定列数并添加列定义 + if (table.getRows().size() > 0) { + int columnCount = table.getRows().get(0).getTableCells().size(); + for (int i = 0; i < columnCount; i++) { + latexTable.append("l|"); // 默认左对齐 + } + } + latexTable.append("}\n\\hline\n"); + + // 添加表格内容 + for (XWPFTableRow row : table.getRows()) { + List cells = row.getTableCells(); + for (int i = 0; i < cells.size(); i++) { + XWPFTableCell cell = cells.get(i); + String cellText = cell.getText(); + cellText = escapeLatexSpecialChars(cellText); + + latexTable.append(cellText); + if (i < cells.size() - 1) { + latexTable.append(" & "); + } + } + latexTable.append(" \\\\\n\\hline\n"); + } + + latexTable.append("\\end{tabular}"); + + return latexTable.toString(); +} + + + + + /** + * 读取Word文档文件内容 + * @param filename 文件名 + * @return ReturnValue 包含文件内容的返回值对象 + */ @ApiOperation(value = "读取文件") @PostMapping("readdoc") public ReturnValue myDocReader(String filename) { System.out.println(filename); ArrayList al = new ArrayList(); try { + // 构建文件路径并打开文件输入流 File file = new File(this.BASE_DIR + filename); FileInputStream fis = new FileInputStream(file); XWPFDocument xdoc = new XWPFDocument(fis); - + + // 遍历文档段落,提取文本内容并处理格式标记 List list = xdoc.getParagraphs(); for (int i = 0; i < list.size(); i++) { String cache = ""; List runs = list.get(i).getRuns(); + // 处理每个文本运行单元,根据格式添加HTML标签 for (XWPFRun r : runs) { String cach = ""; if (r.getText(0) == null) { @@ -247,11 +458,13 @@ public class TypesetController { return new ReturnValue(ReturnCodeAndMsgEnum.Success, al); } + //网上专用文件读取接口 @ApiOperation(value = "网上专用文件读取接口") @PostMapping("webReaddoc") public ReturnValue DocReader(String fileRoute, HttpServletRequest request, HttpServletResponse response) { + ArrayList al = new ArrayList(); try { InputStream inputStream = FileDownloadUtil.getInputStream(fileRoute); @@ -330,14 +543,20 @@ public class TypesetController { if (r.getText(0) == null) { continue; } + // 核心修改:转义 < 和 > 符号 + String originalText = r.getText(0); + // 先转义 < 为 <,再转义 > 为 > + String escapedText = originalText.replace("<", "<").replace(">", ">"); + + if (r.isItalic() && r.isBold()) { - cach = "" + r.getText(0) + ""; + cach = "" + escapedText + ""; } else if (r.isItalic()) { - cach = "" + r.getText(0) + ""; + cach = "" + escapedText + ""; } else if (r.isBold()) { - cach = "" + r.getText(0) + ""; + cach = "" + escapedText + ""; } else { - cach = r.getText(0); + cach = escapedText; } cache += cach; }