Java使用Spire.Doc for Java輕松搞定Word文檔打印
在 Java 應(yīng)用程序中實(shí)現(xiàn) Word 文檔的直接打印功能是許多企業(yè)級(jí)應(yīng)用的需求。本文將詳細(xì)介紹如何使用 Spire.Doc for Java 庫(kù)結(jié)合 Java 標(biāo)準(zhǔn)庫(kù)中的 java.awt.print 包,實(shí)現(xiàn)從加載 Word 文檔到指定打印機(jī)打印的完整解決方案。
準(zhǔn)備工作
首先,確保您的項(xiàng)目中已經(jīng)引入了必要的依賴(lài)。Spire.Doc for Java是一個(gè)強(qiáng)大的Word文檔處理庫(kù),支持文檔的創(chuàng)建、編輯、轉(zhuǎn)換和打印。您可以通過(guò)Maven或手動(dòng)下載方式添加該庫(kù)。同時(shí),java.awt.print是Java標(biāo)準(zhǔn)庫(kù)的一部分,無(wú)需額外安裝。
<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>
接下來(lái),確保你的系統(tǒng)可以識(shí)別要使用的打印機(jī),可以通過(guò)打印機(jī)控制面板進(jìn)行測(cè)試。
代碼實(shí)現(xiàn)
以下是一個(gè)完整的示例代碼,展示了如何使用 Java 打印一個(gè) 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)建一個(gè) PrinterJob 對(duì)象,初始與默認(rèn)打印機(jī)關(guān)聯(lián)
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 指定打印機(jī)名稱(chēng)
PrintService myPrintService = findPrintService("\\192.168.1.104\HP LaserJet P1007");
printerJob.setPrintService(myPrintService);
// 創(chuàng)建 PageFormat 實(shí)例,并設(shè)置默認(rèn)大小和方向
PageFormat pageFormat = printerJob.defaultPage();
// 返回與此 PageFormat 相關(guān)的 Paper 對(duì)象的副本
Paper paper = pageFormat.getPaper();
// 設(shè)置 Paper 的可打印區(qū)域
paper.setImageableArea(0, 0, pageFormat.getWidth(), pageFormat.getHeight());
pageFormat.setPaper(paper);
// 創(chuàng)建文檔對(duì)象
Document document = new Document();
// 從文件中加載 Word 文檔
document.loadFromFile("C:\Users\Administrator\Desktop\Input.docx");
// 設(shè)置打印文檔的格式
printerJob.setPrintable(document, pageFormat);
// 執(zhí)行打印操作
try {
printerJob.print();
} catch (PrinterException e) {
e.printStackTrace();
}
}
// 查找打印服務(wù)
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 對(duì)象 :使用
PrinterJob.getPrinterJob()初始化一個(gè)默認(rèn)打印作業(yè)。 - 查找打印服務(wù) :
findPrintService方法循環(huán)遍歷系統(tǒng)中所有的打印服務(wù),并匹配指定的打印機(jī)名稱(chēng)。 - 定義紙張格式 :使用
PageFormat和Paper類(lèi)來(lái)設(shè)置紙張的大小和可打印區(qū)域。 - 加載 Word 文檔 :使用 Spire.Doc 的
Document類(lèi)加載指定路徑的 Word 文檔。 - 打印文檔 :使用
printerJob.print()執(zhí)行打印操作。同時(shí),對(duì)可能拋出的PrinterException進(jìn)行異常處理。
知識(shí)補(bǔ)充
本文介紹如何在Java程序中通過(guò)物理打印機(jī)和虛擬打印機(jī)來(lái)打印Word文檔的方法。文中使用了類(lèi)庫(kù)Spire.Doc for Java,可通過(guò)官網(wǎng)下載jar文件并導(dǎo)入程序或者直接通過(guò)maven倉(cāng)庫(kù)安裝導(dǎo)入。
【示例1】通過(guò)物理打印機(jī)打印
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對(duì)象
PrinterSettings printerSettings = new PrinterSettings();
//指定物理打印機(jī)名稱(chēng)
printerSettings.setPrinterName("\\\\192.168.1.104\\HP LaserJet P1007");
//設(shè)置打印份數(shù)
printerSettings.setCopies((short) 1);
//設(shè)置打印范圍
printerSettings.setFromPage(2);
printerSettings.setToPage(4);
//應(yīng)用打印設(shè)置
document.getPrintDocument().setPrinterSettings(printerSettings);
//執(zhí)行打印
document.getPrintDocument().print();
}
}
【示例2】通過(guò)虛擬打印機(jī)打印
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對(duì)象
PrinterSettings printerSettings = new PrinterSettings();
//指定虛擬打印機(jī)
printerSettings.setPrinterName("Microsoft Print to PDF");
//打印到文檔
printerSettings.setPrintToFile(true);
//指定打印文檔的保存路徑和名稱(chēng)
printerSettings.setPrintFileName("output/PrintToPDF.pdf");
//應(yīng)用打印設(shè)置
document.getPrintDocument().setPrinterSettings(printerSettings);
//執(zhí)行打印
document.getPrintDocument().print();
}
}
java操作word并通過(guò)打印機(jī)打印
1.本文使用工具類(lèi)為Jacob 來(lái)操作word文檔, 優(yōu)點(diǎn)是功能強(qiáng)大, 直接操作word, 方便控制樣式,缺點(diǎn)是配置復(fù)雜,只能用在windows平臺(tái),需要電腦上有wps或office
2.首先下載Jacob壓縮包,將其中的 jacob-1.17-M2-x64.dll 文件放在 %JAVA_HOME%/jre/bin目錄下 ,win7放在System32 目錄下。(如果win7是32位系統(tǒng),則放在 System64目錄下,有點(diǎn)詭異)
3.在項(xiàng)目的resource目錄下新建lib文件夾,將Jacob.jar 放在lib目錄下
4.引入pom依賴(lài)
<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.打開(kāi)要操作的word,其中要填充的數(shù)據(jù)位使用占位符填充,格式為 {{變量名}},此處變量名需要與java中相應(yīng)的變量名一致
6.在數(shù)據(jù)庫(kù)中取出想要的數(shù)據(jù),創(chuàng)建一個(gè)相對(duì)應(yīng)的map
/**
* 生成收據(jù)
*/
@GetMapping("/contract")
public AjaxResult Contract() {
String fileName = DateUtils.timechuo() + ".docx"; //根據(jù)模板生成的文件名
String templateFilePath = null;
String printerName = null; //打印機(jī)的名字,也可以不指定
//從數(shù)據(jù)庫(kù)中查詢(xún)訂單信息
/通過(guò)你自己的service在數(shù)據(jù)庫(kù)中查詢(xún)想要的數(shù)據(jù)
for (Object o : jsonArray) { //如果是多條數(shù)據(jù) 使用循環(huán)遍歷 根據(jù)業(yè)務(wù)進(jìn)行修改
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)建一個(gè)map 將數(shù)據(jù)庫(kù)中的數(shù)據(jù)寫(xiě)進(jìn)去
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 {
//可以指定打印機(jī)
// insertAndOutFile2(templateFilePath,outFilePath,map,printerName);
//不指定打印機(jī)會(huì)選擇默認(rèn)打印機(jī))
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();
}
/**
* 生成一個(gè)新的收據(jù)
* @param templateFilePath word模板文件路徑
* @param outFilePath 填充后輸出文件路徑
* @param map key:word中的占位標(biāo)簽,value對(duì)應(yīng)標(biāo)簽要替換的值。
* @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}},值在渲染的時(shí)候會(huì)替換掉對(duì)應(yīng)的標(biāo)簽
XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //編譯模板,把數(shù)據(jù)塞入模板中,找到對(duì)應(yīng)標(biāo)簽替換
FileOutputStream out = new FileOutputStream(outFilePath);//新建導(dǎo)出文件
template.write(out); //輸出到流
out.flush();
out.close();
template.close();
PrintWordUtiil.printWord(outFilePath,printerName);
}
//重載 不需要傳打印機(jī)名字的方法
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}},值在渲染的時(shí)候會(huì)替換掉對(duì)應(yīng)的標(biāo)簽
XWPFTemplate template = XWPFTemplate.compile(templateFilePath).render(map); //編譯模板,把數(shù)據(jù)塞入模板中,找到對(duì)應(yīng)標(biāo)簽替換
FileOutputStream out = new FileOutputStream(outFilePath);//新建導(dǎo)出文件
template.write(out); //輸出到流
out.flush();
out.close();
template.close();
PrintWordUtiil.printWord(outFilePath);
}
//下邊兩個(gè)方法是生成文件夾和命名的 可用可不用
/**
* 以當(dāng)前日期為名,創(chuàng)建新文件夾
*
* @return
*/
private static String createNewDir() {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMdd");
return fmt.format(new Date());
}
/**
* 為文件重新命名,命名規(guī)則為當(dāng)前系統(tǒng)時(shí)間毫秒數(shù)
*
* @return string
*/
private static String getFileNameNew() {
SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");
return fmt.format(new Date());
}
7.打印工具類(lèi),核心,需要打印的文件只需要調(diào)用 PrintWordUtil.printWord()方法,傳入相應(yīng)參數(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 {
//這個(gè)方法是需要傳打印機(jī)名字的(即指定打印機(jī)) 下邊有個(gè)重載的方法不需要傳打印機(jī)名字
public static void printWord(String filePath,String printerName) throws PrinterException {
// 初始化線程
ComThread.InitSTA();
ActiveXComponent word = new ActiveXComponent("Word.Application");
//設(shè)置打印機(jī)名稱(chēng)
if (printerName == null && printerName == ""){
//如果打印機(jī)的名字為空,則默認(rèn)機(jī)器首個(gè)打印機(jī)
// 創(chuàng)建一個(gè)PrinterJob對(duì)象
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 設(shè)置打印機(jī)
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
printerJob.setPrintService(printService);
printerName = printService.getName();
System.out.println("發(fā)現(xiàn)的打印機(jī)名名稱(chēng)為:"+printerName);
}
word.setProperty("ActivePrinter", new Variant(printerName));
// 這里Visible是控制文檔打開(kāi)后是可見(jiàn)還是不可見(jiàn),若是靜默打印,那么第三個(gè)參數(shù)就設(shè)為false就好了
Dispatch.put(word, "Visible", new Variant(false));
// 獲取文檔屬性
Dispatch document = word.getProperty("Documents").toDispatch();
// 打開(kāi)激活文擋
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文檔關(guān)閉
}
} 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");
//設(shè)置打印機(jī)名稱(chēng)
PrinterJob printerJob = PrinterJob.getPrinterJob();
// 設(shè)置打印機(jī)
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
printerJob.setPrintService(printService);
String printerName = printService.getName();
System.out.println("發(fā)現(xiàn)的打印機(jī)名名稱(chēng)為:"+printerName);
printWord(filePath,printerName);
}
}結(jié)論
通過(guò)以上步驟,你可以輕松地在 Java 應(yīng)用程序中集成打印功能。利用 Spire.Doc for Java 和 java.awt.print 庫(kù),你可以實(shí)現(xiàn)對(duì) Word 文檔的自動(dòng)打印,提升用戶(hù)體驗(yàn)和工作效率。在開(kāi)發(fā)過(guò)程中,務(wù)必確保打印機(jī)連接正常,以及文件路徑的正確性,以避免運(yùn)行時(shí)錯(cuò)誤。
相關(guān)文章
java實(shí)現(xiàn)優(yōu)酷視頻地址解析示例代碼分享
最近做了一個(gè)在線視頻的下載器,需要解析youku的視頻,獲得真正的視頻地址,現(xiàn)在把解析過(guò)程記錄下來(lái)以供參考2014-01-01
解決Spring Boot 在localhost域奇怪的404問(wèn)題(Mac book pro)
這篇文章主要介紹了解決Spring Boot 在localhost域奇怪的404問(wèn)題(Mac book pro),需要的朋友可以參考下2017-09-09
Springboot通過(guò)谷歌Kaptcha?組件生成圖形驗(yàn)證碼功能
Kaptcha是谷歌開(kāi)源的一款簡(jiǎn)單實(shí)用的圖形驗(yàn)證碼組件。我個(gè)人推薦它的最大原因是容易上手,采用約定大于配置的方式,快速契合到項(xiàng)目中,這篇文章主要介紹了Springboot通過(guò)谷歌Kaptcha組件生成圖形驗(yàn)證碼的方法,需要的朋友可以參考下2023-05-05
Java處理圖片實(shí)現(xiàn)base64編碼轉(zhuǎn)換
這篇文章主要介紹了Java處理圖片實(shí)現(xiàn)base64編碼轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
RedisKey的失效監(jiān)聽(tīng)器KeyExpirationEventMessageListener問(wèn)題
這篇文章主要介紹了RedisKey的失效監(jiān)聽(tīng)器KeyExpirationEventMessageListener問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
Spring事務(wù)Transaction配置的五種注入方式詳解
這篇文章主要介紹了Spring事務(wù)Transaction配置的五種注入方式詳解,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04

