2 回答

TA貢獻1804條經(jīng)驗 獲得超3個贊
如果您查看屏幕截圖,您會在 MiddleName、Vehicle_Type 和 Reg_No 下看到紅色波浪線。這意味著,它Word
檢測到這里可能存在拼寫問題。這也存儲在文件中,這就是為什么文本 [MIddleName]、[Vehicle_Type] 和 [Reg_No] 沒有與它們周圍的括號一起出現(xiàn)在一個文本行中。括號在他們自己的文本運行中,并且文本與可能的拼寫問題一起標記。
這是一個眾所周知的問題,一些圖書館已經(jīng)嘗試通過比僅在文本運行中搜索它們更復(fù)雜的方式檢測文本變量來解決這個問題。例如有templ4docx。
但我更喜歡的方式是另一種。Word
長期以來提供使用文本表單字段。請參閱使用表單域。請注意,這里指的是遺留表單字段,而不是 ActiveX 表單字段。
有關(guān)示例,請參閱替換 .docx 中的文本模板(Apache POI、Docx4j 或其他)。
您的案例的修改示例:
Word模板.docx:
所有灰色字段都是從開發(fā)人員選項卡插入的遺留文本表單字段。它們Text Form Field Options的Bookmark:名稱是Text1, Text2, ... 并且根據(jù)需要設(shè)置默認文本。
代碼:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.SimpleValue;
import javax.xml.namespace.QName;
public class WordReplaceTextInFormFields {
private static void replaceFormFieldText(XWPFDocument document, String ffname, String text) {
boolean foundformfield = false;
for (XWPFParagraph paragraph : document.getParagraphs()) {
for (XWPFRun run : paragraph.getRuns()) {
XmlCursor cursor = run.getCTR().newCursor();
cursor.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:fldChar/@w:fldCharType");
while(cursor.hasNextSelection()) {
cursor.toNextSelection();
XmlObject obj = cursor.getObject();
if ("begin".equals(((SimpleValue)obj).getStringValue())) {
cursor.toParent();
obj = cursor.getObject();
obj = obj.selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:ffData/w:name/@w:val")[0];
if (ffname.equals(((SimpleValue)obj).getStringValue())) {
foundformfield = true;
} else {
foundformfield = false;
}
} else if ("end".equals(((SimpleValue)obj).getStringValue())) {
if (foundformfield) return;
foundformfield = false;
}
}
if (foundformfield && run.getCTR().getTList().size() > 0) {
run.getCTR().getTList().get(0).setStringValue(text);
foundformfield = false;
//System.out.println(run.getCTR());
}
}
}
}
public static void main(String[] args) throws Exception {
XWPFDocument document = new XWPFDocument(new FileInputStream("WordTemplate.docx"));
replaceFormFieldText(document, "Text1", "Mrs.");
replaceFormFieldText(document, "Text2", "Janis");
replaceFormFieldText(document, "Text3", "Lyn");
replaceFormFieldText(document, "Text4", "Joplin");
replaceFormFieldText(document, "Text5", "Mercedes Benz");
replaceFormFieldText(document, "Text6", "1234-56-789");
replaceFormFieldText(document, "Text7", "Stuttgart");
FileOutputStream out = new FileOutputStream("WordReplaceTextInFormFields.docx");
document.write(out);
out.close();
document.close();
}
}
此代碼使用并需要FAQ-N10025中提到apache poi 4.1.0的所有模式的完整 jar 進行測試。ooxml-schemas-1.4.jar
結(jié)果:
請注意,文本字段的灰色背景僅在GUI
. 默認情況下不會打印出來。
優(yōu)點:
表單域內(nèi)容只能整體格式化。所以表單字段內(nèi)容永遠不會撕裂。
文檔可以受到保護,因此只能填寫表單字段。然后模板也可以用作表單Word
GUI
。

TA貢獻1806條經(jīng)驗 獲得超5個贊
如果您正在尋找一種超級快速修復(fù)來防止將文本拆分為多個運行,以便它可以被 java 程序識別/讀取,請執(zhí)行以下操作:
在一次運行中復(fù)制您想要的文本
將其粘貼到記事本中(刪除所有 docx 格式)
將該文本復(fù)制并粘貼到word文檔中,點擊保存。
現(xiàn)在它將作為一次運行插入。
添加回答
舉報