我想使用Apache POI创建一个包含文本和图片的文档。文本的某些部分必须与图片交叉引用。我尝试遵循此问题的答案,但未成功将addExternalRelationship
方法更改为addRelationship
:
How to create hyperlinks in Apache POI Word?
编辑:下面是我研究以下代码后的尝试:
Generate Inter-Document Hyperlink with Apache POI in Java
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.UnderlinePatterns;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHyperlinkRun;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
public class CrossReference {
public static void main(String[] args) throws InvalidFormatException, FileNotFoundException, IOException {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
document.createParagraph();
document.createParagraph().createRun().addBreak(BreakType.PAGE);
XWPFParagraph pictureParagraph = document.createParagraph();
pictureParagraph.setSpacingAfter(0);
XWPFRun pictureRun = pictureParagraph.createRun();
String imgPath = "img.png";
pictureRun.addPicture(new FileInputStream(imgPath),
XWPFDocument.PICTURE_TYPE_PNG,
imgPath,
Units.toEMU(288),
Units.toEMU(288));
String anchor = "anchor";
XWPFParagraph captionParagraph = document.createParagraph();
XWPFRun captionRun = captionParagraph.createRun();
captionRun.setText("Figure ");
CTBookmark bookmark = captionParagraph.getCTP().addNewBookmarkStart();
bookmark.setName(anchor);
bookmark.setId(BigInteger.valueOf(0));
captionParagraph.createRun().getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
captionParagraph.getCTP().addNewFldSimple().setInstr("SEQ Figure \\* ARABIC");
captionParagraph.createRun().getCTR().addNewFldChar().setFldCharType(STFldCharType.END);
captionParagraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(0));
CTHyperlink ctHyperlink = paragraph.getCTP().addNewHyperlink();
ctHyperlink.setAnchor(anchor);
XWPFHyperlinkRun hyperlinkRun = new XWPFHyperlinkRun(ctHyperlink,
ctHyperlink.addNewR(), paragraph);
hyperlinkRun.setText("Figure 1");
hyperlinkRun.setUnderline(UnderlinePatterns.SINGLE);
FileOutputStream out = new FileOutputStream(new File("test.docx"));
document.write(out);
out.close();
document.close();
}
}
但是,在docx的document.xml中,获得的段落是:
<w:p>
<w:hyperlink w:anchor="anchor">
<w:r>
<w:rPr>
<w:u w:val="single" />
</w:rPr>
<w:t>Figure 1</w:t>
</w:r>
</w:hyperlink>
</w:p>
<w:p />
虽然我期望下面提供类似XML的内容(通过使用LibreOffice Writer手动添加引用来获得)。超链接方法的问题在于它的文本是固定的,如果文档被编辑,它将不会被更新。
<w:p>
<w:pPr>
<w:pStyle w:val="Normal" />
<w:rPr />
</w:pPr>
<w:r>
<w:rPr />
<w:t xml:space="preserve">Figure </w:t>
</w:r>
<w:r>
<w:rPr />
<w:fldChar w:fldCharType="begin" />
</w:r>
<w:r>
<w:rPr />
<w:instrText>REF Ref_Figure0_number_only \h</w:instrText>
</w:r>
<w:r>
<w:rPr />
<w:fldChar w:fldCharType="separate" />
</w:r>
<w:r>
<w:rPr />
<w:t>1</w:t>
</w:r>
<w:r>
<w:rPr />
<w:fldChar w:fldCharType="end" />
</w:r>
</w:p>
答案 0 :(得分:0)
我发现问题的解决方案是通过书签而不是超链接获得的:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
public class CrossReference {
public static void main(String[] args) throws InvalidFormatException, FileNotFoundException, IOException {
XWPFDocument document = new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
document.createParagraph().createRun().addBreak(BreakType.PAGE);
XWPFParagraph pictureParagraph = document.createParagraph();
pictureParagraph.setSpacingAfter(0);
XWPFRun pictureRun = pictureParagraph.createRun();
String imgPath = "img.png";
pictureRun.addPicture(new FileInputStream(imgPath),
XWPFDocument.PICTURE_TYPE_PNG,
imgPath,
Units.toEMU(288),
Units.toEMU(288));
XWPFParagraph captionParagraph = document.createParagraph();
XWPFRun captionRun = captionParagraph.createRun();
captionRun.setText("Figure ");
CTBookmark bookmark = captionParagraph.getCTP().addNewBookmarkStart();
bookmark.setName("Figure-1");
bookmark.setId(BigInteger.valueOf(0));
captionParagraph.createRun().getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
captionParagraph.getCTP().addNewFldSimple().setInstr("SEQ Figure \\* ARABIC");
captionParagraph.createRun().getCTR().addNewFldChar().setFldCharType(STFldCharType.END);
captionParagraph.getCTP().addNewBookmarkEnd().setId(BigInteger.valueOf(0));
paragraph.createRun().setText("Figure ");
paragraph.createRun().getCTR().addNewFldChar().setFldCharType(STFldCharType.BEGIN);
paragraph.createRun().getCTR().addNewInstrText().setStringValue("REF " + bookmark.getName() + " \\h");
paragraph.createRun().getCTR().addNewFldChar().setFldCharType(STFldCharType.END);
FileOutputStream out = new FileOutputStream(new File("test.docx"));
document.write(out);
out.close();
document.close();
}
}