import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import core.SysText;
/**
* 特殊字符替换工具类
* @author ws
* @date 2019-06-24
*
*/
public class TszfReplace {
static WebApplicationContext webApplicationContext = null;
static ServletContext servletContext = null;
static Map<String, String> map = null;
static{//获取servlet上下文
//webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
//servletContext = webApplicationContext.getServletContext();
//map = (Map<String, String>)servletContext.getAttribute(SysText.SYS_TSZF_MAP);//取得特殊字符对照表
}
/**
* 替换特殊字符
* @param listmap
* @return
*/
public static List<Map<String, Object>> replaceTSZF(List<Map<String, Object>> listmap){
if(map!=null && map.size()>0){
for(Map<String, Object> mp : listmap){
for(String key : mp.keySet()){
if(mp.get(key) != null && mp.get(key) instanceof String && !StringUtils.isEmpty(mp.get(key).toString())){
String value = mp.get(key).toString();
for(String mkey : map.keySet()){
if(mkey==null || map.get(mkey)==null) continue;
value = value.replace(mkey, map.get(mkey));
//System.out.println(array[j][0]+"-"+array[j][1]);
}
System.out.println(mp.get(key)+":"+value);
if(!mp.get(key).toString().equals(value)){
mp.put(key, value);
}
}
}
}
}
return listmap;
}
/**
* 替换特殊字符
* @param s
* @return
*/
public static String replaceTSZF(String s){
System.out.println(s);
if(!StringUtils.isEmpty(s)){
for(String mkey : map.keySet()){
if(mkey==null || map.get(mkey)==null) continue;
s = s.replace(mkey, map.get(mkey));
}
}
return s;
}
/**
* 替换所有的表格
*
* @param xwpfTableList
* @param params
*/
public static void replaceInTables(List<XWPFTable> xwpfTableList) {
for (XWPFTable table : xwpfTableList) {
replaceInTable(table);
}
}
/**
* 替换一个表格中的所有行
*
* @param xwpfTable
* @param params
*/
public static void replaceInTable(XWPFTable xwpfTable) {
List<XWPFTableRow> rows = xwpfTable.getRows();
replaceInRows(rows);
}
/**
* 替换表格中的一行
*
* @param rows
* @param params
*/
public static void replaceInRows(List<XWPFTableRow> rows) {
for (int i = 0; i < rows.size(); i++) {
XWPFTableRow row = rows.get(i);
replaceInCells(row.getTableCells());
}
}
/**
* 替换一行中所有的单元格
*
* @param xwpfTableCellList
* @param params
*/
public static void replaceInCells(List<XWPFTableCell> xwpfTableCellList) {
for (XWPFTableCell cell : xwpfTableCellList) {
replaceInCell(cell);
}
}
/**
* 替换表格中每一行中的每一个单元格中的所有段落
*
* @param cell
* @param params
*/
public static void replaceInCell(XWPFTableCell cell) {
List<XWPFParagraph> cellParagraphs = cell.getParagraphs();
replaceInAllParagraphs(cellParagraphs);
}
/**
* 替换所有段落中的标记
*
* @param xwpfParagraphList
* @param params
*/
public static void replaceInAllParagraphs(List<XWPFParagraph> xwpfParagraphList) {
for (XWPFParagraph paragraph : xwpfParagraphList) {
if (paragraph.getText() == null || paragraph.getText().equals("")) continue;
System.out.println("paragraph:"+paragraph.getText());
String text = paragraph.getText();
for (String key : map.keySet()) {
if (text.indexOf(key)!=-1) {
System.out.println("包含特殊字符 : ");
text = text.replace(key, map.get(key));
System.out.println("替换后:"+text);
}
}
for (int i = 0;i<paragraph.getRuns().size(); i++){
paragraph.removeRun(i);
}
paragraph.createRun().setText(text);
}
}
/**
* 替换段落中的字符串
*
* @param xwpfParagraph
* @param oldString
* @param newString
*/
public static void replaceInParagraph(XWPFParagraph xwpfParagraph, String oldString, String newString) {
Map<String, Integer> pos_map = findSubRunPosInParagraph(xwpfParagraph, oldString);
if (pos_map != null) {
System.out.println("start_pos:" + pos_map.get("start_pos"));
System.out.println("end_pos:" + pos_map.get("end_pos"));
List<XWPFRun> runs = xwpfParagraph.getRuns();
XWPFRun modelRun = runs.get(pos_map.get("end_pos"));
XWPFRun xwpfRun = xwpfParagraph.insertNewRun(pos_map.get("end_pos") + 1);
xwpfRun.setText(newString);
System.out.println("字体大小:" + modelRun.getFontSize());
if (modelRun.getFontSize() != -1) xwpfRun.setFontSize(modelRun.getFontSize());//默认值是五号字体,但五号字体getFontSize()时,返回-1
xwpfRun.setFontFamily(modelRun.getFontFamily());
for (int i = pos_map.get("end_pos"); i >= pos_map.get("start_pos"); i--) {
System.out.println("remove run pos in :" + i);
xwpfParagraph.removeRun(i);
}
}
}
/**
* 找到段落中子串的起始XWPFRun下标和终止XWPFRun的下标
*
* @param xwpfParagraph
* @param substring
* @return
*/
public static Map<String, Integer> findSubRunPosInParagraph(XWPFParagraph xwpfParagraph, String substring) {
List<XWPFRun> runs = xwpfParagraph.getRuns();
int start_pos = 0;
int end_pos = 0;
String subtemp = "";
for (int i = 0; i < runs.size(); i++) {
subtemp = "";
start_pos = i;
for (int j = i; j < runs.size(); j++) {
if (runs.get(j).getText(runs.get(j).getTextPosition()) == null) continue;
subtemp += runs.get(j).getText(runs.get(j).getTextPosition());
if (subtemp.equals(substring)) {
end_pos = j;
Map<String, Integer> map = new HashMap<>();
map.put("start_pos", start_pos);
map.put("end_pos", end_pos);
return map;
}
}
}
return null;
}
public static void main(String[] args) throws Exception {
String filepathString = "d://222.docx";
String destpathString = "d://2222.docx";
map = new HashMap<String, String>();
map.put("", "\ud835\ude1c");
map.put("", "\ud835\ude1c");
OPCPackage pack = POIXMLDocument.openPackage(filepathString);
XWPFDocument document = new XWPFDocument(pack);
/**
* 对段落中的标记进行替换
*/
List<XWPFParagraph> parasList = document.getParagraphs();
replaceInAllParagraphs(parasList);
/**
* 对表格中的标记进行替换
*/
List<XWPFTable> tables = document.getTables();
replaceInTables(tables);
FileOutputStream outStream = null;
try {
outStream = new FileOutputStream(destpathString);
document.write(outStream);
outStream.flush();
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}