[英]Setting a style on an XWPFRun by style ID
I am trying to apply named styles to individual runs in an XWPFDocument, and I am seeing strange results. 我正在尝试将命名样式应用于XWPFDocument中的单个运行,并且看到奇怪的结果。
The javadoc for XWPFRun describes the setStyle method , but the style appears to not be applied in the final document. XWPFRun的javadoc描述了setStyle方法 ,但该样式似乎未在最终文档中应用。 I say appears , because in the QuickLook preview in Finder, the style does appear on the run as expected. 我说出现 ,是因为在Finder中的QuickLook预览中,样式确实按预期出现在运行中。 In the example below, I am applying a named style to the hyperlink, which appears as expected in the preview on the right, but not in Word on the left. 在下面的示例中,我将命名样式应用于超链接,该样式将按预期显示在右侧的预览中,而不是出现在左侧的Word中。
So clearly POI is actually doing something to apply the style, but Word is not rendering the style. 显然,POI实际上正在做一些应用样式的操作,但是Word并未呈现样式。 I tried several other .docx readers, all of which produced similar results. 我尝试了其他几种.docx阅读器,所有阅读器均产生相似的结果。
So I started peeling apart the style and applying the attributes to the run individually, which does work in Word. 因此,我开始剥离样式并将属性分别应用于运行,这在Word中确实有效。 This is one of those things that seems like I must just be missing something. 这似乎是我必须丢失的东西之一。 I can of course write a routine that can read in an existing style and apply it to a run like this, but I would much rather not. 我当然可以编写一个例程,该例程可以读取现有样式并将其应用于这样的运行,但是我宁愿不这样做。 I have searched for answers, but this part of POI seems to be very much a work in progress. 我一直在寻找答案,但是POI的这一部分似乎正在开发中。
So am I just missing something obvious, or am I going to just have to suck it up and do this the painful way? 那么,我只是错过了明显的东西,还是只是不得不吸吮它并以痛苦的方式做到这一点?
//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");
}
If the XWPfDocument
is created from a template, then this template must contain the named style "Hyperlink" already. 如果XWPfDocument
是从模板创建的,则此模板必须已经包含命名样式“ Hyperlink”。 That means, it must contain in /word/styles.xml
the entry in latent styles 这意味着,它必须在/word/styles.xml
包含潜在样式的条目
...
<w:latentStyles...
...
<w:lsdException w:name="Hyperlink" w:qFormat="1"/>
...
as well as the style definition 以及样式定义
...
<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>
...
If that is true then the following code works for me using apache poi 4.0.0
: 如果是这样,那么以下代码将使用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();
}
}
Note there is not any possibility for creating XWPFHyperlinkRun except using the low level org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink
class. 请注意,除了使用较低级别的org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink
类之外,无法创建XWPFHyperlinkRun 。
It produces: 它产生:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.