apache 如何为同一段落设置/定义不同的样式

wa7juj8i  于 2023-08-07  发布在  Apache
关注(0)|答案(1)|浏览(156)

我试图转换html文本生成一个单词表。它工作得很好,创建的word文件是正确的,除了字符样式。
这是我第一次尝试使用Apache POI。
到目前为止,我能够检测到新的线()标记(请参阅下面的代码)。但我还想检查一些其他标记,如、,并为每个部分设置正确的运行值。
举例来说:

这是我的文字,现在是斜体,但也在粗体取决于其重要性

我想我应该解析文本,并为每个部分应用不同的运行,但我不知道如何做。

  1. private static XWPFParagraph getTableParagraph(XWPFTableCell cell, String text)
  2. {
  3. int fontsize= 11;
  4. XWPFParagraph paragraph = cell.addParagraph();
  5. cell.removeParagraph(0);
  6. paragraph.setSpacingAfterLines(0);
  7. paragraph.setSpacingAfter(0);
  8. XWPFRun myRun1 = paragraph.createRun();
  9. if (text==null) text="";
  10. else
  11. {
  12. while (true)
  13. {
  14. int x = text.indexOf("<br>");
  15. if (x <0) break;
  16. String work = text.substring(0,x );
  17. text= text.substring(x+4);
  18. myRun1.setText(work);
  19. myRun1.addBreak();
  20. }
  21. }
  22. myRun1.setText(text);
  23. myRun1.setFontSize(fontsize);
  24. return paragraph;
  25. }

字符串

ltskdhd1

ltskdhd11#

在转换HTML文本时,永远不要只使用字符串方法。XMLHTML都是标记语言。它们的内容是标记,而不仅仅是纯文本。需要遍历标记以获取所有单个节点及其含义。这个遍历过程从来都不是微不足道的,因此有专门的库。在这些库的深处也需要使用字符串方法,但这些方法被 Package 成用于遍历标记的有用方法。
对于遍历HTML,例如可以使用jsoup。特别是使用NodeVisitorNodeTraversor对于遍历HTML非常有用。
我的示例创建了一个实现NodeVisitorParagraphNodeVisitor。这个接口请求方法public void head(Node node, int depth),每当NodeTraversor在节点的头部时调用该方法,并且每当NodeTraversor在节点的尾部时调用public void tail(Node node, int depth)。在那些方法中,可以实现用于处理单个节点的过程。在我们的例子中,这个过程的主要部分是我们是否需要一个新的XWPFRun以及这个运行需要什么设置。
范例:

  1. import java.io.FileOutputStream;
  2. import org.apache.poi.xwpf.usermodel.*;
  3. import org.jsoup.Jsoup;
  4. import org.jsoup.nodes.Document;
  5. import org.jsoup.nodes.Node;
  6. import org.jsoup.nodes.TextNode;
  7. import org.jsoup.nodes.Element;
  8. import org.jsoup.select.Elements;
  9. import org.jsoup.select.NodeVisitor;
  10. import org.jsoup.select.NodeTraversor;
  11. public class HTMLtoDOCX {
  12. private XWPFDocument document;
  13. public HTMLtoDOCX(String html, String docxPath) throws Exception {
  14. this.document = new XWPFDocument();
  15. XWPFParagraph paragraph = null;
  16. Document htmlDocument = Jsoup.parse(html);
  17. Elements htmlParagraphs = htmlDocument.select("p");
  18. for(Element htmlParagraph : htmlParagraphs) {
  19. System.out.println(htmlParagraph);
  20. paragraph = document.createParagraph();
  21. createParagraphFromHTML(paragraph, htmlParagraph);
  22. }
  23. FileOutputStream out = new FileOutputStream(docxPath);
  24. document.write(out);
  25. out.close();
  26. document.close();
  27. }
  28. void createParagraphFromHTML(XWPFParagraph paragraph, Element htmlParagraph) {
  29. ParagraphNodeVisitor nodeVisitor = new ParagraphNodeVisitor(paragraph);
  30. NodeTraversor.traverse(nodeVisitor, htmlParagraph);
  31. }
  32. private class ParagraphNodeVisitor implements NodeVisitor {
  33. String nodeName;
  34. boolean needNewRun;
  35. boolean isItalic;
  36. boolean isBold;
  37. boolean isUnderlined;
  38. int fontSize;
  39. String fontColor;
  40. XWPFParagraph paragraph;
  41. XWPFRun run;
  42. ParagraphNodeVisitor(XWPFParagraph paragraph) {
  43. this.paragraph = paragraph;
  44. this.run = paragraph.createRun();
  45. this.nodeName = "";
  46. this.isItalic = false;
  47. this.isBold = false;
  48. this.isUnderlined = false;
  49. this.fontSize = 11;
  50. this.fontColor = "000000";
  51. }
  52. @Override
  53. public void head(Node node, int depth) {
  54. nodeName = node.nodeName();
  55. System.out.println("Start "+nodeName+": " + node);
  56. if ("#text".equals(nodeName)) {
  57. run.setText(((TextNode)node).text());
  58. } else if ("i".equals(nodeName)) {
  59. isItalic = true;
  60. } else if ("b".equals(nodeName)) {
  61. isBold = true;
  62. } else if ("u".equals(nodeName)) {
  63. isUnderlined = true;
  64. } else if ("br".equals(nodeName)) {
  65. run.addBreak();
  66. } else if ("font".equals(nodeName)) {
  67. fontColor = (!"".equals(node.attr("color")))?node.attr("color").substring(1):"000000";
  68. fontSize = (!"".equals(node.attr("size")))?Integer.parseInt(node.attr("size")):11;
  69. }
  70. run.setItalic(isItalic);
  71. run.setBold(isBold);
  72. if (isUnderlined) run.setUnderline(UnderlinePatterns.SINGLE); else run.setUnderline(UnderlinePatterns.NONE);
  73. run.setColor(fontColor); run.setFontSize(fontSize);
  74. }
  75. @Override
  76. public void tail(Node node, int depth) {
  77. nodeName = node.nodeName();
  78. System.out.println("End "+nodeName);
  79. if ("#text".equals(nodeName)) {
  80. run = paragraph.createRun(); //after setting the text in the run a new run is needed
  81. } else if ("i".equals(nodeName)) {
  82. isItalic = false;
  83. } else if ("b".equals(nodeName)) {
  84. isBold = false;
  85. } else if ("u".equals(nodeName)) {
  86. isUnderlined = false;
  87. } else if ("br".equals(nodeName)) {
  88. run = paragraph.createRun(); //after setting a break a new run is needed
  89. } else if ("font".equals(nodeName)) {
  90. fontColor = "000000";
  91. fontSize = 11;
  92. }
  93. run.setItalic(isItalic);
  94. run.setBold(isBold);
  95. if (isUnderlined) run.setUnderline(UnderlinePatterns.SINGLE); else run.setUnderline(UnderlinePatterns.NONE);
  96. run.setColor(fontColor); run.setFontSize(fontSize);
  97. }
  98. }
  99. public static void main(String[] args) throws Exception {
  100. String html =
  101. "<p>Text without tags. <b> Then bold <br/> having break.</b> Then without tags again.</p>"
  102. +"<p><font size='32' color='#0000FF'><b>First paragraph.</font></b><br/>Just like a heading</p>"
  103. +"<p>This is my text <i>which now is in italic <b>but also in bold</b> depending on its <u>importance</u></i>.<br/>Now a <b><i><u>new</u></i></b> line starts <i>within <b>the same</b> paragraph</i>.</p>"
  104. +"<p><b>Last <u>paragraph <i>comes</u> here</b> finally</i>.</p>"
  105. +"<p>But yet <u><i><b>another</i></u></b> paragraph having <i><font size='22' color='#FF0000'>special <u>font</u> settings</font></i>. Now default font again.</p>"
  106. ;
  107. HTMLtoDOCX htmlToDOCX = new HTMLtoDOCX(html, "./CreateWordParagraphFromHTML.docx");
  108. }
  109. }

字符串
测试结果:


的数据
免责声明:这是一个工作草案,显示的原则。它既不是完全准备好的,也不是在生产环境中使用的代码准备好的。

展开查看全部

相关问题