Java使用Spire.Doc for Java轻松搞定Word文档打印
在 Java 应用程序中实现 Word 文档的直接打印功能是许多企业级应用的需求。本文将详细介绍如何使用 Spire.Doc for Java 库结合 Java 标准库中的 java.awt.print 包,实现从加载 Word 文档到指定打印机打印的完整解决方案。
准备工作
首先,确保您的项目中已经引入了必要的依赖。Spire.Doc for Java是一个强大的Word文档处理库,支持文档的创建、编辑、转换和打印。您可以通过Maven或手动下载方式添加该库。同时,java.awt.print是Java标准库的一部分,无需额外安装。
<repositories>
<repository>
<id>com.e-iceblue</id>
<name>e-iceblue</name>
<url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>e-iceblue</groupId>
<artifactId>spire.doc</artifactId>
<version>14.1.3</version>
</dependency>
</dependencies>
接下来,确保你的系统可以识别要使用的打印机,可以通过打印机控制面板进行测试。
代码实现
以下是一个完整的示例代码,展示了如何使用 Java 打印一个 Word 文档:
import com.spire.doc.Document;
import javax.print.PrintService;
import java.awt.print.PageFormat;
import java.awt.print.Paper;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
public class PrintWithSpecifiedPrinter {
public static void main(String[] args) throws PrinterException {
// 创建一个 PrinterJob 对象,初始与默认打印机关联
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 指定打印机名称
PrintService myPrintService = findPrintService("\\192.168.1.104\HP LaserJet P1007");
printerJob.setPrintService(myPrintService);
// 创建 PageFormat 实例,并设置默认大小和方向
PageFormat pageFormat = printerJob.defaultPage();
// 返回与此 PageFormat 相关的 Paper 对象的副本
Paper paper = pageFormat.getPaper();
// 设置 Paper 的可打印区域
paper.setImageableArea(0, 0, pageFormat.getWidth(), pageFormat.getHeight());
pageFormat.setPaper(paper);
// 创建文档对象
Document document = new Document();
// 从文件中加载 Word 文档
document.loadFromFile("C:\Users\Administrator\Desktop\Input.docx");
// 设置打印文档的格式
printerJob.setPrintable(document, pageFormat);
// 执行打印操作
try {
printerJob.print();
} catch (PrinterException e) {
e.printStackTrace();
}
}
// 查找打印服务
private static PrintService findPrintService(String printerName) {
PrintService[] printServices = PrinterJob.lookupPrintServices();
for (PrintService printService : printServices) {
if (printService.getName().equals(printerName)) {
return printService;
}
}
return null;
}
}
代码解释
- 创建 PrinterJob 对象 :使用
PrinterJob.getPrinterJob()初始化一个默认打印作业。 - 查找打印服务 :
findPrintService方法循环遍历系统中所有的打印服务,并匹配指定的打印机名称。 - 定义纸张格式 :使用
PageFormat和Paper类来设置纸张的大小和可打印区域。 - 加载 Word 文档 :使用 Spire.Doc 的
Document类加载指定路径的 Word 文档。 - 打印文档 :使用
printerJob.print()执行打印操作。同时,对可能抛出的PrinterException进行异常处理。
知识补充
本文介绍如何在Java程序中通过物理打印机和虚拟打印机来打印Word文档的方法。文中使用了类库Spire.Doc for Java,可通过官网下载jar文件并导入程序或者直接通过maven仓库安装导入。
【示例1】通过物理打印机打印
import com.spire.doc.Document;
import com.spire.ms.System.Drawing.Printing.PrinterSettings;
public class PrintWord {
public static void main(String[] args) {
//加载Word文档
Document document = new Document();
document.loadFromFile("C:\\Users\\Administrator\\Desktop\\DocoumentToPrint.docx");
//创建PrinterSettings对象
PrinterSettings printerSettings = new PrinterSettings();
//指定物理打印机名称
printerSettings.setPrinterName("\\\\192.168.1.104\\HP LaserJet P1007");
//设置打印份数
printerSettings.setCopies((short) 1);
//设置打印范围
printerSettings.setFromPage(2);
printerSettings.setToPage(4);
//应用打印设置
document.getPrintDocument().setPrinterSettings(printerSettings);
//执行打印
document.getPrintDocument().print();
}
}
【示例2】通过虚拟打印机打印
import com.spire.doc.Document;
import com.spire.ms.System.Drawing.Printing.PrinterSettings;
public class PrintWord {
public static void main(String[] args) {
//加载Word文档
Document document = new Document();
document.loadFromFile("C:\\Users\\Administrator\\Desktop\\DocumentToPrint.docx");
//创建PrinterSettings对象
PrinterSettings printerSettings = new PrinterSettings();
//指定虚拟打印机
printerSettings.setPrinterName("Microsoft Print to PDF");
//打印到文档
printerSettings.setPrintToFile(true);
//指定打印文档的保存路径和名称
printerSettings.setPrintFileName("output/PrintToPDF.pdf");
//应用打印设置
document.getPrintDocument().setPrinterSettings(printerSettings);
//执行打印
document.getPrintDocument().print();
}
}
java操作word并通过打印机打印
1.本文使用工具类为Jacob 来操作word文档, 优点是功能强大, 直接操作word, 方便控制样式,缺点是配置复杂,只能用在windows平台,需要电脑上有wps或office
2.首先下载Jacob压缩包,将其中的 jacob-1.17-M2-x64.dll 文件放在 %JAVA_HOME%/jre/bin目录下 ,win7放在System32 目录下。(如果win7是32位系统,则放在 System64目录下,有点诡异)
3.在项目的resource目录下新建lib文件夹,将Jacob.jar 放在lib目录下
4.引入pom依赖
<dependency>
<groupId>com.jacob</groupId>
<artifactId>jacob</artifactId>
<version>1.17</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/jacob.jar</systemPath>
</dependency>5.打开要操作的word,其中要填充的数据位使用占位符填充,格式为 {{变量名}},此处变量名需要与java中相应的变量名一致
6.在数据库中取出想要的数据,创建一个相对应的map
/**
* 生成收据
*/
@GetMapping("/contract")
public AjaxResult Contract() {
String fileName = DateUtils.timechuo() + ".docx"; //根据模板生成的文件名
String templateFilePath = null;
String printerName = null; //打印机的名字,也可以不指定
//从数据库中查询订单信息
/通过你自己的service在数据库中查询想要的数据
for (Object o : jsonArray) { //如果是多条数据 使用循环遍历 根据业务进行修改
JSONObject ob = (JSONObject) o;
String houseid = ob.getString("houseid");
String amount = ob.getString("shouldamount");
String outtradeno = ob.getString("outtradeno");
String houseNo = getHouseNo(houseid);
//创建一个map 将数据库中的数据写进去
Map<String,String> map = new HashMap<>();
//map的键必须与word中的占位符一致, 如word中{{houseid}}则map键名为 "houseid"
map.put("houseid",houseid);
map.put("Amount",amountUp);
map.put("outtradeno",outtradeno);
String path1 = "D:/模板.docx"; //模板word路径
String outFilePath = "D:/" + fileName; //生成的word文件输出路径
templateFilePath = path1; //模板word路径
//调用接口生成收据
try {
//可以指定打印机
// insertAndOutFile2(templateFilePath,outFilePath,map,printerName);
//不指定打印机会选择默认打印机)
insertAndOutFile2(templateFilePath,outFilePath,map);
//修改打印状态
ob.put("status",1);
//这里调用你自己的service修改状态就可以了
}catch (Exception e){
System.out.println(e.getMessage());
}
}
return AjaxResult.success();
}
/**
* 生成一个新的收据
* @param templateFilePath word模板文件路径
* @param outFilePath 填充后输出文件路径
* @param map key:word中的占位标签,value对应标签要替换的值。
* @throws IOException
*/
public void insertAndOutFile2(String templateFilePath, String outFilePath, Map<String,String> map, String printerName) throws Exception {
// Map<String,Object> data = new HashMap<String, Object>();
// data.put("title", "Poi-tl 模板引擎");//添加数据,键是 模板中的{{title}},值在渲染的时候会替换掉对应的标签
XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //编译模板,把数据塞入模板中,找到对应标签替换
FileOutputStream out = new FileOutputStream(outFilePath);//新建导出文件
template.write(out); //输出到流
out.flush();
out.close();
template.close();
PrintWordUtiil.printWord(outFilePath,printerName);
}
//重载 不需要传打印机名字的方法
public void insertAndOutFile2(String templateFilePath, String outFilePath, Map<String,String> map) throws Exception {
// Map<String,Object> data = new HashMap<String, Object>();
// data.put("title", "Poi-tl 模板引擎");//添加数据,键是 模板中的{{title}},值在渲染的时候会替换掉对应的标签
XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //编译模板,把数据塞入模板中,找到对应标签替换
FileOutputStream out = new FileOutputStream(outFilePath);//新建导出文件
template.write(out); //输出到流
out.flush();
out.close();
template.close();
PrintWordUtiil.printWord(outFilePath);
}
//下边两个方法是生成文件夹和命名的 可用可不用
/**
* 以当前日期为名,创建新文件夹
*
* @return
*/
private static String createNewDir() {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
return fmt.format(new Date());
}
/**
* 为文件重新命名,命名规则为当前系统时间毫秒数
*
* @return string
*/
private static String getFileNameNew() {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
return fmt.format(new Date());
}
7.打印工具类,核心,需要打印的文件只需要调用 PrintWordUtil.printWord()方法,传入相应参数就可以了
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.standard.Sides;
import java.awt.print.*;
import java.io.File;
import java.io.IOException;
public class PrintWordUtiil {
//这个方法是需要传打印机名字的(即指定打印机) 下边有个重载的方法不需要传打印机名字
public static void printWord(String filePath,String printerName) throws PrinterException {
// 初始化线程
ComThread.InitSTA();
ActiveXComponent word = new ActiveXComponent("Word.Application");
//设置打印机名称
if (printerName == null && printerName == ""){
//如果打印机的名字为空,则默认机器首个打印机
// 创建一个PrinterJob对象
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 设置打印机
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
printerJob.setPrintService(printService);
printerName = printService.getName();
System.out.println("发现的打印机名名称为:"+printerName);
}
word.setProperty("ActivePrinter", new Variant(printerName));
// 这里Visible是控制文档打开后是可见还是不可见,若是静默打印,那么第三个参数就设为false就好了
Dispatch.put(word, "Visible", new Variant(false));
// 获取文档属性
Dispatch document = word.getProperty("Documents").toDispatch();
// 打开激活文挡
Dispatch doc=Dispatch.call(document, "Open", filePath).toDispatch();
//Dispatch doc = Dispatch.invoke(document, "Open", Dispatch.Method,
// new Object[] { filePath }, new int[1]).toDispatch();
try{
Dispatch.callN(doc, "PrintOut");
System.out.println("打印成功!");
}catch (Exception e){
e.printStackTrace();
System.out.println("打印失败");
}finally {
try {
if (doc != null) {
Dispatch.call(doc, "Close", new Variant(0));//word文档关闭
}
} catch (Exception e2) {
e2.printStackTrace();
}
//退出
word.invoke("Quit", new Variant[0]);
//释放资源
ComThread.Release();
ComThread.quitMainSTA();
}
}
public static void printWord(String filePath) throws PrinterException {
// 初始化线程
ComThread.InitSTA();
ActiveXComponent word = new ActiveXComponent("Word.Application");
//设置打印机名称
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 设置打印机
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
printerJob.setPrintService(printService);
String printerName = printService.getName();
System.out.println("发现的打印机名名称为:"+printerName);
printWord(filePath,printerName);
}
}结论
通过以上步骤,你可以轻松地在 Java 应用程序中集成打印功能。利用 Spire.Doc for Java 和 java.awt.print 库,你可以实现对 Word 文档的自动打印,提升用户体验和工作效率。在开发过程中,务必确保打印机连接正常,以及文件路径的正确性,以避免运行时错误。
相关文章
SpringBoot自定义HttpMessageConverter操作
这篇文章主要介绍了SpringBoot自定义HttpMessageConverter的操作,具有很好的参考价值,如有错误或未考虑完全的地方,望不吝赐教2021-08-08
spring-boot-maven-plugin:unknown的完美解决方法
这篇文章主要介绍了spring-boot-maven-plugin:unknown的完美解决方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-11-11


最新评论