poi中复制段落样式到下一行

博客给出示例代码,主要调用 insertContent 方法插入和上一行样式相同的内容,代码借鉴地址在类上面有标注。

示例代码如下

package com.poi.service;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.poi.xwpf.usermodel.IBody;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlTokenSource;
import org.junit.Test;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPrChange;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTParaRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTParaRPrChange;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPrChange;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrackChange;
import org.w3c.dom.Node;

/**
 * word test
 * @author Administrator
 * 参考地址资料:https://www.jianshu.com/p/de58ab550157
 * POI 排序参考地址 http://www.cnblogs.com/unruly/p/7485645.html
 * 最终参考地址:https://blog.youkuaiyun.com/qq_36331127/article/details/84798301
 * 
 */
public class WordUtilTest {

	
	public static XWPFDocument readDoc() throws IOException {
		//读取word源文件
		FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Administrator\\Desktop\\mergeResult2.docx");
		XWPFDocument document = new XWPFDocument(fileInputStream);
		return document;
	}	
	
	
	@Test
	public void mainTest() {
		
		try {
			XWPFDocument document = readDoc();
			List<String> contents = new ArrayList<String>();
			contents.add("惟沉默是最高的轻蔑。");
			contents.add("大雨倾盆未必湿人梦 日光倾城未必暖人心");
			contents.add("我不怕别的,我就怕你现在放弃的太多,将来有朝一日会后悔。");
			contents.add("我不怕别的,我就怕你现在放弃的太多,将来有朝一日会后悔。");
			
			insertContext(document,contents);
			
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 追加内容到页面
	 * @param document
	 * @throws IOException 
	 */
	public void insertContext(XWPFDocument document, List<String> contents) throws IOException{
		
		// 1. 定位信息到要替换的地方
		XWPFParagraph targetParagraph = null;
		
		List<XWPFParagraph> replaceXwpfParagraph = document.getParagraphs();	
		for (XWPFParagraph xwpfParagraph : replaceXwpfParagraph) {
			
			if(xwpfParagraph.getText().contains("${append}")) {
				
				targetParagraph = xwpfParagraph;
				break;
			}
		} 
		for (String context : contents) {
			
			XmlCursor cursor = targetParagraph.getCTP().newCursor();
			XWPFParagraph insertNewParagraph = document.insertNewParagraph(cursor);
			//XmlCursor xmlCursor = insertNewParagraph.getCTP().newCursor();//获取到段落的光标
			CTPPr oldPPr = getUnLockCTPPR(targetParagraph);
				
			insertNewParagraph.getCTP().setPPr(oldPPr);//把传过来的段落中的ppr标签设置到新的段落里
			List<XWPFRun> runs = targetParagraph.getRuns();//获取run对象
				for (int k=0;k<runs.size();k++) {

					XWPFRun oldRun = runs.get(k);
					CTRPr oldRPr = oldRun.getCTR().getRPr();
					CTRPrChange oldRPrChange = oldRPr.getRPrChange();//run标签里也有rprchange标签也需要像上面一样设置

					if (oldRPrChange!=null) {
						oldRPr.unsetRPrChange();
					}

					XWPFRun newRun = insertNewParagraph.createRun();
					newRun.getCTR().setRPr(oldRPr);
					newRun.setText(context);
					insertNewParagraph.addRun(newRun);
				}
				//xmlCursor.toPrevSibling();
				//insertNewParagraph = document.insertNewParagraph(xmlCursor);//在当前光标处插入新的段落
				//xmlCursor = insertNewParagraph.getCTP().newCursor();
			
		}
		document.removeBodyElement(document.getPosOfParagraph(targetParagraph));
		FileOutputStream fopts = new FileOutputStream("E:/new.docx");
		document.write(fopts);
		fopts.close();
				
	}


	private CTPPr getUnLockCTPPR(XWPFParagraph targetParagraph) {
		CTPPr oldPPr = targetParagraph.getCTP().getPPr();//获取段落对象的样式的ppr标签

		if (oldPPr!=null) {

			CTParaRPr oldPPrRpr = oldPPr.getRPr();//获取ppr标签里的rpr标签
			CTPPrChange oldPPrChange = oldPPr.getPPrChange();//获取pprchange标签

			CTTrackChange rprIns = null;
			CTParaRPrChange oldPraRprChange = null;

			if (oldPPrRpr!=null) {
				rprIns = oldPPrRpr.getIns();//获取ins标签
				oldPraRprChange = oldPPrRpr.getRPrChange();//获取ppr标签中的rpr标签里的rprchange标签
			}

			if (oldPPrChange!=null) {//如果有change标签证明是修订内容,设置为取消修订
				oldPPr.unsetPPrChange();
			}

			if (oldPraRprChange!=null) {
				oldPPrRpr.unsetRPrChange();
			}
			if (rprIns!=null) {//ins标签代表着修订线,如果有修订线则取消修订线
				oldPPrRpr.unsetIns();
			}
		}
		return oldPPr;
	}
	    /*
		if (replaceXwpfParagraph != null) {
			XmlCursor cursor = replaceXwpfParagraph.getCTP().newCursor();
			
			//String replaceStyle = replaceXwpfParagraph.getStyleID();
			
			XWPFParagraph newPara = document.insertNewParagraph(cursor);
			
			// 将上一行样式还原到这一行的replace中
			List<XWPFRun> runs = replaceXwpfParagraph.getRuns();
			
			String context ="时间和习惯,是这个世界上最强大的麻药";
			newPara.setNumID(replaceXwpfParagraph.getNumID());
			XWPFRun newParaRun = newPara.createRun();
			XWPFRun xwpfRunTemp = null;
			// copy 上一行的字体样式
            for (XWPFRun xwpfRun : runs) {
				if(xwpfRun.getText(xwpfRun.getTextPosition())!=null &&
						xwpfRun.getText(xwpfRun.getTextPosition()).contains("${append}")){
					xwpfRunTemp = xwpfRun;
					System.out.println(xwpfRun.getText(xwpfRun.getTextPosition())); 
					System.out.println("华文仿宋" + xwpfRunTemp.isBold() + xwpfRunTemp.getFontFamily() + xwpfRunTemp.getFontSize());
					//break;
				}
			}
            // newParaRun.getCTR().getRPr();
			newParaRun.setText(context);
            newParaRun.setBold(true);
			newParaRun.setFontFamily("华文仿宋");
			newParaRun.setFontSize(10);
			
			document.removeBodyElement(document.getPosOfParagraph(replaceXwpfParagraph));
			FileOutputStream fopts = new FileOutputStream("E:/new.docx");
			document.write(fopts);
			fopts.close();
		}else {
			
			System.out.println("未找到相关的替换内容");
			
		}*/
	
}

本章代码主要是调用到 insertContent 方法来插入和上一行样式相同的内容  代码的借鉴地址类上面有标注。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值