docx4j根据关键字添加指定批注

/**
     * is:文件输入流 filename:文件名 map:关键字和批注键值对
     */
    
        @Override
	public String docx4jHandler(FileInputStream is,String fileName,HashMap map,SessionDto sessionDto) throws Exception {
		long a = System.currentTimeMillis();
		String upload_path = ConfigManager.getConfigValue("upload_path");
		//读取word
//		WordprocessingMLPackage wordMLPackage = Docx4jHandlerUtil.getTemplate(upload_path + File.separator + filePath);
		WordprocessingMLPackage wordMLPackage = Docx4jHandlerUtil.getTemplate(is);
		MainDocumentPart mp = wordMLPackage.getMainDocumentPart();
		ObjectFactory factory = Context.getWmlObjectFactory();
		List<Object> objList = wordMLPackage.getMainDocumentPart().getContent();
		BigInteger commentId = BigInteger.valueOf(1);
		//文字样式
		RPr fontRPr = new RPr();
		// 批注样式
		RPr commentRPr = Docx4jHandlerUtil.getRPrStyle(factory, "微软雅黑", "41A62D", "18",
				STHint.EAST_ASIA, false, false, false, false, null, null,
				false, null, false, null, null, null);
		Comments comments = Docx4jHandlerUtil.addDocumentCommentsPart(wordMLPackage, factory);
		
		//循环段落
		int objSize = objList.size();
		for (int i = 0, len = objSize; i < len; i++) {
			if (objList.get(i) instanceof P) {
				P p = (P) objList.get(i);
				if(map.size()>0){
					commentId = Docx4jHandlerUtil.createComment(wordMLPackage, mp, factory, p,
							commentId, fontRPr, commentRPr, comments, map);
				}
			}
		}
		//保存文档
		String filePath = UUID.randomUUID().toString() + "_analysisWord";
		String fileUrl = upload_path + File.separator + filePath ;
		Docx4jHandlerUtil.writeDocxToStream(wordMLPackage, fileUrl);
		long b = System.currentTimeMillis();
		System.out.println("添加批注耗时共" + (b - a) / 1000 + "秒 ");
		this.saveFileInDB(fileName, filePath, fileUrl,sessionDto);
		System.gc();
		return filePath;
	};
package com.daorigin.contAnalysis;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;

import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.CommentsPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.BooleanDefaultTrue;
import org.docx4j.wml.CTShd;
import org.docx4j.wml.CTVerticalAlignRun;
import org.docx4j.wml.Color;
import org.docx4j.wml.CommentRangeEnd;
import org.docx4j.wml.CommentRangeStart;
import org.docx4j.wml.Comments;
import org.docx4j.wml.Highlight;
import org.docx4j.wml.HpsMeasure;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.RFonts;
import org.docx4j.wml.RPr;
import org.docx4j.wml.STHint;
import org.docx4j.wml.STShd;
import org.docx4j.wml.Text;
import org.docx4j.wml.U;
import org.docx4j.wml.UnderlineEnumeration;
import org.docx4j.wml.Comments.Comment;

public class Docx4jHandlerUtil {
	
	private static R r_normal;
	private static Text t_normal;
	private static R r_key;
	private static Text t_key;
	private static CommentRangeStart startComment;
	private static CommentRangeEnd endComment;
	private static Comment comment;
	private static BigInteger index = BigInteger.valueOf(1);
	
	public static BigInteger createComment(WordprocessingMLPackage wordMLPackage,
			MainDocumentPart t, ObjectFactory factory, P p,
			BigInteger commentId, RPr fontRPr, RPr commentRPr,
			Comments comments, HashMap map) throws Exception {
		//String split = "";
		StringBuffer splitBuffer = new StringBuffer("");
		// 防止段落最后是关键字,分割后造成关键字丢失
		String paragraph = p.toString() + "尾部填充字";
		// 遍历得到key
		for (Iterator iter = map.entrySet().iterator(); iter.hasNext();) {
			Map.Entry element = (Map.Entry) iter.next();
			//split += element.getKey() + "|";
			splitBuffer.append(element.getKey() + "|");
			// 防止整个段落都是关键字
			paragraph = paragraph.replaceAll(element.getKey().toString(),
					"头部填充字" + element.getKey().toString());
		}
		//split = split.substring(0, split.length() - 1);
		splitBuffer.deleteCharAt(splitBuffer.length() - 1);
		//BigInteger index = BigInteger.valueOf(1);

		// 得到原文本段落样式(若段落中存在多种不同样式会有问题)
		List<Object> pContent = p.getContent();
		int pContentSize = pContent.size();
		for (int i = 0, len = pContentSize; i < len; i++) {
			if (pContent.get(i) instanceof R) {
				R r = (R) pContent.get(i);
				fontRPr = r.getRPr();
			}
		}

		// 以关键字分割段落
		String[] paragraphArr = paragraph.split(splitBuffer.toString());
		if (paragraphArr != null && paragraphArr.length > 1) {
			p.getContent().clear();
			index = createCommentRound(factory, p, fontRPr, commentRPr,
					commentId, comments, paragraphArr, paragraph, map);
		}
		return index;
	}

	// 创建批注(选定范围)
	public static BigInteger createCommentRound(ObjectFactory factory, P p,
			RPr fontRPr, RPr commentRPr, BigInteger commentId,
			Comments comments, String[] paragraphArr, String pStr, HashMap map)
			throws Exception {
		for (int i = 0; i < paragraphArr.length; i++) {
			if (i == paragraphArr.length - 1) {
				paragraphArr[i] = paragraphArr[i].replaceAll("尾部填充字", "");
			}
//			R run = factory.createR();
//			Text txt = factory.createText();
//			txt.setValue(paragraphArr[i].replaceAll("头部填充字", ""));
//			run.getContent().add(txt);
//			run.setRPr(fontRPr);
//			p.getContent().add(run);
			r_normal = factory.createR();
			t_normal = factory.createText();
			t_normal.setValue(paragraphArr[i].replaceAll("头部填充字", ""));
			r_normal.getContent().add(t_normal);
			r_normal.setRPr(fontRPr);
			p.getContent().add(r_normal);

			// 最后一个分割字符串,后续肯定没有批注。
			if (i < paragraphArr.length - 1) {
				pStr = pStr.substring(pStr.indexOf(paragraphArr[i])
						+ paragraphArr[i].length());
				String key = pStr.substring(0,
						pStr.indexOf(paragraphArr[i + 1]));
				pStr = pStr.substring(pStr.indexOf(key) + key.length());
				
				if(map.get(key) == null){  //说明本段文字之前已有此关键字
					//批注文字
//					R run1 = factory.createR();
//					Text txt1 = factory.createText();
//					txt1.setValue(key);
//					run1.getContent().add(txt1);
//					run1.setRPr(fontRPr);
//					p.getContent().add(run1);
					
					r_key = factory.createR();
					t_key = factory.createText();
					t_key.setValue(key);
					r_key.getContent().add(t_key);
					r_key.setRPr(fontRPr);
					p.getContent().add(r_key);
				}else{
					//批注文字开始位
//					CommentRangeStart startComment = factory
//							.createCommentRangeStart();
					startComment = factory
							.createCommentRangeStart();
					startComment.setId(commentId);
					p.getContent().add(startComment);
					
					//批注文字
//					R run1 = factory.createR();
//					Text txt1 = factory.createText();
//					txt1.setValue(key);
//					run1.getContent().add(txt1);
//					run1.setRPr(fontRPr);
//					p.getContent().add(run1);
					r_key = factory.createR();
					t_key = factory.createText();
					t_key.setValue(key);
					r_key.getContent().add(t_key);
					r_key.setRPr(fontRPr);
					p.getContent().add(r_key);
					
					//批注文字结束位
//					CommentRangeEnd endComment = factory.createCommentRangeEnd();
					endComment = factory.createCommentRangeEnd();
					endComment.setId(commentId);
					p.getContent().add(endComment);
					
					//添加批注
//					Comment commentOne = createComment(factory, commentId, "合同小精灵",
//							new Date(), map.get(key).toString(), commentRPr);
					comment = createComment(factory, commentId, "合同小精灵",
							new Date(), map.get(key).toString(), commentRPr);
					comments.getComment().add(comment);
					p.getContent().add(
							createRunCommentReference(factory, commentId));
					commentId = commentId.add(BigInteger.ONE);
					map.remove(key);
				}
			}

		}
		return commentId;
	}

	public static WordprocessingMLPackage getTemplate(FileInputStream is)
			throws Docx4JException, FileNotFoundException {
		WordprocessingMLPackage template = WordprocessingMLPackage
				.load(is);
		return template;
	}

	// 字体样式
	public static RPr getRPrStyle(ObjectFactory factory, String fontFamily,
			String colorVal, String fontSize, STHint sTHint, boolean isBlod,
			boolean isItalic, boolean isStrike, boolean isUnderLine,
			UnderlineEnumeration underLineStyle, String underLineColor,
			boolean isHightLight, String hightLightValue, boolean isShd,
			STShd shdValue, String shdColor, CTVerticalAlignRun stRunEnum) {
		RPr rPr = factory.createRPr();
		RFonts rf = new RFonts();
		if (sTHint != null) {
			rf.setHint(sTHint);
		}
		if (fontFamily != null) {
			rf.setAscii(fontFamily);
			rf.setEastAsia(fontFamily);
			rf.setHAnsi(fontFamily);
		}
		rPr.setRFonts(rf);
		if (colorVal != null) {
			Color color = new Color();
			color.setVal(colorVal);
			rPr.setColor(color);
		}
		if (fontSize != null) {
			HpsMeasure sz = new HpsMeasure();
			sz.setVal(new BigInteger(fontSize));
			rPr.setSz(sz);
			rPr.setSzCs(sz);
		}

		BooleanDefaultTrue bdt = factory.createBooleanDefaultTrue();
		if (isBlod) {
			rPr.setB(bdt);
		}
		if (isItalic) {
			rPr.setI(bdt);
		}
		if (isStrike) {
			rPr.setStrike(bdt);
		}
		if (isUnderLine) {
			U underline = new U();
			if (underLineStyle != null) {
				underline.setVal(underLineStyle);
			}
			if (underLineColor != null) {
				underline.setColor(underLineColor);
			}
			rPr.setU(underline);
		}
		if (isHightLight) {
			Highlight hight = new Highlight();
			hight.setVal(hightLightValue);
			rPr.setHighlight(hight);
		}
		if (isShd) {
			CTShd shd = new CTShd();
			if (shdColor != null) {
				shd.setColor(shdColor);
			}
			if (shdValue != null) {
				shd.setVal(shdValue);
			}
			rPr.setShd(shd);
		}
		if (stRunEnum != null) {
			rPr.setVertAlign(stRunEnum);
		}
		return rPr;
	}

	public static Comments addDocumentCommentsPart(
			WordprocessingMLPackage wordMLPackage, ObjectFactory factory)
			throws Exception {
		CommentsPart cp = new CommentsPart();
		wordMLPackage.getMainDocumentPart().addTargetPart(cp);
		Comments comments = factory.createComments();
		cp.setJaxbElement(comments);
		return comments;
	}

	public static R createRunCommentReference(ObjectFactory factory,
			BigInteger commentId) {
		R run = factory.createR();
		R.CommentReference commentRef = factory.createRCommentReference();
		run.getContent().add(commentRef);
		commentRef.setId(commentId);
		return run;
	}

	public static XMLGregorianCalendar toXMLCalendar(Date d) throws Exception {
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(d);
		XMLGregorianCalendar xml = DatatypeFactory.newInstance()
				.newXMLGregorianCalendar();
		xml.setYear(gc.get(Calendar.YEAR));
		xml.setMonth(gc.get(Calendar.MONTH) + 1);
		xml.setDay(gc.get(Calendar.DAY_OF_MONTH));
		xml.setHour(gc.get(Calendar.HOUR_OF_DAY));
		xml.setMinute(gc.get(Calendar.MINUTE));
		xml.setSecond(gc.get(Calendar.SECOND));
		return xml;
	}

	public static Comments.Comment createComment(ObjectFactory factory,
			BigInteger commentId, String author, Date date,
			String commentContent, RPr commentRPr) throws Exception {
		Comments.Comment comment = factory.createCommentsComment();
		comment.setId(commentId);
		if (author != null) {
			comment.setAuthor(author);
		}
		if (date != null) {
			comment.setDate(toXMLCalendar(date));
		}
		P commentP = factory.createP();
		comment.getEGBlockLevelElts().add(commentP);
		R commentR = factory.createR();
		commentP.getContent().add(commentR);
		Text commentText = factory.createText();
		commentR.getContent().add(commentText);
		commentR.setRPr(commentRPr);
		commentText.setValue(commentContent);
		return comment;
	}

	public static void writeDocxToStream(WordprocessingMLPackage template,
			String target) throws IOException, Docx4JException {
		File f = new File(target);
		template.save(f);
	}
}

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值