我正在尝试将命名样式应用于XWPFDocument中的各个运行,并且看到奇怪的结果。
javadoc for XWPFRun describes the setStyle method,但是样式出现不会在最终文档中应用。我说出现,是因为在Finder的QuickLook预览中,确实样式会按预期出现在运行中。在下面的示例中,我将命名样式应用于超链接,该样式将按预期显示在右侧的预览中,而不是出现在左侧的Word中。
因此,很明显,POI实际上正在做一些应用样式的操作,但是Word没有呈现样式。我尝试了其他几种.docx阅读器,所有阅读器均产生相似的结果。
因此,我开始剥离样式并将属性分别应用于运行,这在Word中是有效的。这似乎是我必须丢失的东西之一。我可以当然可以编写一个例程,该例程可以读取现有样式并将其应用于这样的运行,但是我宁愿不这样做。我一直在寻找答案,但是POI的这一部分似乎正在处理中。
那么我是否只是想念一些明显的东西,还是只需要把它吸起来并以痛苦的方式来做?
//This does not work.
run.setStyle(styleId);
if(docStyles.styleExist(styleId))
{
/*
In order to set the style on the run, we need to manually
determine the properties of the style, and set them on the
run individually.
This makes no sense.
*/
XWPFStyle style = docStyles.getStyle(styleId);
CTStyle ctStyle = style.getCTStyle();
CTRPr ctRpr = ctStyle.getRPr();
if (ctRpr.isSetB())
{
CTOnOff onOff = ctRpr.getB();
STOnOff.Enum stOnOff = onOff.getVal();
boolean bold = (stOnOff == STOnOff.TRUE);
run.setBold(bold);
}
if(ctRpr.isSetU())
{
CTUnderline underline = ctRpr.getU();
STUnderline.Enum val = underline.getVal();
UnderlinePatterns underlinePattern = UnderlinePatterns.valueOf(val.intValue());
run.setUnderline(underlinePattern);
}
// ... //
}
else
{
System.out.println("404: Style not found");
}
答案 0 :(得分:1)
如果XWPfDocument
是从模板创建的,则此模板必须已经包含命名样式“ Hyperlink”。也就是说,它必须在/word/styles.xml
中包含潜在样式的条目
...
<w:latentStyles...
...
<w:lsdException w:name="Hyperlink" w:qFormat="1"/>
...
以及样式定义
...
<w:style w:type="character" w:styleId="Hyperlink">
<w:name w:val="Hyperlink"/>
<w:basedOn w:val="..."/>
<w:uiPriority w:val="99"/>
<w:unhideWhenUsed/>
<w:qFormat/>
<w:rsid w:val="00072FE4"/>
<w:rPr>
<w:color w:val="0000FF" w:themeColor="hyperlink"/>
<w:u w:val="single"/>
</w:rPr>
</w:style>
...
如果是这样,那么以下代码将使用apache poi 4.0.0
为我工作:
import java.io.FileInputStream;
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
public class CreateWordStyledHyperlinkRunFromTemplate {
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(new FileInputStream("Template.docx"));
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");
XWPFStyles styles = document.getStyles();
if (styles.styleExist("Hyperlink")) {
System.out.println("Style Hyperlink exists."); //Template must contain named style "Hyperlink" already
hyperlinkrun.setStyle("Hyperlink");
} else {
hyperlinkrun.setColor("0000FF");
hyperlinkrun.setUnderline(UnderlinePatterns.SINGLE);
}
run = paragraph.createRun();
run.setText(" in it.");
FileOutputStream out = new FileOutputStream("CreateWordStyledHyperlinkRunFromTemplate.docx");
document.write(out);
out.close();
document.close();
}
}
请注意,除非使用低级org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink
类,否则无法创建XWPFHyperlinkRun。
它产生: