使用Apache POI操作Word文檔:從入門到實戰

Apache POI是Java生態中最流行的Microsoft Office文檔操作庫之一,它為Word文檔(包括傳統的.doc格式和現代的.docx格式)提供了全面的API支持。本文將詳細介紹如何使用Apache POI創建、讀取和修改Word文檔。

一、Apache POI簡介與環境準備

1. Apache POI組件

Apache POI包含多個組件用于處理不同Office文檔:

  • POI-HWPF:處理.doc格式(Word 97-2003)
  • POI-XWPF:處理.docx格式(Word 2007及以后版本)
  • POI-HSLF:處理PowerPoint
  • POI-HSSF/XSSF:處理Excel

2. 添加Maven依賴

<dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.3</version>
</dependency>
<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version>
</dependency>

3. 核心類介紹

  • XWPFDocument:代表整個Word文檔
  • XWPFParagraph:文檔中的段落
  • XWPFRun:段落中的文本運行(具有相同格式的文本段)
  • XWPFTable:表格
  • XWPFPicture:圖片

二、創建Word文檔

1. 創建簡單文檔

import org.apache.poi.xwpf.usermodel.*;import java.io.FileOutputStream;
import java.io.IOException;public class SimpleDocumentCreator {public static void main(String[] args) throws IOException {// 1. 創建空文檔XWPFDocument document = new XWPFDocument();// 2. 創建段落XWPFParagraph title = document.createParagraph();title.setAlignment(ParagraphAlignment.CENTER);// 3. 創建文本運行并設置樣式XWPFRun titleRun = title.createRun();titleRun.setText("Apache POI示例文檔");titleRun.setBold(true);titleRun.setFontSize(16);// 4. 添加正文段落XWPFParagraph body = document.createParagraph();body.setAlignment(ParagraphAlignment.LEFT);body.setIndentationFirstLine(600); // 首行縮進XWPFRun bodyRun = body.createRun();bodyRun.setText("這是使用Apache POI創建的Word文檔。");bodyRun.addBreak(); // 換行bodyRun.setText("POI支持豐富的文本格式設置。");// 5. 保存文檔try (FileOutputStream out = new FileOutputStream("SimpleDocument.docx")) {document.write(out);}document.close();System.out.println("文檔創建成功!");}
}

2. 添加復雜格式

// 創建帶格式的段落
XWPFParagraph styledPara = document.createParagraph();
styledPara.setAlignment(ParagraphAlignment.BOTH); // 兩端對齊XWPFRun styledRun = styledPara.createRun();
styledRun.setText("格式豐富的文本:");
styledRun.setColor("FF0000"); // 紅色
styledRun.setFontFamily("宋體");
styledRun.addBreak();// 添加不同格式的文本
styledRun = styledPara.createRun();
styledRun.setText("粗體+斜體");
styledRun.setBold(true);
styledRun.setItalic(true);
styledRun.addTab(); // 制表符styledRun = styledPara.createRun();
styledRun.setText("下劃線");
styledRun.setUnderline(UnderlinePatterns.SINGLE);

三、操作表格

1. 創建表格

// 創建3行4列的表格
XWPFTable table = document.createTable(3, 4);// 設置表格寬度
table.setWidth("100%");// 填充表頭
XWPFTableRow headerRow = table.getRow(0);
headerRow.getCell(0).setText("序號");
headerRow.getCell(1).setText("姓名");
headerRow.getCell(2).setText("年齡");
headerRow.getCell(3).setText("部門");// 填充數據
for (int i = 1; i < 3; i++) {XWPFTableRow row = table.getRow(i);row.getCell(0).setText(String.valueOf(i));row.getCell(1).setText("員工" + i);row.getCell(2).setText(String.valueOf(20 + i));row.getCell(3).setText(i % 2 == 0 ? "技術部" : "市場部");
}// 合并單元格
table.getRow(2).getCell(3).setText("備注:所有部門");
table.addNewColSpan(2, 3, 2); // 合并第3行的第3-4列

2. 表格樣式設置

// 設置表格邊框
CTTblPr tblPr = table.getCTTbl().getTblPr();
CTBorder border = tblPr.addNewTblBorders();
border.addNewBottom().setVal(STBorder.SINGLE);
border.addNewTop().setVal(STBorder.SINGLE);
border.addNewLeft().setVal(STBorder.SINGLE);
border.addNewRight().setVal(STBorder.SINGLE);
border.addNewInsideH().setVal(STBorder.SINGLE);
border.addNewInsideV().setVal(STBorder.SINGLE);// 設置表頭背景色
for (XWPFTableCell cell : headerRow.getTableCells()) {cell.setColor("D3D3D3"); // 淺灰色背景
}

四、插入圖片

import org.apache.poi.util.Units;// 從文件插入圖片
try (FileInputStream is = new FileInputStream("logo.png")) {XWPFParagraph imagePara = document.createParagraph();imagePara.setAlignment(ParagraphAlignment.CENTER);XWPFRun imageRun = imagePara.createRun();imageRun.addPicture(is, Document.PICTURE_TYPE_PNG, "logo.png", Units.toEMU(200), // 寬度Units.toEMU(100)); // 高度
}// 從字節數組插入圖片
byte[] imageData = getImageData(); // 獲取圖片字節數組的方法
XWPFRun imageRun = document.createParagraph().createRun();
imageRun.addPicture(new ByteArrayInputStream(imageData),Document.PICTURE_TYPE_JPEG,"photo.jpg",Units.toEMU(150),Units.toEMU(150));

五、讀取和修改現有文檔

1. 讀取文檔內容

public void readDocument(String filePath) throws IOException {try (FileInputStream fis = new FileInputStream(filePath);XWPFDocument document = new XWPFDocument(fis)) {System.out.println("==== 段落 ====");for (XWPFParagraph para : document.getParagraphs()) {System.out.println(para.getText());}System.out.println("\n==== 表格 ====");for (XWPFTable table : document.getTables()) {for (XWPFTableRow row : table.getRows()) {for (XWPFTableCell cell : row.getTableCells()) {System.out.print(cell.getText() + "\t");}System.out.println();}}}
}

2. 修改現有文檔

public void modifyDocument(String inputPath, String outputPath) throws IOException {try (FileInputStream fis = new FileInputStream(inputPath);XWPFDocument document = new XWPFDocument(fis)) {// 修改第一個段落XWPFParagraph firstPara = document.getParagraphs().get(0);if (firstPara != null) {XWPFRun run = firstPara.createRun();run.setText("\n(本文件由系統自動生成)");run.setItalic(true);run.setColor("808080");}// 在文檔末尾添加新內容XWPFParagraph newPara = document.createParagraph();newPara.setAlignment(ParagraphAlignment.RIGHT);XWPFRun newRun = newPara.createRun();newRun.setText("生成時間: " + LocalDate.now());newRun.addBreak(BreakType.PAGE); // 分頁符// 保存修改后的文檔try (FileOutputStream fos = new FileOutputStream(outputPath)) {document.write(fos);}}
}

六、高級功能

1. 頁眉頁腳設置

// 創建頁眉
XWPFHeader header = document.createHeader(HeaderFooterType.DEFAULT);
XWPFParagraph headerPara = header.createParagraph();
headerPara.setAlignment(ParagraphAlignment.RIGHT);
XWPFRun headerRun = headerPara.createRun();
headerRun.setText("公司機密");
headerRun.setColor("FF0000");// 創建頁腳
XWPFFooter footer = document.createFooter(HeaderFooterType.DEFAULT);
XWPFParagraph footerPara = footer.createParagraph();
footerPara.setAlignment(ParagraphAlignment.CENTER);
XWPFRun footerRun = footerPara.createRun();
footerRun.setText("頁碼: ");
footerRun.getCTR().addNewFldSimple().setInstr("PAGE \\* MERGEFORMAT");

2. 目錄生成

// 創建目錄段落
XWPFParagraph tocPara = document.createParagraph();
tocPara.setStyle("TOCHeading");XWPFRun tocRun = tocPara.createRun();
tocRun.setText("目錄");
tocRun.setBold(true);
tocRun.setFontSize(16);
tocRun.addBreak();// 添加目錄字段
tocRun = tocPara.createRun();
tocRun.getCTR().addNewFldSimple().setInstr("TOC \\o \"1-3\" \\h \\z \\u");

3. 批注(注釋)添加

// 在第一個段落添加批注
XWPFParagraph firstPara = document.getParagraphs().get(0);
String commentText = "這是系統自動添加的批注";
String commentAuthor = "AutoSystem";
CTComment ctComment = document.getDocument().getBody().addNewComment();
ctComment.setAuthor(commentAuthor);
ctComment.setDate(new GregorianCalendar());
ctComment.addNewP().addNewR().addNewT().setStringValue(commentText);// 將段落與批注關聯
CTMarkupRange range = firstPara.getCTP().addNewCommentRangeStart();
range.setId(ctComment.getId());
firstPara.getCTP().addNewCommentRangeEnd().setId(ctComment.getId());
firstPara.getCTP().addNewR().addNewCommentReference().setId(ctComment.getId());

七、性能優化與最佳實踐

1. 大文件處理優化

對于大文檔,建議使用事件模型(XWPFEventAPI)而非DOM模型:

import org.apache.poi.xwpf.eventusermodel.*;public class LargeDocumentReader {public static void main(String[] args) throws Exception {OPCPackage pkg = OPCPackage.open("large.docx");XWPFEventBasedParser parser = new XWPFEventBasedParser();parser.parse(pkg, new XWPFVisitor() {@Overridepublic void visitParagraph(XWPFParagraph paragraph) {System.out.println("段落: " + paragraph.getText());}@Overridepublic void visitTable(XWPFTable table) {System.out.println("發現表格");}});pkg.close();}
}

2. 內存管理

  • 及時關閉文檔對象和流
  • 對于批量處理,考慮復用XWPFDocument對象
  • 使用try-with-resources確保資源釋放

3. 樣式重用

// 創建并重用樣式
CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
CTPageSz pageSz = sectPr.addNewPgSz();
pageSz.setW(BigInteger.valueOf(12240)); // A4寬度
pageSz.setH(BigInteger.valueOf(15840)); // A4高度// 創建段落樣式
CTStyle ctStyle = CTStyle.Factory.newInstance();
ctStyle.setStyleId("MyStyle");
CTPPr pPr = ctStyle.addNewPPr();
pPr.addNewSpacing().setAfter(BigInteger.valueOf(200)); // 段后間距
document.getStyle().addStyle(ctStyle);// 應用樣式
XWPFParagraph para = document.createParagraph();
para.setStyle("MyStyle");

八、常見問題與解決方案

1. 中文亂碼問題

確保使用支持中文的字體:

run.setFontFamily("宋體");

或者在文檔級別設置默認字體:

document.getStyles().setDefaultFonts("宋體", null);

2. 格式不兼容問題

  • 盡量使用.docx格式而非.doc格式
  • 避免使用太新的Office特性
  • 在生成文檔后進行兼容性測試

3. 性能問題

  • 對于大文檔,分批次處理內容
  • 避免頻繁創建/銷毀XWPFRun對象
  • 考慮緩存常用樣式

九、總結

Apache POI提供了強大而靈活的API來操作Word文檔,從簡單的文本生成到復雜的格式設置、表格處理和圖片插入都能勝任。通過本文的介紹,您應該已經掌握了:

  1. 基本的文檔創建與保存
  2. 文本格式設置與段落控制
  3. 表格的創建與樣式設置
  4. 圖片插入方法
  5. 現有文檔的讀取與修改
  6. 高級功能如頁眉頁腳、目錄生成
  7. 性能優化技巧

在實際項目中,建議根據具體需求選擇合適的API,并注意資源管理和性能優化。對于更復雜的需求,可以結合模板引擎或考慮商業解決方案。

Apache POI的官方文檔和社區資源豐富,遇到問題時可以查閱:

  • 官方文檔:https://poi.apache.org/
  • API文檔:https://poi.apache.org/apidocs/index.html
  • 示例代碼:https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/examples/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/84796.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/84796.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/84796.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CentOS 7.3環境中部署Kerberos集群

CentOS 7.3環境中部署Kerberos集群 文章目錄 CentOS 7.3環境中部署Kerberos集群環境安裝服務包 Kerberos MS 規劃安裝 KDC Master Server配置文件/etc/krb5.conf/var/kerberos/krb5kdc/kdc.conf/var/kerberos/krb5kdc/kadm5.acl 創建Kerberos數據庫啟動與停止服務創建管理員創建…

1 Studying《Arm A715 Software Optimization Guide》

目錄 1 Introduction 1.1 Product revision status 1.2 Intended audience 1.3 Scope 1.4 Conventions 1.5 Useful resources 2 Overview 2.1 Pipeline overview 3 Instruction characteristics 3.1 Instruction tables 3.2 Legend for reading the utilized pipeli…

第二十四章 24.QoS(CCNA)

第二十四章 24.QoS(CCNA) 介紹了switch QoS的配置方法 注釋&#xff1a; 學習資源是B站的CCNA by Sean_Ning CCNA 最新CCNA 200-301 視頻教程(含免費實驗環境&#xff09; PS&#xff1a;喜歡的可以去買下他的課程&#xff0c;不貴&#xff0c;講的很細 To be continued……

什么是穩定幣?

穩定幣&#xff08;Stablecoin&#xff09;是一種特殊的加密貨幣&#xff0c;其核心目標是維持價格穩定&#xff0c;通常與某種穩定資產&#xff08;如美元、黃金等&#xff09;掛鉤。 一、為什么需要穩定幣&#xff1f; 普通加密貨幣&#xff08;如比特幣、以太坊&#xff09…

伺服學習(IS620N)

DI 端子的基本概念 DI 端子是伺服驅動器上的數字輸入接口&#xff0c;用于接收外部開關、按鈕或PLC的24V/0V信號。每個端子的功能可通過參數靈活配置&#xff08;如啟停、限位等&#xff09;。 核心要點 功能設置&#xff1a;通過驅動器參數組&#xff08;如H03&#xff09;…

基于Python的氣象數據分析及可視化研究

目錄 一.&#x1f981;前言二.&#x1f981;開源代碼與組件使用情況說明三.&#x1f981;核心功能1. ?算法設計2. ?PyEcharts庫3. ?Flask框架4. ?爬蟲5. ?部署項目 四.&#x1f981;演示效果1. 管理員模塊1.1 用戶管理 2. 用戶模塊2.1 登錄系統2.2 查看實時數據2.3 查看天…

Excel處理控件Aspose.Cells教程:使用 C# 在 Excel 中應用數據驗證

Excel 中的數據驗證可確保用戶在工作表中僅輸入有效數據。在設計表單、收集數據或構建財務模型時&#xff0c;數據驗證有助于維護結構并最大限度地減少用戶錯誤。在本文中&#xff0c;我們將向您展示如何使用 C# 以編程方式在 Excel 中應用數據驗證。 Aspose.Cells 最新版下載…

AI應用:計算機視覺相關技術總結

計算機視覺概述 計算機視覺&#xff08;Computer Vision, CV&#xff09;是一門讓計算機從圖像或視頻中 “理解” 和 “解釋” 視覺信息的技術&#xff0c;涉及多學科交叉&#xff08;如數學、統計學、機器學習、信號處理等&#xff09;。以下從技術體系、核心任務、關鍵技術、…

人口販賣暑期威脅消解:算法協同提升安全預警

隨著暑期的到來&#xff0c;人員流動加劇&#xff0c;人口販賣等惡性犯罪活動進入高發階段&#xff0c;景區、車站、商場等公共場所成為潛在風險區域。傳統安防手段在應對此類隱蔽性強、危害性大的犯罪時顯得力不從心。為此&#xff0c;引入基于視覺分析的多維度算法技術&#…

【DSP筆記 · 第3章】數字世界的“棱鏡”:離散傅里葉變換(DFT)完全解析

數字世界的“棱鏡”&#xff1a;離散傅里葉變換&#xff08;DFT&#xff09;完全解析 在上一章&#xff0c;我們探索了Z變換和離散時間傅里葉變換&#xff08;DTFT&#xff09;。我們知道&#xff0c;DTFT是一個無比強大的理論工具&#xff0c;它能將一個時域離散序列的“基因…

卷積神經網絡的參數量及尺度變化計算

文章目錄 前言1.卷積2.參數量的計算2.1案例一2.2案例二 3.奇怪的優化思想3.1使用小核卷積替換大核卷積3.2卷積核11的應用 4.輸出圖像尺寸的計算4.1Same convolution4.2具體計算規則4.3轉置卷積 小結 前言 本篇博客主要介紹卷積基本概念&#xff0c;卷積神經網絡的參數量計算、…

OpenCV——圖像平滑

圖像平滑 一、圖像的噪聲1.1、噪聲來源1.2、噪聲類型1.3、噪聲模擬 二、濾波器三、線性濾波3.1、均值濾波3.2、方框濾波3.3、高斯濾波 四、非線性濾波4.1、中值濾波4.2、雙邊濾波 圖像在采集和傳輸過程中容易受到各種因素的影響而產生噪聲&#xff0c;而噪聲會對圖像的正確解讀…

鴻蒙系統備份恢復

鴻蒙系統嘗試者&#xff0c;在純血鴻蒙與鴻蒙4.2/4.3之前反復橫跳&#xff0c;中間折騰… 目錄 鴻蒙4.2/4.3升級鴻蒙5.0系統備份 鴻蒙5.0回退鴻蒙4.2/4.3系統備份備份恢復 華為手機助手注意 鴻蒙4.2/4.3升級鴻蒙5.0 系統備份 云空間備份手機本地備份華為手機助手備份 鴻蒙5.…

JS進階 Day03

1.兩種面向編程思想 2.構造函數實現封裝以及存在的問題 下面就引出了原型對象 3.原型對象prototype 共享原理圖&#xff1a; 4.數組擴展案例-求最大值和數組求和 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><…

visual studio小番茄插件某些快捷鍵失效

問題 AltO 切換頭文件和源文件失效。 背景 最近升級了 visual studio&#xff0c;多了一些插件 原因 Alt O 快捷鍵被其他插件占用了 解決方案 工具 → 選項 → 環境 → 鍵盤 搜索這個 VAssistX.OpenCorrespondingFile&#xff08;切換頭/源文件&#xff09; 發現命令的快…

基于單片機的PT100溫度變送器設計

基于單片機的PT100溫度變送器設計 文章目錄 基于單片機的PT100溫度變送器設計前言一、資源分享二、系統框架三、硬件準備1.主控制器2、PT100溫度傳感器3、顯示屏4、WIFI模塊5、USB轉RS485模塊6、SP3485EN7、K11-11D3 四、設計PCB1、安裝下載立創EDA專業版2、畫原理圖3、擺放元器…

Git 清理指南:如何從版本庫中移除誤提交的文件(保留本地文件)

場景 在 Git 項目中&#xff0c;我們可能會不小心提交了本應忽略的文件&#xff08;如 node_modules/、.env、*.log 等&#xff09;&#xff0c;導致倉庫體積膨脹或敏感信息泄露。本文介紹如何從 Git 歷史中徹底刪除這些文件&#xff0c;同時保留本地文件。 解決方案 1. 確認…

服務器數據恢復—重裝系統導致XFS文件系統分區無法訪問的數據恢復案例

服務器數據恢復環境&故障&#xff1a; 一臺服務器上通過磁盤柜RAID卡組建的riad5磁盤陣列&#xff0c;服務器上層安裝Linux操作系統&#xff0c;搭建XFS文件系統。服務器上層分配一個LUN&#xff0c;并劃分了兩個分區。通過LVM擴容的方式將sdc1分區加入到了root_lv中&#…

在QtCreator中使用GitHubCopilot

文章目錄 1.github copilot賬號2. 安裝node.js3.安裝 GitHub Copilot Neovim plugin4.在Qt中啟用4.1.在extension中啟用4.2.在配置中啟用4.3.使用/禁用 5.評價 在最新版的QtCreator中&#xff0c;已經通過Extension集成了GitHubCopilot進來。 我用的是16.0.2版本的&#xff08;…

島嶼周長問題的三種解法:直接計數法、數學計算法與深度優先搜索

問題描述 給定一個二維網格 grid&#xff0c;其中1表示陸地&#xff0c;0表示水域。網格中的格子水平和垂直方向相連&#xff08;對角線不相連&#xff09;。網格中恰好有一個島嶼&#xff08;即一個或多個相連的陸地格子&#xff09;&#xff0c;需要計算這個島嶼的周長。 解…