我正在用Apache POI生成XWPFDocument(在此之前从未使用过),并且我想将一个段落链接到同一.docx文档中的另一个段落。是否可以使用POI的本机功能,还是我需要深入研究XML Bean包装器类(例如CTP)来对此进行干扰?还是我不走运?我所看到的有关超链接和POI的每个问题实例都引用了创建外部类型的超链接或Excel工作簿工作表之间的链接的参考。到目前为止,我只能按ctrl键单击完成的文档中的段落来生成“超链接”,并且看起来只是从文档顶部开始进行文本搜索。这是我目前用于实现此目的的代码。提前致谢!
public static void addInternalHyperlink(XWPFParagraph origin, String text, XWPFParagraph target) { if (target != null) { // Create the hyperlink itself CTHyperlink link = origin.getCTP().addNewHyperlink(); link.setAnchor(target.getText()); // Create hyperlink text CTText linkText = CTText.Factory.newInstance(); linkText.setStringValue(text); CTR ctr = CTR.Factory.newInstance(); ctr.setTArray(new CTText[] {linkText}); // Format hyperlink text CTFonts fonts = CTFonts.Factory.newInstance(); fonts.setAscii("Times New Roman"); CTRPr rpr = ctr.addNewRPr(); CTColor color = CTColor.Factory.newInstance(); color.setVal("0000FF"); rpr.setColor(color); CTRPr rpr1 = ctr.addNewRPr(); rpr1.addNewU().setVal(STUnderline.SINGLE); // Insert formatted text into link link.setRArray(new CTR[] {ctr}); } }
请注意,我想将’origin’参数用作包含实际链接的段落,将’text’参数用作链接文本,并将’target’参数用作实际链接目标。
更新:这是一个包含示例段落的XML代码段,我已通过Word GUI将其链接到节标题。
<w:p w14:paraId="5B1C3A0C" w14:textId="659E388D" w:rsidR="00A4419C" w:rsidRDefault="00A4419C" w:rsidP="00A4419C"><w:hyperlink w:anchor="_Another_Heading" w:history="1"><w:r w:rsidRPr="00A4419C"><w:rPr><w:rStyle w:val="Hyperlink"/></w:rPr><w:t>Here is some stuff that could b</w:t></w:r><w:r w:rsidRPr="00A4419C"><w:rPr><w:rStyle w:val="Hyperlink"/></w:rPr><w:t>e</w:t></w:r><w:r w:rsidRPr="00A4419C"><w:rPr><w:rStyle w:val="Hyperlink"/></w:rPr><w:t xml:space="preserve"> the link</w:t></w:r></w:hyperlink></w:p><w:p w14:paraId="19996B78" w14:textId="5C39B081" w:rsidR="00A4419C" w:rsidRPr="00A4419C" w:rsidRDefault="00A4419C" w:rsidP="00A4419C"><w:pPr><w:pStyle w:val="Heading1"/></w:pPr><w:bookmarkStart w:id="0" w:name="_Another_Heading"/><w:bookmarkEnd w:id="0"/><w:r><w:t>Another Heading</w:t></w:r><w:bookmarkStart w:id="1" w:name="_GoBack"/><w:bookmarkEnd w:id="1"/></w:p>
解决方案分为两部分。
首先,我们需要一个XWPFHyperlinkRun目标是文档中的锚点。
XWPFHyperlinkRun
其次,我们需要该目标锚,例如,它可以是文档中的书签。因此,我们需要在文档中创建此类书签。
不幸的是,apache poi到目前为止,仅高级别的类都不支持两者。因此,我们也需要低级类形式ooxml-schemas。
apache poi
ooxml-schemas
以下代码apache poi 4.0.0与ooxml- schemas-1.4结合使用。
apache poi 4.0.0
import java.io.FileOutputStream; import org.apache.poi.xwpf.usermodel.*; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink; import java.math.BigInteger; public class CreateWordHyperlinkBookmark { static XWPFHyperlinkRun createHyperlinkRunToAnchor(XWPFParagraph paragraph, String anchor) throws Exception { CTHyperlink cthyperLink=paragraph.getCTP().addNewHyperlink(); cthyperLink.setAnchor(anchor); cthyperLink.addNewR(); return new XWPFHyperlinkRun( cthyperLink, cthyperLink.getRArray(0), paragraph ); } static XWPFParagraph createBookmarkedParagraph(XWPFDocument document, String anchor, int bookmarkId) { XWPFParagraph paragraph = document.createParagraph(); CTBookmark bookmark = paragraph.getCTP().addNewBookmarkStart(); bookmark.setName(anchor); bookmark.setId(BigInteger.valueOf(bookmarkId)); XWPFRun run = paragraph.createRun(); paragraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(bookmarkId)); return paragraph; } public static void main(String[] args) throws Exception { XWPFDocument document = new XWPFDocument(); String anchor = "hyperlink_target"; int bookmarkId = 0; XWPFParagraph paragraph = document.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText("This is a text paragraph having "); //create hyperlink run XWPFHyperlinkRun hyperlinkrun = createHyperlinkRunToAnchor(paragraph, anchor); hyperlinkrun.setText("a link to an bookmark anchor"); hyperlinkrun.setColor("0000FF"); hyperlinkrun.setUnderline(UnderlinePatterns.SINGLE); run = paragraph.createRun(); run.setText(" in it."); //some empty paragraphs for (int i = 0; i < 10; i++) { paragraph = document.createParagraph(); } //create bookmarked paragraph as the hyperlink target paragraph = createBookmarkedParagraph(document, anchor, bookmarkId++); run = paragraph.getRuns().get(0); run.setText("This is the target."); FileOutputStream out = new FileOutputStream("CreateWordHyperlinkBookmark.docx"); document.write(out); out.close(); document.close(); } }