Я использую apache-poi, чтобы выделить предложение в docx. Я написал код внизу, который работает, если в предложении, которое я должен выделить, нет XWPFFieldRun
. XWPFFieldRun
может быть чем-то вроде ссылки на главу или что-то в этом роде.
private void highlightSentence(XWPFParagraph p, String sentence, HighlighterColor color, XWPFDefaultRunStyle defaultRunStyle) {
List<XWPFRun> oldRuns = new ArrayList<>(p.getRuns());
PositionInParagraph pos = new PositionInParagraph();
TextSegement searchText = p.searchText(sentence, pos);
while (searchText != null) {
int beginPosIndex = searchText.getBeginPos().getRun();
int endPosIndex = searchText.getEndPos().getRun();
int offsetRuns = highlightInvolvedRuns(beginPosIndex, endPosIndex, oldRuns, sentence, p, color, defaultRunStyle);
searchText = p.searchText(sentence, new PositionInParagraph(endPosIndex + offsetRuns + 1, 0, 0));
}
}
Если XWPFFieldRun
входит в число прогонов, содержащих предложение, метод searchText
не находит предложение в тексте. Если XWPFFieldRun
находится среди прогонов до предложения, метод возвращает результаты, сдвинутые на единицу, как если бы прогон был меньше. Похоже, что XWPFFieldRun
s не считаются настоящими text-run , поэтому я повторно реализовал метод searchText
, просматривая только текст.
Новый метод находит текст и соответствующие серии, содержащие мое предложение, но когда все сказано и сделано, выделенный документ содержит содержимое XWPFFieldRun
в начале абзаца.
INPUT : Это обычный текст и **** Вот ссылка на главу ****
ВЫХОД : **** Вот ссылка на главу **** Это обычный текст и
Я думаю, что причина этого сдвига в том, что я удаляю / добавляю прогоны в процессе. Вот подфункция, которая делает работу:
private int highlightSubsentence(String sentence, XWPFParagraph p, int i, String hexColor, XWPFDefaultRunStyle defaultRunStyle) {
XWPFRun currentRun = p.getRuns().get(i);
Style currentStyle = new Style(currentRun, defaultRunStyle);
String currentRunText = currentRun.text();
int sentenceLength = sentence.length();
int sentenceBeginIndex = currentRunText.indexOf(sentence);
int offsetRuns = 0;
p.removeRun(i);
if (sentenceBeginIndex > 0) {
XWPFRun before = p.insertNewRun(i);
before.setText(currentRunText.substring(0, sentenceBeginIndex));
currentStyle.copyStyle(before);
offsetRuns++;
}
XWPFRun sentenceRun = p.insertNewRun(i + offsetRuns);
sentenceRun.setText(currentRunText.substring(sentenceBeginIndex, sentenceBeginIndex + sentenceLength));
currentStyle.copyStyle(sentenceRun);
Style.addShading(sentenceRun, hexColor);
if (sentenceBeginIndex + sentenceLength != currentRunText.length()) {
XWPFRun after = p.insertNewRun(i + offsetRuns + 1);
after.setText(currentRunText.substring(sentenceBeginIndex + sentenceLength));
currentStyle.copyStyle(after);
//addedRuns++; this run can be searched again
}
return offsetRuns;
}
Когда я спрашиваю о запуске абзаца, после того, как все добавления и удаления сделаны, я вижу их в правильном порядке.
После того, как файл записи завершен, и я открываю файл, прогоны такие же, как я описал ранее.
Как я могу заставить XWPFFieldRun
воспринимать сдвиг вместо того, чтобы помещать его в начало абзаца?
Спасибо