如何用Apache POI提取Word文档中文本框的位置与尺寸?
Apache POI提取Word文本框的位置与尺寸信息
我正尝试使用Apache POI提取Word文档中文本框的位置与尺寸信息。Aspose.Words具备处理文本框及其他形状的方法与类,请问Apache POI是否有类似功能?
我已通过以下代码实现文本框内文本的提取:
XWPFDocument document = new XWPFDocument(OPCPackage.open(fis)); List<XWPFParagraph> paragraphs = document.getParagraphs(); XmlObject[] textBoxObjects; for(XWPFParagraph paragraph : paragraphs) { textBoxObjects = paragraph.getCTP().selectPath( "declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' " + "declare namespace wps='http://schemas.microsoft.com/office/word/2010/wordprocessingShape' " + "declare namespace v='urn:schemas-microsoft-com:vml'"+ ".//*/wps:txbx/w:txbxContent | .//*/v:textbox/w:txbxContent"); // for (int i =0; i < textBoxObjects.length; i++){ XWPFParagraph embeddedPara = null; try { XmlObject[] paraObjects = textBoxObjects[i].selectChildren(new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "p")); for (int j=0; j<paraObjects.length; j++) { embeddedPara = new XWPFParagraph(CTP.Factory.parse(paraObjects[j].xmlText()), paragraph.getBody()); System.out.println(embeddedPara.getText()); } } catch (Exception e) { e.printStackTrace(); } }
但我还需要获取文本框的位置与尺寸信息以推进开发。我注意到Word文档的XML结构中,<wp:anchor>标签包含posOffset位置参数,<wp:extent>标签包含尺寸数据,希望能通过Apache POI提取这些内容,恳请提供可行方案。
可行方案
Apache POI目前没有像Aspose.Words那样封装好的直接获取文本框位置和尺寸的API,但可以通过解析Word的OOXML结构来提取这些信息,具体实现如下:
核心思路
文本框的位置、尺寸信息嵌套在<wp:anchor>标签内,该标签通常位于段落的<w:drawing>节点下。我们可以通过XPath定位到该标签,再提取其中的posOffset(位置)和cx/cy(尺寸)属性值。
示例代码
在原有文本提取逻辑基础上,新增位置与尺寸的提取逻辑:
import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.xmlbeans.XmlObject; import javax.xml.namespace.QName; public class TextBoxInfoExtractor { public static void main(String[] args) throws Exception { OPCPackage opcPackage = OPCPackage.open("your-document.docx"); XWPFDocument document = new XWPFDocument(opcPackage); // 定义OOXML命名空间 String nsDeclare = "declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' " + "declare namespace wp='http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing' " + "declare namespace wps='http://schemas.microsoft.com/office/word/2010/wordprocessingShape' " + "declare namespace v='urn:schemas-microsoft-com:vml'"; for (XWPFParagraph paragraph : document.getParagraphs()) { // 定位所有文本框对应的wp:anchor元素 XmlObject[] anchorNodes = paragraph.getCTP().selectPath(nsDeclare + ".//w:drawing/wp:anchor"); for (XmlObject anchor : anchorNodes) { // 提取水平/垂直位置(posOffset,单位:EMU,1EMU=1/914400英寸) XmlObject posH = anchor.selectPath(nsDeclare + ".//wp:positionH/wp:posOffset")[0]; XmlObject posV = anchor.selectPath(nsDeclare + ".//wp:positionV/wp:posOffset")[0]; long horizontalOffset = Long.parseLong(posH.newCursor().getTextValue()); long verticalOffset = Long.parseLong(posV.newCursor().getTextValue()); // 提取宽高(extent的cx/cy属性,单位:EMU) XmlObject extent = anchor.selectPath(nsDeclare + ".//wp:extent")[0]; long width = Long.parseLong(extent.getAttributeValue(new QName("", "cx"))); long height = Long.parseLong(extent.getAttributeValue(new QName("", "cy"))); // 输出位置与尺寸信息 System.out.println("文本框位置:水平偏移 " + horizontalOffset + " EMU,垂直偏移 " + verticalOffset + " EMU"); System.out.println("文本框尺寸:宽度 " + width + " EMU,高度 " + height + " EMU"); // 提取文本框内文本(复用原有逻辑) XmlObject[] textBoxContents = anchor.selectPath(nsDeclare + ".//wps:txbx/w:txbxContent | .//v:textbox/w:txbxContent"); for (XmlObject content : textBoxContents) { XmlObject[] paraObjects = content.selectChildren(new QName("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "p")); for (XmlObject paraObj : paraObjects) { XWPFParagraph embeddedPara = new XWPFParagraph(CTP.Factory.parse(paraObj.xmlText()), paragraph.getBody()); System.out.println("文本框内容:" + embeddedPara.getText()); } } System.out.println("---------------------------"); } } document.close(); opcPackage.close(); } }
关键说明
- 单位转换:EMU是Office文档的标准单位,转换公式:
- EMU转英寸:
英寸 = EMU / 914400 - EMU转厘米:
厘米 = (EMU * 2.54) / 914400
- EMU转英寸:
- 兼容性:代码同时兼容旧版VML格式和Office 2010+的WPS格式文本框
- 异常处理:实际使用时需添加空值判断,避免因文档结构差异导致空指针异常
内容的提问来源于stack exchange,提问作者vignesh
相关产品推荐
相关产品推荐

