=依赖,需要在官网下载然后安装到maven中=
xml
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc.free</artifactId>
<version>5.3.2</version>
</dependency>
=这段代码可以替换word中的latex文本替换为latex公式=
java
package com.kd.distributeSimulate.aiConversation.entity;
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.fields.*;
import com.spire.doc.fields.omath.*;
import java.util.regex.*;
public class LatexFormulaReplacer {
public static void main(String[] args) {
// 输入和输出文件路径
String inputFilePath = "123.docx";
String outputFilePath = "output_with_formulas.docx";
// 加载Word文档
Document doc = new Document();
doc.loadFromFile(inputFilePath);
// 处理文档中的所有LaTeX公式
replaceLatexFormulas(doc);
// 保存文档
doc.saveToFile(outputFilePath, FileFormat.Docx);
System.out.println("LaTeX公式替换完成!输出文件: " + outputFilePath);
}
private static void replaceLatexFormulasInTable(Table table,Document doc) {
Pattern pattern = Pattern.compile("\\$(.*?)\\$");
// 遍历表格的所有行
for (Object rowObj : table.getRows()) {
TableRow row = (TableRow) rowObj;
// 遍历行中的所有单元格
for (Object cellObj : row.getCells()) {
TableCell cell = (TableCell) cellObj;
// 处理单元格中的所有段落
for (Object paragraphObj : cell.getParagraphs()) {
Paragraph paragraph = (Paragraph) paragraphObj;
String paragraphText = paragraph.getText();
Matcher matcher = pattern.matcher(paragraphText);
// 记录处理偏移量,因为替换后文本长度会变化
int offset = 0;
// 查找所有匹配的LaTeX公式
while (matcher.find()) {
// 计算实际位置(考虑之前的替换导致的偏移)
int startPos = matcher.start() - offset;
int endPos = matcher.end() - offset;
String fullMatch = matcher.group(0); // 包含$的完整匹配
String latexFormula = matcher.group(1); // 仅LaTeX内容
System.out.println("找到公式: " + latexFormula);
// 创建OfficeMath对象并设置LaTeX公式
OfficeMath math = new OfficeMath(doc);
math.fromLatexMathCode(latexFormula);
// 查找包含当前匹配文本的TextRange及其在段落中的索引
TextRangeInfo rangeInfo = findTextRangeWithPosition(paragraph, startPos, endPos);
if (rangeInfo == null) {
continue;
}
TextRange targetRange = rangeInfo.textRange;
int rangeIndex = rangeInfo.index;
int relativeStart = rangeInfo.relativeStart;
int relativeEnd = rangeInfo.relativeEnd;
// 拆分文本为三部分:公式前、公式、公式后
String textBefore = targetRange.getText().substring(0, relativeStart);
String textAfter = targetRange.getText().substring(relativeEnd);
// 移除原始文本范围
paragraph.getChildObjects().remove(targetRange);
// 插入公式前的文本(如果不为空)
if (!textBefore.isEmpty()) {
TextRange beforeRange = new TextRange(doc);
beforeRange.setText(textBefore);
paragraph.getChildObjects().insert(rangeIndex, beforeRange);
rangeIndex++; // 插入后索引增加,确保后续元素位置正确
}
// 插入公式对象
paragraph.getChildObjects().insert(rangeIndex, math);
rangeIndex++;
// 插入公式后的文本(如果不为空)
if (!textAfter.isEmpty()) {
TextRange afterRange = new TextRange(doc);
afterRange.setText(textAfter);
paragraph.getChildObjects().insert(rangeIndex, afterRange);
}
// 更新偏移量(原始长度 - 新内容长度,公式对象不占文本长度)
offset += fullMatch.length();
}
}
}
}
}
/**
* 替换文档中所有用$包裹的LaTeX文本为公式对象,保留前后文本
* @param doc Word文档对象
*/
public static void replaceLatexFormulas(Document doc) {
// 正则表达式匹配$包裹的LaTeX公式(非贪婪模式)
Pattern pattern = Pattern.compile("\\$(.*?)\\$");
// 遍历所有节
for (Object sectionObj : doc.getSections()) {
Section section = (Section) sectionObj;
// 处理节中的表格
for (Object tableObj : section.getTables()) {
Table table = (Table) tableObj;
replaceLatexFormulasInTable(table,doc);
}
// 遍历所有段落
for (Object paragraphObj : section.getParagraphs()) {
Paragraph paragraph = (Paragraph) paragraphObj;
// 获取段落文本
String paragraphText = paragraph.getText();
Matcher matcher = pattern.matcher(paragraphText);
// 记录处理偏移量,因为替换后文本长度会变化
int offset = 0;
// 查找所有匹配的LaTeX公式
while (matcher.find()) {
// 计算实际位置(考虑之前的替换导致的偏移)
int startPos = matcher.start() - offset;
int endPos = matcher.end() - offset;
String fullMatch = matcher.group(0); // 包含$的完整匹配
String latexFormula = matcher.group(1); // 仅LaTeX内容
System.out.println("找到公式: " + latexFormula);
// 创建OfficeMath对象并设置LaTeX公式
OfficeMath math = new OfficeMath(doc);
math.fromLatexMathCode(latexFormula);
// 查找包含当前匹配文本的TextRange及其在段落中的索引
TextRangeInfo rangeInfo = findTextRangeWithPosition(paragraph, startPos, endPos);
if (rangeInfo == null) {
continue;
}
TextRange targetRange = rangeInfo.textRange;
int rangeIndex = rangeInfo.index;
int relativeStart = rangeInfo.relativeStart;
int relativeEnd = rangeInfo.relativeEnd;
// 拆分文本为三部分:公式前、公式、公式后
String textBefore = targetRange.getText().substring(0, relativeStart);
String textAfter = targetRange.getText().substring(relativeEnd);
// 移除原始文本范围
paragraph.getChildObjects().remove(targetRange);
// 插入公式前的文本(如果不为空)
if (!textBefore.isEmpty()) {
TextRange beforeRange = new TextRange(doc);
beforeRange.setText(textBefore);
paragraph.getChildObjects().insert(rangeIndex, beforeRange);
rangeIndex++; // 插入后索引增加,确保后续元素位置正确
}
// 插入公式对象
paragraph.getChildObjects().insert(rangeIndex, math);
rangeIndex++;
// 插入公式后的文本(如果不为空)
if (!textAfter.isEmpty()) {
TextRange afterRange = new TextRange(doc);
afterRange.setText(textAfter);
paragraph.getChildObjects().insert(rangeIndex, afterRange);
}
// 更新偏移量(原始长度 - 新内容长度,公式对象不占文本长度)
offset += fullMatch.length();
}
}
}
}
/**
* 辅助类:存储TextRange及其位置信息
*/
private static class TextRangeInfo {
TextRange textRange;
int index; // 在段落子对象中的索引
int relativeStart; // 在TextRange中的起始位置
int relativeEnd; // 在TextRange中的结束位置
TextRangeInfo(TextRange tr, int idx, int rs, int re) {
textRange = tr;
index = idx;
relativeStart = rs;
relativeEnd = re;
}
}
/**
* 在段落中查找包含指定位置范围的TextRange及其详细位置信息
* @param paragraph 段落对象
* @param startPos 起始位置(段落文本中的绝对位置)
* @param endPos 结束位置(段落文本中的绝对位置)
* @return 包含TextRange及位置信息的对象,未找到返回null
*/
private static TextRangeInfo findTextRangeWithPosition(Paragraph paragraph, int startPos, int endPos) {
int currentPos = 0;
int childIndex = 0;
for (Object obj : paragraph.getChildObjects()) {
if (obj instanceof TextRange) {
TextRange textRange = (TextRange) obj;
String text = textRange.getText();
int textLength = text.length();
// 检查当前TextRange是否包含目标位置范围
if (currentPos <= startPos && currentPos + textLength >= endPos) {
// 计算在当前TextRange中的相对位置
int relativeStart = startPos - currentPos;
int relativeEnd = endPos - currentPos;
// 确保相对位置在有效范围内
if (relativeStart >= 0 && relativeEnd <= textLength) {
return new TextRangeInfo(textRange, childIndex, relativeStart, relativeEnd);
}
}
currentPos += textLength;
}
childIndex++;
}
return null;
}
}