Java使用Spire.Doc for Java輕松搞定Word文檔打印
在 Java 應用程序中實現(xiàn) Word 文檔的直接打印功能是許多企業(yè)級應用的需求。本文將詳細介紹如何使用 Spire.Doc for Java 庫結合 Java 標準庫中的 java.awt.print 包,實現(xiàn)從加載 Word 文檔到指定打印機打印的完整解決方案。
準備工作
首先,確保您的項目中已經(jīng)引入了必要的依賴。Spire.Doc for Java是一個強大的Word文檔處理庫,支持文檔的創(chuàng)建、編輯、轉換和打印。您可以通過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>
接下來,確保你的系統(tǒng)可以識別要使用的打印機,可以通過打印機控制面板進行測試。
代碼實現(xiàn)
以下是一個完整的示例代碼,展示了如何使用 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 {
// 創(chuàng)建一個 PrinterJob 對象,初始與默認打印機關聯(lián)
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 指定打印機名稱
PrintService myPrintService = findPrintService("\\192.168.1.104\HP LaserJet P1007");
printerJob.setPrintService(myPrintService);
// 創(chuàng)建 PageFormat 實例,并設置默認大小和方向
PageFormat pageFormat = printerJob.defaultPage();
// 返回與此 PageFormat 相關的 Paper 對象的副本
Paper paper = pageFormat.getPaper();
// 設置 Paper 的可打印區(qū)域
paper.setImageableArea(0, 0, pageFormat.getWidth(), pageFormat.getHeight());
pageFormat.setPaper(paper);
// 創(chuàng)建文檔對象
Document document = new Document();
// 從文件中加載 Word 文檔
document.loadFromFile("C:\Users\Administrator\Desktop\Input.docx");
// 設置打印文檔的格式
printerJob.setPrintable(document, pageFormat);
// 執(zhí)行打印操作
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;
}
}
代碼解釋
- 創(chuàng)建 PrinterJob 對象 :使用
PrinterJob.getPrinterJob()初始化一個默認打印作業(yè)。 - 查找打印服務 :
findPrintService方法循環(huán)遍歷系統(tǒng)中所有的打印服務,并匹配指定的打印機名稱。 - 定義紙張格式 :使用
PageFormat和Paper類來設置紙張的大小和可打印區(qū)域。 - 加載 Word 文檔 :使用 Spire.Doc 的
Document類加載指定路徑的 Word 文檔。 - 打印文檔 :使用
printerJob.print()執(zhí)行打印操作。同時,對可能拋出的PrinterException進行異常處理。
知識補充
本文介紹如何在Java程序中通過物理打印機和虛擬打印機來打印Word文檔的方法。文中使用了類庫Spire.Doc for Java,可通過官網(wǎng)下載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");
//創(chuàng)建PrinterSettings對象
PrinterSettings printerSettings = new PrinterSettings();
//指定物理打印機名稱
printerSettings.setPrinterName("\\\\192.168.1.104\\HP LaserJet P1007");
//設置打印份數(shù)
printerSettings.setCopies((short) 1);
//設置打印范圍
printerSettings.setFromPage(2);
printerSettings.setToPage(4);
//應用打印設置
document.getPrintDocument().setPrinterSettings(printerSettings);
//執(zhí)行打印
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");
//創(chuàng)建PrinterSettings對象
PrinterSettings printerSettings = new PrinterSettings();
//指定虛擬打印機
printerSettings.setPrinterName("Microsoft Print to PDF");
//打印到文檔
printerSettings.setPrintToFile(true);
//指定打印文檔的保存路徑和名稱
printerSettings.setPrintFileName("output/PrintToPDF.pdf");
//應用打印設置
document.getPrintDocument().setPrinterSettings(printerSettings);
//執(zhí)行打印
document.getPrintDocument().print();
}
}
java操作word并通過打印機打印
1.本文使用工具類為Jacob 來操作word文檔, 優(yōu)點是功能強大, 直接操作word, 方便控制樣式,缺點是配置復雜,只能用在windows平臺,需要電腦上有wps或office
2.首先下載Jacob壓縮包,將其中的 jacob-1.17-M2-x64.dll 文件放在 %JAVA_HOME%/jre/bin目錄下 ,win7放在System32 目錄下。(如果win7是32位系統(tǒng),則放在 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,其中要填充的數(shù)據(jù)位使用占位符填充,格式為 {{變量名}},此處變量名需要與java中相應的變量名一致
6.在數(shù)據(jù)庫中取出想要的數(shù)據(jù),創(chuàng)建一個相對應的map
/**
* 生成收據(jù)
*/
@GetMapping("/contract")
public AjaxResult Contract() {
String fileName = DateUtils.timechuo() + ".docx"; //根據(jù)模板生成的文件名
String templateFilePath = null;
String printerName = null; //打印機的名字,也可以不指定
//從數(shù)據(jù)庫中查詢訂單信息
/通過你自己的service在數(shù)據(jù)庫中查詢想要的數(shù)據(jù)
for (Object o : jsonArray) { //如果是多條數(shù)據(jù) 使用循環(huán)遍歷 根據(jù)業(yè)務進行修改
JSONObject ob = (JSONObject) o;
String houseid = ob.getString("houseid");
String amount = ob.getString("shouldamount");
String outtradeno = ob.getString("outtradeno");
String houseNo = getHouseNo(houseid);
//創(chuàng)建一個map 將數(shù)據(jù)庫中的數(shù)據(jù)寫進去
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路徑
//調(diào)用接口生成收據(jù)
try {
//可以指定打印機
// insertAndOutFile2(templateFilePath,outFilePath,map,printerName);
//不指定打印機會選擇默認打印機)
insertAndOutFile2(templateFilePath,outFilePath,map);
//修改打印狀態(tài)
ob.put("status",1);
//這里調(diào)用你自己的service修改狀態(tài)就可以了
}catch (Exception e){
System.out.println(e.getMessage());
}
}
return AjaxResult.success();
}
/**
* 生成一個新的收據(jù)
* @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 模板引擎");//添加數(shù)據(jù),鍵是 模板中的{{title}},值在渲染的時候會替換掉對應的標簽
XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //編譯模板,把數(shù)據(jù)塞入模板中,找到對應標簽替換
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 模板引擎");//添加數(shù)據(jù),鍵是 模板中的{{title}},值在渲染的時候會替換掉對應的標簽
XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //編譯模板,把數(shù)據(jù)塞入模板中,找到對應標簽替換
FileOutputStream out = new FileOutputStream(outFilePath);//新建導出文件
template.write(out); //輸出到流
out.flush();
out.close();
template.close();
PrintWordUtiil.printWord(outFilePath);
}
//下邊兩個方法是生成文件夾和命名的 可用可不用
/**
* 以當前日期為名,創(chuàng)建新文件夾
*
* @return
*/
private static String createNewDir() {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
return fmt.format(new Date());
}
/**
* 為文件重新命名,命名規(guī)則為當前系統(tǒng)時間毫秒數(shù)
*
* @return string
*/
private static String getFileNameNew() {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
return fmt.format(new Date());
}
7.打印工具類,核心,需要打印的文件只需要調(diào)用 PrintWordUtil.printWord()方法,傳入相應參數(shù)就可以了
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 == ""){
//如果打印機的名字為空,則默認機器首個打印機
// 創(chuàng)建一個PrinterJob對象
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 設置打印機
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
printerJob.setPrintService(printService);
printerName = printService.getName();
System.out.println("發(fā)現(xiàn)的打印機名名稱為:"+printerName);
}
word.setProperty("ActivePrinter", new Variant(printerName));
// 這里Visible是控制文檔打開后是可見還是不可見,若是靜默打印,那么第三個參數(shù)就設為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("發(fā)現(xiàn)的打印機名名稱為:"+printerName);
printWord(filePath,printerName);
}
}結論
通過以上步驟,你可以輕松地在 Java 應用程序中集成打印功能。利用 Spire.Doc for Java 和 java.awt.print 庫,你可以實現(xiàn)對 Word 文檔的自動打印,提升用戶體驗和工作效率。在開發(fā)過程中,務必確保打印機連接正常,以及文件路徑的正確性,以避免運行時錯誤。
相關文章
SpringBoot自定義HttpMessageConverter操作
這篇文章主要介紹了SpringBoot自定義HttpMessageConverter的操作,具有很好的參考價值,如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08
mybatis配置文件簡介_動力節(jié)點Java學院整理
這篇文章主要為大家詳細介紹了mybatis配置文件簡介的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09
spring-boot-maven-plugin:unknown的完美解決方法
這篇文章主要介紹了spring-boot-maven-plugin:unknown的完美解決方法,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-11-11

