一、准备环境
1️⃣ 安装 JDK
java -version
2️⃣ 安装 Maven
mvn -version
确认可用
二、创建 Maven 项目(命令行方式)
1️⃣ 创建项目结构
mvn archetype:generate ^
-DgroupId=com.example ^
-DartifactId=word-toc-tool ^
-DarchetypeArtifactId=maven-archetype-quickstart ^
-DinteractiveMode=false
2️⃣ 进入项目
cd word-toc-tool
三、项目结构说明
生成后结构:
word-toc-tool/
│
├── pom.xml
└── src/
├── main/
│ └── java/
│ └── com/example/
│ └── App.java
└── test/
四、修改 Java 代码(关键补充)
1️⃣ 删除默认 App.java
src/main/java/com/example/App.java
2️⃣ 新建文件:
WordTocUpdater.java
路径:
src/main/java/com/example/WordTocUpdater.java
3️⃣ 核心代码(可直接用)
package com.example;
import com.aspose.words.*;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
public class WordTocUpdater {
private static int step = 1;
private static String now() {
return new SimpleDateFormat("HH:mm:ss").format(new Date());
}
private static void logStep(String msg) {
System.out.println("[" + now() + "] [" + (step++) + "] " + msg);
}
private static void logInfo(String msg) {
System.out.println("[" + now() + "] [INFO] " + msg);
}
private static void logWarn(String msg) {
System.out.println("[" + now() + "] [WARN] " + msg);
}
private static void logErr(String msg) {
System.err.println("[" + now() + "] [ERROR] " + msg);
}
public static String updateToc(String inputPath) {
logStep("开始处理");
logInfo("输入文件: " + inputPath);
String outputPath;
int dotIndex = inputPath.lastIndexOf(".");
if (dotIndex == -1) {
outputPath = inputPath + "_toc.docx";
} else {
outputPath = inputPath.substring(0, dotIndex) + "_toc.docx";
}
try {
File file = new File(inputPath);
if (!file.exists()) {
logErr("文件不存在!");
return null;
}
// 1. 加载
logStep("加载文档");
Document doc = new Document(inputPath);
doc.acceptAllRevisions();
doc.getCompatibilityOptions().optimizeFor(MsWordVersion.WORD_2010);
// 2. 字体 & 表格
configFontsPath();
autoFitTables(doc);
// 3. 分节
splitTocAndBody(doc);
// 4. 页码
insertPageNumber(doc);
// 5. Word逻辑
logStep("分页");
doc.updatePageLayout();
logStep("更新目录");
doc.updateFields();
// 6. 保存
doc.save(outputPath, SaveFormat.DOCX);
logStep("完成");
logInfo("输出文件: " + outputPath);
} catch (Exception e) {
logErr("处理失败");
e.printStackTrace();
}
return outputPath;
}
private static void splitTocAndBody(Document doc) throws Exception {
logStep("分节处理");
if (doc.getSections().getCount() > 1) {
logWarn("已有多个节,跳过");
return;
}
DocumentBuilder builder = new DocumentBuilder(doc);
boolean hasToc = false;
for (Field field : doc.getRange().getFields()) {
if (field.getType() == FieldType.FIELD_TOC) {
builder.moveToField(field, true);
builder.insertBreak(BreakType.SECTION_BREAK_NEW_PAGE);
hasToc = true;
logInfo("检测到TOC并已分节");
break;
}
}
if (!hasToc) {
logWarn("未检测到TOC");
return;
}
Section sec1 = doc.getSections().get(0);
sec1.getPageSetup().setRestartPageNumbering(true);
sec1.getPageSetup().setPageStartingNumber(1);
sec1.getPageSetup().setPageNumberStyle(NumberStyle.LOWERCASE_ROMAN);
Section sec2 = doc.getSections().get(1);
sec2.getPageSetup().setRestartPageNumbering(true);
sec2.getPageSetup().setPageStartingNumber(1);
sec2.getPageSetup().setPageNumberStyle(NumberStyle.ARABIC);
}
private static void insertPageNumber(Document doc) throws Exception {
logStep("插入页码");
for (int i = 0; i < doc.getSections().getCount(); i++) {
Section section = doc.getSections().get(i);
HeaderFooter footer = section.getHeadersFooters()
.getByHeaderFooterType(HeaderFooterType.FOOTER_PRIMARY);
if (footer == null) {
footer = new HeaderFooter(doc, HeaderFooterType.FOOTER_PRIMARY);
section.getHeadersFooters().add(footer);
}
if (i > 0) {
section.getHeadersFooters().linkToPrevious(false);
}
footer.removeAllChildren();
Paragraph p = new Paragraph(doc);
p.getParagraphFormat().setAlignment(ParagraphAlignment.CENTER);
// ✅ 关键修复:统一页码体系
p.appendChild(new Run(doc, "第 "));
p.appendField(FieldType.FIELD_PAGE, true);
p.appendChild(new Run(doc, " 页 / 共 "));
p.appendField(FieldType.FIELD_NUM_PAGES, true);
p.appendChild(new Run(doc, " 页"));
footer.appendChild(p);
}
logInfo("页码插入完成(已修复错乱问题)");
}
private static void autoFitTables(Document doc) {
NodeCollection tables = doc.getChildNodes(NodeType.TABLE, true);
int count = 0;
for (Object obj : tables) {
try {
Table table = (Table) obj;
table.autoFit(AutoFitBehavior.AUTO_FIT_TO_WINDOW);
count++;
} catch (Exception e) {
logWarn("表格处理失败");
}
}
logInfo("表格数量: " + count);
}
private static void configFontsPath() {
try {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
FontSettings.getDefaultInstance()
.setFontsFolder("C:/Windows/Fonts", true);
} else {
FontSettings.getDefaultInstance()
.setFontsFolders(new String[]{
"/usr/share/fonts",
"/usr/local/share/fonts"
}, true);
}
logInfo("字体配置完成");
} catch (Exception e) {
logWarn("字体配置失败");
}
}
public static void main(String[] args) {
if (args.length == 0) {
System.out.println("用法: java -jar xxx.jar 文件.docx");
return;
}
updateToc(args[0]);
}
}
五、替换 pom.xml
改成Aspose 版本 + 打包插件:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>word-toc-tool</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<!-- ⭐ 正确方式:普通依赖(关键修改) -->
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>21.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- ⭐ Maven Shade:打 fat jar -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<!-- ⭐ 防止依赖丢失 -->
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.WordTocUpdater</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
六、安装 Aspose 到本地仓库
mvn install:install-file ^
-Dfile=aspose-words-24.7-jdk17.jar ^
-DgroupId=com.aspose ^
-DartifactId=aspose-words ^
-Dversion=24.7 ^
-Dpackaging=jar
七、打包
mvn clean package

184

被折叠的 条评论
为什么被折叠?



