Попытка заменить текст несколькими словами, разбросанными по разным прогонам в абзаце, используя образец, предоставленный @Thierry Bodhuin ниже, однако, он бросает под исключение:Замена текста несколькими словами в Apache POI XWPF не работает - org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
Exception in thread "main" org.apache.xmlbeans.impl.values.XmlValueDisconnectedException
at org.apache.xmlbeans.impl.values.XmlObjectBase.check_orphaned(XmlObjectBase.java:1258)
at org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTRImpl.isSetRsidDel(Unknown Source)
at org.apache.poi.xwpf.usermodel.XWPFParagraph.getText(XWPFParagraph.java:221)
at com.db.a.WordExtractReplaceFormat.replace(WordExtractReplaceFormat.java:60)
at com.db.a.WordExtractReplaceFormat.replace(WordExtractReplaceFormat.java:52)
at com.db.a.WordExtractReplaceFormat.replace(WordExtractReplaceFormat.java:37)
at com.db.a.WordExtractReplaceFormat.main(WordExtractReplaceFormat.java:114)
* фрагмент кода из этого ответа [Replacing a text in Apache POI XWPF на ** Thierry Bodhuin
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
public class WordExtractReplaceFormat {
private static Map<Integer, XWPFRun> getPosToRuns(XWPFParagraph paragraph) {
int pos = 0;
Map<Integer, XWPFRun> map = new HashMap<Integer, XWPFRun>(10);
for (XWPFRun run : paragraph.getRuns()) {
String runText = run.text();
if (runText != null) {
for (int i = 0; i < runText.length(); i++) {
map.put(pos + i, run);
}
pos += runText.length();
}
}
return (map);
}
public static <V> void replace(XWPFDocument document, Map<String, V> map) throws FileNotFoundException, IOException {
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
replace(paragraph, map);
}
String filePath = "C:\\test-1.docx";
saveWord(filePath, document);
}
public static <V> void replace(XWPFDocument document, String searchText, V replacement) {
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
replace(paragraph, searchText, replacement);
}
}
private static <V> void replace(XWPFParagraph paragraph, Map<String, V> map) {
for (Map.Entry<String, V> entry : map.entrySet()) {
replace(paragraph, entry.getKey(), entry.getValue());
}
}
public static <V> void replace(XWPFParagraph paragraph, String searchText, V replacement) {
boolean found = true;
while (found) {
found = false;
int pos = paragraph.getText().indexOf(searchText);
if (pos >= 0) {
found = true;
Map<Integer, XWPFRun> posToRuns = getPosToRuns(paragraph);
XWPFRun run = posToRuns.get(pos);
XWPFRun lastRun = posToRuns.get(pos + searchText.length() - 1);
int runNum = paragraph.getRuns().indexOf(run);
int lastRunNum = paragraph.getRuns().indexOf(lastRun);
String texts[] = replacement.toString().split("\n");
run.setText(texts[0], 0);
XWPFRun newRun = run;
for (int i = 1; i < texts.length; i++) {
newRun.addCarriageReturn();
newRun = paragraph.insertNewRun(runNum + i);
/*
We should copy all style attributes
to the newRun from run
also from background color, ...
Here we duplicate only the simple attributes...
*/
newRun.setText(texts[i]);
newRun.setBold(run.isBold());
newRun.setCapitalized(run.isCapitalized());
// newRun.setCharacterSpacing(run.getCharacterSpacing());
newRun.setColor(run.getColor());
newRun.setDoubleStrikethrough(run.isDoubleStrikeThrough());
newRun.setEmbossed(run.isEmbossed());
newRun.setFontFamily(run.getFontFamily());
newRun.setFontSize(run.getFontSize());
newRun.setImprinted(run.isImprinted());
newRun.setItalic(run.isItalic());
newRun.setKerning(run.getKerning());
newRun.setShadow(run.isShadowed());
newRun.setSmallCaps(run.isSmallCaps());
newRun.setStrikeThrough(run.isStrikeThrough());
newRun.setSubscript(run.getSubscript());
newRun.setUnderline(run.getUnderline());
}
for (int i = lastRunNum + texts.length - 1; i > runNum + texts.length - 1; i--) {
paragraph.removeRun(i);
}
}
}
}
public static void main(String[] args) throws FileNotFoundException, IOException {
XWPFDocument docx;
Map<String, String> keyValue = new TreeMap<>();
keyValue.put("$<[Member] [Manager] [Officer]>", "Member Only");
keyValue.put("${Lawyer_Name}", "Lawyer Name Updated with Actual");
keyValue.put("${Place_Holder_Key}", "Place_Holder_value");
WordExtractReplaceFormat wexrf = new WordExtractReplaceFormat();
docx = new XWPFDocument(new FileInputStream("C:\\test.docx"));
wexrf.replace(docx, keyValue);
}
private static void saveWord(String filePath, XWPFDocument doc) throws FileNotFoundException, IOException{
FileOutputStream out = null;
try{
out = new FileOutputStream(filePath);
doc.write(out);
}
finally{
out.close();
}
}
}
** Код сбой в этой строке - int pos = paragraph.getText(). IndexOf (searchText);
Вы пытаетесь найти и заменить одно слово с предложением (группа слов) или то, что, пожалуйста, объясните, что именно хочешь заменить .И это это одно слово или одно место? –
Если вы просто пытаетесь найти слово и заменить другим (слово или слова) в docx, есть простой подход. –
Требование состоит в том, чтобы найти группу слов (текст) из шаблона и удалить/заменить набор слов и сохранить только соответствующие слова, относящиеся к документу. Пример: searchText = "$ <[Member] [Manager] [Officer]>" replaceText = "Member alone". Примечание. SearchText может содержать более одного места в шаблоне. – RSB