0

How do I make a string bold while it's inside a sentence?

I've just started using Apache POI like 4 hours ago and wanted to:

  1. Locate different strings inside a Word-Document (.docx/XWPF)
  2. Replace the strings with the value of the map
  3. Make the value appear bold, if the string has a special flag.

I tried to first approach this by iterating over the paragraph (not the Runs), but it didn't work. I've got my current solution from this post right here.

Everything is fine with the first two steps, now I want to make every value that contains a special flag (like ${key:bold} or ${score:bold}) bold. I've tried to create a new XWPFRun that writes the bold string, it just won't work with the code underneath...

ParagraphFieldReplacer.java (Currently working for step 1 and 2)

import java.util.List;
import java.util.Map;

import org.apache.poi.ooxml.POIXMLException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

public final class ParagraphFieldReplacer {
    
    public static void replace(final Student student, final XWPFDocument document, final Map<String, FormatObject> fields) {
        final List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (final XWPFParagraph paragraph : paragraphs)
            replaceParagraph(student, paragraph, fields);
    }
    
    private static void replaceParagraph(final Student student, final XWPFParagraph paragraph, final Map<String, FormatObject> fields) throws POIXMLException {
        List<XWPFRun> runs;
        String paragraphtext;
        String runsText;
        XWPFRun nextRun;
        String target;
        XWPFRun run;
        for (final String key : fields.keySet()) {
            paragraphtext = paragraph.getText();
            if (!(paragraphtext.contains("${")))
                return;
            target = "${" + key + "}";
            if (!(paragraphtext.contains(target)))
                continue;
            runs = paragraph.getRuns();
            for (int i = 0; i < runs.size(); i++) {
                run = runs.get(i);
                runsText = run.getText(0);
                if (runsText.contains("${") || (runsText.contains("$") && runs.get(i + 1).getText(0).substring(0, 1).equals("{"))) {
                    while (!(openTagCountIsEqualCloseTagCount(runsText))) {
                        nextRun = runs.get(i + 1);
                        runsText = runsText + nextRun.getText(0);
                        paragraph.removeRun(i + 1);
                    }
                    if (!(runsText.contains(target)))
                        run.setText(runsText, 0);
                    else {
                        final FormatObject format = fields.get(key);
                        final String handle = format.handle(student);
                        run.setText(runsText.replace(target, handle), 0);
                    }
                }
            }
        }
    }
    
    private static boolean openTagCountIsEqualCloseTagCount(final String runText) {
        final int openTagCount = (runText.split("\\$\\{", -1).length - 1);
        final int closeTagCount = (runText.split("}", -1).length - 1);
        return (openTagCount == closeTagCount);
    }
    
}

FormatObject.java

public final class FormatObject {
    
    private boolean bold;
    private FormatHandler<Student, String> handler;
    
    public FormatObject(final FormatHandler<Student, String> handler, final boolean bold) {
        this.handler= handler;
        this.bold = bold;
    }
    
    public boolean isBold() {
        return bold;
    }
    
    public String handle(final ZertifikationsStudent student) {
        return handler.handle(student);
    }
    
}

FormatHandler.java

@FunctionalInterface
public interface FormatHandler<P, R> {
    
    public R handle(P p);
    
}

Thanks for reading/helping!

MomoTheDev
  • 435
  • 1
  • 4
  • 8

1 Answers1

0

I got this working the other day!

The best way to make it bold is to make the format-indicator bold in the document itself.

The other way is to create a new XWPFRun and set it to bold. The text should be the value of the key. After that, you can just add all the fixed XWPFRuns into an ArrayList and re-insert them, after removing every run in the selected paragraph. You can then just remove the old-normal XWPFRun that contains the format-indicator.

MomoTheDev
  • 435
  • 1
  • 4
  • 8