当前位置: 首页 > 知识库问答 >
问题:

使用Java Apache POI从docx文件中更改特定单词的字体样式

颜君浩
2023-03-14

我只是做了类似的事情,在本例中,代码工作,我只想将单词“ipsum”更新为“hello world”:

   File file = new File("document.docx");
   FileInputStream fis = new FileInputStream(file.getAbsolutePath());

   XWPFDocument document = new XWPFDocument(fis);

   List<XWPFParagraph> paragraphs = document.getParagraphs();

    for (XWPFParagraph p: paragraphs) {
        List<XWPFRun> runs = p.getRuns();
        for (XWPFRun r: runs) {
           String endText = r.getText(0).replaceFirst("ipsum" , "hello world");
           r.setText(endText,0);
        }
    }

        document.write(new FileOutputStream(uuid + ".docx"));
        fis.close();
        document.close();

但是如果我试图改变文本样式,比如粗体,甚至改变字体颜色,所有的“运行”都会改变,不仅仅是我搜索的世界。我必须做什么来改变字体样式,只有单词“IPSUM”在示例文本?

共有1个答案

陈畅
2023-03-14

您已经得出结论,文本运行是可能具有文本格式的最低文本实体。因此,需要将一个或多个单词以不同的格式转换成它们自己的文本运行。然后可以格式化这些文本运行。

我已经在将XWPFRun拆分为多个运行中回答了这个问题。但我会为你的特例再出示一次。

具有souce.docx,如下所示:

import java.io.*;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import java.util.*;
import java.awt.Desktop;

public class WordFormatWords {

 static void cloneRunProperties(XWPFRun source, XWPFRun dest) { // clones the underlying w:rPr element
  CTR tRSource = source.getCTR();
  CTRPr rPrSource = tRSource.getRPr();
  if (rPrSource != null) {
   CTRPr rPrDest = (CTRPr)rPrSource.copy();
   CTR tRDest = dest.getCTR();
   tRDest.setRPr(rPrDest);
  }
 }

 static void formatWord(XWPFParagraph paragraph, String keyword, Map<String, String> formats) {
  int runNumber = 0;
  while (runNumber < paragraph.getRuns().size()) { //go through all runs, we cannot use for each since we will possibly insert new runs
   XWPFRun run = paragraph.getRuns().get(runNumber);
   XWPFRun run2 = run;
   String runText = run.getText(0);
   if (runText != null && runText.contains(keyword)) { //if we have a run with keyword in it, then

    char[] runChars = runText.toCharArray(); //split run text into characters
    StringBuffer sb = new StringBuffer();
    for (int charNumber = 0; charNumber < runChars.length; charNumber++) { //go through all characters in that run
     sb.append(runChars[charNumber]); //buffer all characters
     runText = sb.toString();
     if (runText.endsWith(keyword)) { //if the bufferend character stream ends with the keyword  
      //set all chars, which are current buffered, except the keyword, as the text of the actual run
      run.setText(runText.substring(0, runText.length() - keyword.length()), 0); 
      run2 = paragraph.insertNewRun(++runNumber); //insert new run for the formatted keyword
      cloneRunProperties(run, run2); // clone the run properties from original run
      run2.setText(keyword, 0); // set the keyword in run
      for (String toSet : formats.keySet()) { // do the additional formatting
       if ("color".equals(toSet)) {
        run2.setColor(formats.get(toSet));
       } else if ("bold".equals(toSet)) {
        run2.setBold(Boolean.valueOf(formats.get(toSet)));
       }
      }
      run2 = paragraph.insertNewRun(++runNumber); //insert a new run for the next characters
      cloneRunProperties(run, run2); // clone the run properties from original run
      run = run2;
      sb = new StringBuffer(); //empty the buffer
     } 
    }
    run.setText(sb.toString(), 0); //set all characters, which are currently buffered, as the text of the actual run

   }
   runNumber++;
  }
 }


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

  XWPFDocument doc = new XWPFDocument(new FileInputStream("source.docx"));

  String[] keywords = new String[]{"ipsum"};
  Map<String, String> formats = new HashMap<String, String>();
  formats.put("bold", "true");
  formats.put("color", "DC143C");

  for (XWPFParagraph paragraph : doc.getParagraphs()) { //go through all paragraphs
   for (String keyword : keywords) {
    formatWord(paragraph, keyword, formats);
   }
  }

  FileOutputStream out = new FileOutputStream("result.docx");
  doc.write(out);
  out.close();
  doc.close();

  System.out.println("Done");
  Desktop.getDesktop().open(new File("result.docx"));

 }
}
 类似资料:
  • 现在我有一个docx文件,我加载到 我可以看到存储在style中的不同样式的当前字体大小。通过做xml 我想用poi更新字体大小,所以我试了一下 但是,在完成上述代码后,如果我使用第一段代码检查文档的字体大小(object),字体大小仍然是原始值,而不是我想要设置的12。 对于如何解决这个问题,有什么建议吗?

  • 我想读一个文本文件,打印出已知单词前面的单词,比如Java中的xxx。我使用Scanner类用java编写了这段代码。但是这段代码只打印了“xxx”前面的一半单词,而“xxx”前面的一些单词则丢失了。我想知道是什么问题,你能解决这个代码吗。 测试文件包含类似的内容

  • 我试图弄清楚如何更改JTable中一行中单词的颜色。 例如,这是我的句子,在一行中; dmpsrv日志“2013年3月12日星期二15:33:03”(格林尼治标准时间)(DB=SS@2)pid=662node=“B2-W4”执行时间=1(s) 每一行的结构都是相同的,我想用粗体显示用户名。 但是我不知道我该怎么做?有人给点诡计吗? 谢谢

  • 既然Android的XML布局都是矩形的,我怎么能只拥有文本视图的某些部分,这些部分具有不同的字体大小和参数呢? 在下面的示例中,时间(灰色且字体大小较小)总是在文本的末尾。我不知道如何在XML中重现这一点。如果我将两个不同文本视图中的文本分开,并且两者的宽度都是,它将只出现在布局的右侧(在主消息的每一行的右侧,而不是末尾)。 是否可以使用XML进行布局配置,或者我需要使用JAVA以编程方式进行配

  • 在开始之前,我查看了一些解决方案和文档。我似乎不明白为什么我的代码没有按我认为应该的方式工作。我已经扩展了DefaultTableCellRenderer,但我不相信它正在被应用——否则我就把事情搞砸了。 以下是我在发布此问题之前查看过的帖子/网站: Swing-是否可以在JTable单元格中设置特定文本的字体颜色? JTable细胞渲染器 http://docs.oracle.com/javas

  • 当我突出显示div中的特定文本时,如何更改字体。当我从下拉框中选择字体时,下面的代码将更改整个文本的字体。