简体   繁体   中英

How to add a hyperlink to the footer of a XWPFDocument using Apache POI?

The appendExternalHyperlink() method (source) is not working in the footer of a XWPFDocument. In the footer the result is not getting recognised as a hyperlink.

I am new to Apache POI and have no experiences with the low level stuff. Can someone explain what is the problem in here, please?

public class FooterProblem {

  public static void main(final String[] args) throws Exception {

    final XWPFDocument docx = new XWPFDocument();
    final XWPFParagraph para = docx.createParagraph();
    final XWPFRun paraRun = para.createRun();
    paraRun.setText("Email: ");
    appendExternalHyperlink("mailto:me@example.com", "me@example.com", para);

    final XWPFParagraph footer = docx.createFooter(HeaderFooterType.DEFAULT).createParagraph();
    final XWPFRun footerRun = footer.createRun();
    footerRun.setText("Email: ");
    appendExternalHyperlink("mailto:me@example.com", "me@example.com", footer);

    final FileOutputStream out = new FileOutputStream("FooterProblem.docx");
    docx.write(out);
    out.close();
    docx.close();
  }

  public static void appendExternalHyperlink(final String url, final String text, final XWPFParagraph paragraph) {

    // Add the link as External relationship
    final String id = paragraph.getDocument().getPackagePart()
        .addExternalRelationship(url, XWPFRelation.HYPERLINK.getRelation()).getId();

    // Append the link and bind it to the relationship
    final CTHyperlink cLink = paragraph.getCTP().addNewHyperlink();
    cLink.setId(id);

    // Create the linked text
    final CTText ctText = CTText.Factory.newInstance();
    ctText.setStringValue(text);
    final CTR ctr = CTR.Factory.newInstance();
    ctr.setTArray(new CTText[] { ctText });

    // Insert the linked text into the link
    cLink.setRArray(new CTR[] { ctr });
  }
}

The footer[n].xml is its own package part and needs its own relations. But your code creates the external hyperlink relations for the document.xml package part always. It always uses paragraph.getDocument() . This is wrong.

The following code provides a method for creating a XWPFHyperlinkRun in a given XWPFParagraph and gets the correct package part to put the relations on. It uses paragraph.getPart() to get the correct part. So this method works for paragraphs in the document body as well as in header and/or footer.

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.xwpf.usermodel.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;

import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;

public class CreateWordHyperlinks {

 static XWPFHyperlinkRun createHyperlinkRun(XWPFParagraph paragraph, String uri) throws Exception {
  String rId = paragraph.getPart().getPackagePart().addExternalRelationship(
    uri, 
    XWPFRelation.HYPERLINK.getRelation()
   ).getId();

  CTHyperlink cthyperLink=paragraph.getCTP().addNewHyperlink();
  cthyperLink.setId(rId);
  cthyperLink.addNewR();

  return new XWPFHyperlinkRun(
    cthyperLink,
    cthyperLink.getRArray(0),
    paragraph
   );
 }

 public static void main(String[] args) throws Exception {

  XWPFDocument document = new XWPFDocument();

  XWPFParagraph paragraph = document.createParagraph();
  XWPFRun run = paragraph.createRun();
  run.setText("This is a text paragraph having a link to Google ");

  XWPFHyperlinkRun hyperlinkrun = createHyperlinkRun(paragraph, "https://www.google.de");
  hyperlinkrun.setText("https://www.google.de");
  hyperlinkrun.setColor("0000FF");
  hyperlinkrun.setUnderline(UnderlinePatterns.SINGLE);

  run = paragraph.createRun();
  run.setText(" in it.");

  XWPFFooter footer = document.createFooter(HeaderFooterType.DEFAULT);
  paragraph = footer.createParagraph();
  run = paragraph.createRun();
  run.setText("Email: ");

  hyperlinkrun = createHyperlinkRun(paragraph, "mailto:me@example.com");
  hyperlinkrun.setText("me@example.com");
  hyperlinkrun.setColor("0000FF");
  hyperlinkrun.setUnderline(UnderlinePatterns.SINGLE);

  FileOutputStream out = new FileOutputStream("CreateWordHyperlinks.docx");
  document.write(out);
  out.close();
  document.close();

 }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM