Java 打印 Word 文档:从基础打印到高级设置

在日常办公自动化中,打印 Word 文档是个常见需求。无论是批量打印合同、报告,还是在后台服务中自动输出文档,都需要通过代码控制打印过程。手动打开 Word 再打印效率太低,特别是在需要处理大量文档或集成到自动化流程时。

今天分享一下如何用 Java 代码打印 Word 文档,从最简单的一行代码打印,到自定义纸张大小、边距、双面打印等高级设置。完全不需要打开 Microsoft Word,纯后台即可完成。

先说说应用场景

在实际工作中,程序化打印主要用在这些地方:

  1. 批量打印 - 一次性打印几十上百个文档
  2. 后台服务 - 在服务器端自动打印生成的报告
  3. 定时任务 - 按 schedule 自动打印日报/周报
  4. 自助打印系统 - 用户提交文档后自动排队打印
  5. 归档系统 - 打印后扫描存档

理解了用途,就知道什么时候该用程序化方式打印,而不是手动操作。

环境准备

Maven 依赖

如果你的项目使用 Maven,可以在 ​​pom.xml​​ 中添加以下配置:

xml 复制代码
<repositories>
    <repository>
        <id>com.e-iceblue</id>
        <name>e-iceblue</name>
        <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>e-iceblue</groupId>
        <artifactId>spire.doc</artifactId>
        <version>14.6.0</version>
    </dependency>
</dependencies>

导入常用类

在 Java 代码中,需要导入本文示例常用的类:

java 复制代码
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.Printing.*;
import java.awt.print.*;

其中:

  • ​Document​:用于加载 Word 文档;
  • ​PrintDocument​:Spire.Doc 提供的打印对象;
  • ​PrinterJob​:Java 标准打印任务对象;
  • ​PageFormat​​Paper​:用于设置页面格式;
  • ​Margins​:用于设置页边距;
  • ​Duplex​:用于设置双面打印模式。

一、最基础的打印:一行代码搞定

先从最简单的开始------加载文档并直接打印:

typescript 复制代码
import com.spire.doc.*;

public class SimplePrint {
    public static void main(String[] args) {
        // 创建文档对象
        Document document = new Document();
        
        // 加载 Word 文件
        document.loadFromFile("data/report.docx");
        
        // 打印文档(使用默认打印机和设置)
        document.getPrintDocument().print();
        
        // 释放资源
        document.dispose();
        
        System.out.println("文档已发送到打印机!");
    }
}

就这么简单! 三行核心代码完成打印:

  1. 加载文档
  2. 获取打印对象并调用 ​print()​
  3. 释放资源

适用场景:

  • 快速测试打印功能
  • 使用默认打印机和设置
  • 不需要自定义任何参数
  • 内部办公环境,打印机已配置好

注意:

  • 这会弹出打印对话框(取决于系统配置)
  • 使用系统默认打印机
  • 使用文档默认的页面设置

二、使用 PrinterJob 精确控制打印

如果需要更精细的控制(如设置份数、页边距、选择打印机等),可以使用 Java 标准的 ​​PrinterJob​​ API。

java 复制代码
import com.spire.doc.*;
import java.awt.print.*;

public class PrintWithControl {
    public static void main(String[] args) {
        // 加载文档
        Document document = new Document();
        document.loadFromFile("data/report.docx");
        
        // 创建打印任务
        PrinterJob printerJob = PrinterJob.getPrinterJob();
        
        // 获取默认页面格式
        PageFormat pageFormat = printerJob.defaultPage();
        
        // 获取纸张对象
        Paper paper = pageFormat.getPaper();
        
        // 设置可打印区域(移除默认边距)
        paper.setImageableArea(0, 0, pageFormat.getWidth(), pageFormat.getHeight());
        
        // 设置打印份数
        printerJob.setCopies(2);  // 打印 2 份
        
        // 应用纸张设置
        pageFormat.setPaper(paper);
        
        // 设置可打印对象
        printerJob.setPrintable(document, pageFormat);
        
        try {
            // 执行打印
            printerJob.print();
            System.out.println("打印成功!");
        } catch (PrinterException e) {
            System.err.println("打印失败: " + e.getMessage());
            e.printStackTrace();
        }
        
        // 释放资源
        document.dispose();
    }
}

关键设置说明:

  1. 设置打印份数
scss 复制代码
printerJob.setCopies(2);  // 打印 2 份
  1. 移除默认边距
arduino 复制代码
paper.setImageableArea(0, 0, width, height);

这样可以实现无边距打印,适合打印照片或特殊文档。

  1. 异常处理
php 复制代码
try {
    printerJob.print();
} catch (PrinterException e) {
    // 处理打印错误
}

适用场景:

  • 需要设置打印份数
  • 需要自定义页边距
  • 需要选择特定打印机
  • 需要更精细的打印控制

优势:

  • 使用 Java 标准 API,兼容性好
  • 可以集成到现有的打印系统中
  • 支持更多自定义选项

三、自定义纸张大小

有时候需要使用非标准纸张大小,例如自定义标签纸、特殊尺寸的报表等。Spire.Doc 允许你自定义纸张的宽度和高度。

arduino 复制代码
import com.spire.doc.*;
import com.spire.doc.Printing.*;

public class CustomPaperSize {
    public static void main(String[] args) {
        // 加载文档
        Document doc = new Document();
        doc.loadFromFile("data/report.docx");
        
        // 获取打印对象
        PrintDocument printDoc = doc.getPrintDocument();
        
        // 创建自定义纸张大小
        PaperSize size = new PaperSize();
        size.setWidth(900);   // 宽度(单位:点,1点=1/72英寸)
        size.setHeight(800);  // 高度
        
        // 应用自定义纸张大小
        printDoc.getDefaultPageSettings().setPaperSize(size);
        
        // 打印文档
        printDoc.print();
        
        // 释放资源
        doc.dispose();
        
        System.out.println("使用自定义纸张大小打印完成!");
    }
}

纸张尺寸换算:

单位 换算关系 示例
点(Point) 1 点 = 1/72 英寸 A4: 595 x 842 点
英寸 1 英寸 = 72 点 Letter: 612 x 792 点
厘米 1 厘米 ≈ 28.35 点 10cm ≈ 283 点

常见纸张尺寸(单位:点):

  • A4: 595 x 842
  • Letter: 612 x 792
  • Legal: 612 x 1008
  • A3: 842 x 1191

适用场景:

  • 打印自定义标签
  • 特殊尺寸的报表
  • 名片、卡片打印
  • 非标准纸张的文档

注意:

  • 确保打印机支持自定义纸张大小
  • 不同打印机的最大/最小纸张尺寸可能不同
  • 建议在打印前测试实际效果

四、设置页边距和双面打印

专业的文档打印通常需要精确控制页边距,并且为了节省纸张,经常需要双面打印。

java 复制代码
import com.spire.doc.*;
import com.spire.doc.documents.*;
import com.spire.doc.Printing.*;

public class SetMarginAndDuplex {
    public static void main(String[] args) {
        // 加载文档
        Document doc = new Document();
        doc.loadFromFile("data/report.docx");
        
        // 获取打印对象
        PrintDocument printDoc = doc.getPrintDocument();
        
        // 1. 设置图形原点从页边距开始
        printDoc.setOriginAtMargins(true);
        
        // 2. 设置页边距为 0(无边距打印)
        printDoc.getDefaultPageSettings().setMargins(new Margins(0, 0, 0, 0));
        
        // 3. 设置双面打印 - 垂直翻转(长边装订)
        printDoc.getPrinterSettings().setDuplex(Duplex.Vertical);
        
        // 如果是短边装订(横向翻转),使用:
        // printDoc.getPrinterSettings().setDuplex(Duplex.Horizontal);
        
        // 打印文档
        printDoc.print();
        
        // 释放资源
        doc.dispose();
        
        System.out.println("双面打印完成!");
    }
}

双面打印模式说明:

模式 说明 适用场景
​Duplex.Vertical​ 垂直翻转(长边装订) 普通文档、书籍
​Duplex.Horizontal​ 水平翻转(短边装订) 日历、便签本
​Duplex.Simplex​ 单面打印(默认) 单页文档

页边距设置:

scss 复制代码
// 设置四周边距(左、上、右、下),单位:点
new Margins(left, top, right, bottom)

// 示例:
new Margins(0, 0, 0, 0)      // 无边距
new Margins(72, 72, 72, 72)  // 各边 1 英寸
new Margins(36, 36, 36, 36)  // 各边 0.5 英寸

​setOriginAtMargins(true) ​​ 的作用:

  • ​true​: 图形绘制原点从页边距开始(推荐)
  • ​false​: 图形绘制原点从物理纸张边缘开始

适用场景:

  • 节省纸张的双面打印
  • 专业文档的精确边距控制
  • 制作小册子或手册
  • 无边距照片打印

注意:

  • 不是所有打印机都支持双面打印
  • 双面打印前确认打印机支持该功能
  • 某些打印机可能需要手动翻面

五、实战:批量打印多个文档

最后来个完整的实战例子------批量打印文件夹中的所有 Word 文档:

typescript 复制代码
import com.spire.doc.*;
import java.io.File;

public class BatchPrintDocuments {
    
    /**
     * 批量打印指定文件夹中的所有 Word 文档
     * 
     * @param folderPath 文件夹路径
     * @param copies 每个文档打印的份数
     */
    public static void batchPrint(String folderPath, int copies) {
        File folder = new File(folderPath);
        
        if (!folder.exists() || !folder.isDirectory()) {
            System.err.println("错误:文件夹不存在 - " + folderPath);
            return;
        }
        
        // 获取所有 .docx 文件
        File[] docFiles = folder.listFiles((dir, name) -> 
            name.toLowerCase().endsWith(".docx") || name.toLowerCase().endsWith(".doc")
        );
        
        if (docFiles == null || docFiles.length == 0) {
            System.out.println("未找到 Word 文档");
            return;
        }
        
        System.out.println("找到 " + docFiles.length + " 个文档,开始批量打印...\n");
        
        int successCount = 0;
        int failCount = 0;
        
        for (File docFile : docFiles) {
            Document document = null;
            
            try {
                System.out.println("正在打印: " + docFile.getName());
                
                // 加载文档
                document = new Document();
                document.loadFromFile(docFile.getAbsolutePath());
                
                // 获取打印对象
                PrintDocument printDoc = document.getPrintDocument();
                
                // 设置打印份数
                printDoc.getPrinterSettings().setCopies(copies);
                
                // 执行打印
                printDoc.print();
                
                successCount++;
                System.out.println("✓ " + docFile.getName() + " 打印成功\n");
                
            } catch (Exception e) {
                failCount++;
                System.err.println("✗ " + docFile.getName() + " 打印失败: " + e.getMessage() + "\n");
                
            } finally {
                // 确保释放资源
                if (document != null) {
                    document.dispose();
                }
            }
        }
        
        // 输出统计结果
        System.out.println("========== 批量打印完成 ==========");
        System.out.println("成功: " + successCount);
        System.out.println("失败: " + failCount);
    }
    
    public static void main(String[] args) {
        // 批量打印文件夹中的所有文档,每个打印 1 份
        batchPrint("C:\Documents\ToPrint", 1);
    }
}

这个例子展示了:

  • ✅ 自动扫描文件夹中的所有 Word 文档
  • ✅ 支持 ​.doc​​.docx​ 格式
  • ✅ 设置打印份数
  • ✅ 完整的错误处理
  • ✅ 资源管理(确保 ​dispose()​ 被调用)
  • ✅ 详细的进度反馈和统计

使用场景:

  • 月底批量打印所有员工报告
  • 打印一批合同文档
  • 自动打印生成的发票
  • 定期打印日报/周报

六、常见问题与解决方案

问题1:打印时弹出对话框

原因: 默认打印行为可能会显示打印对话框。

解决方案:

scss 复制代码
// 方法1:使用 PrinterJob 静默打印
PrinterJob printerJob = PrinterJob.getPrinterJob();
printerJob.setPrintable(document, pageFormat);
printerJob.print();  // 不会弹出对话框

// 方法2:设置打印机属性
printDoc.getPrinterSettings().setPrintToFile(false);

问题2:找不到打印机

原因: 系统没有配置默认打印机,或指定的打印机不可用。

解决方案:

ini 复制代码
// 检查可用打印机
PrinterJob printerJob = PrinterJob.getPrinterJob();
PrintService[] services = PrinterJob.lookupPrintServices();

if (services.length == 0) {
    System.err.println("未找到可用打印机");
    return;
}

// 选择特定打印机
for (PrintService service : services) {
    System.out.println("可用打印机: " + service.getName());
}

问题3:打印内容偏移或裁剪

原因: 页边距设置不正确,或纸张大小不匹配。

解决方案:

scss 复制代码
// 调整页边距
printDoc.getDefaultPageSettings().setMargins(new Margins(36, 36, 36, 36));

// 或者移除边距
paper.setImageableArea(0, 0, width, height);

// 确认纸张大小正确
printDoc.getDefaultPageSettings().setPaperSize(PaperSize.A4);

问题4:双面打印不生效

原因: 打印机不支持双面打印,或驱动未正确配置。

解决方案:

ini 复制代码
// 检查打印机是否支持双面打印
PrintService service = printerJob.getPrintService();
boolean supportsDuplex = service.isAttributeCategorySupported(Duplex.class);

if (!supportsDuplex) {
    System.out.println("打印机不支持双面打印");
    // 降级为单面打印
    printDoc.getPrinterSettings().setDuplex(Duplex.Simplex);
}

问题5:内存占用过高

原因: 批量打印时未及时释放资源。

解决方案:

javascript 复制代码
// 始终在 finally 块中释放资源
Document document = null;
try {
    document = new Document();
    document.loadFromFile(filePath);
    // ... 打印操作 ...
} finally {
    if (document != null) {
        document.dispose();
    }
}

// 对于大量文档,考虑分批处理
// 每处理 10 个文档后触发垃圾回收
if (count % 10 == 0) {
    System.gc();
}

七、最佳实践总结

1. 始终释放资源

javascript 复制代码
Document document = new Document();
try {
    document.loadFromFile("file.docx");
    // ... 打印操作 ...
} finally {
    document.dispose();  // 确保资源被释放
}

2. 添加异常处理

php 复制代码
try {
    printDoc.print();
} catch (PrinterException e) {
    System.err.println("打印失败: " + e.getMessage());
    // 记录日志、通知用户等
}

3. 打印前验证

go 复制代码
// 检查文件是否存在
if (!new File(filePath).exists()) {
    System.err.println("文件不存在: " + filePath);
    return;
}

// 检查打印机是否可用
PrinterJob printerJob = PrinterJob.getPrinterJob();
if (printerJob == null) {
    System.err.println("无法获取打印任务");
    return;
}

4. 选择合适的打印方法

场景 推荐方法
简单快速打印 ​document.getPrintDocument().print()​
需要精确控制 使用 ​​PrinterJob​​ API
自定义纸张 使用 ​​PrintDocument​​​ + ​​PaperSize​
双面打印 使用 ​​PrintDocument​​​ + ​​Duplex​
批量打印 循环 + 资源管理

5. 性能优化

scss 复制代码
// 批量打印时,考虑异步处理
ExecutorService executor = Executors.newFixedThreadPool(2);

for (File file : files) {
    executor.submit(() -> {
        printDocument(file.getAbsolutePath());
    });
}

executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);

小结

使用 Spire.Doc for Java 打印 Word 文档非常灵活,可以根据需求选择不同的打印方式:

核心要点:

  • ✅ 基础打印只需一行代码:​document.getPrintDocument().print()​
  • ✅ 使用 ​PrinterJob​ 可以获得更精细的控制
  • ✅ 可以自定义纸张大小、页边距、打印份数
  • ✅ 支持双面打印(垂直/水平翻转)
  • ✅ 批量打印时注意资源管理和异常处理

常见操作速查:

操作 代码示例
基础打印 ​doc.getPrintDocument().print()​
设置份数 ​printerJob.setCopies(2)​
自定义纸张 ​printDoc.getDefaultPageSettings().setPaperSize(size)​
设置边距 ​printDoc.getDefaultPageSettings().setMargins(new Margins(0,0,0,0))​
双面打印 ​printDoc.getPrinterSettings().setDuplex(Duplex.Vertical)​
移除边距 ​paper.setImageableArea(0, 0, width, height)​

适用场景:

  • 批量打印办公文档
  • 后台服务自动打印
  • 定时任务打印报告
  • 自助打印系统
  • 文档归档系统

注意事项:

  • 始终调用 ​dispose()​ 释放资源
  • 添加适当的异常处理
  • 确认打印机支持所需功能(如双面打印)
  • 批量打印时注意内存管理
  • 测试不同打印机的兼容性

希望这篇文章能帮你更好地理解和实现 Java 打印 Word 文档。有问题欢迎在评论区交流讨论!

相关推荐
用户35218024547517 小时前
当 Prompt 学会"热更新":Spring Boot × Nacos3 AI 实战
java·spring boot·ai编程
东坡白菜20 小时前
破局全栈:一个前端开发的Java入门实战记录(1)
java·全栈
唐青枫20 小时前
Java Tomcat 实战指南:从 Servlet 容器到 Spring Boot 部署
java
wsaaaqqq20 小时前
roudan:自由选择实体、灵活操作数据、快速写入数据库的 Java 框架
java
plainGeekDev1 天前
null 判断 → Kotlin 可空类型
android·java·kotlin
糖拌西瓜皮1 天前
Java开发者视角:深入理解Node.js异步编程模型
java·后端·node.js
plainGeekDev1 天前
getter/setter → Kotlin 属性
android·java·kotlin
一线大码1 天前
Smart-Doc 的简单使用
java·后端·restful
MacroZheng1 天前
Claude Code官方桌面端正式发布,夯爆了!
java·人工智能·后端