Closed jyf1997 closed 3 years ago
@jyf1997 是否方便贴一下源码?我的源码里word添加水印的思路是采用docx4j,不是poi的方法,你可以尝试用我的代码实现下,详见单元测试类 WordProcessorTests
以下是我解析Word的代码,我尝试过,如果是通过 IO流或者模板去创建 document对象, paragraph.getCTP().getRArray(0).getPictArray(0).这句就会报数组下标越界错误。如果直接调用无参的构造方法,则可以正常的运行并加上水印。随便问一下:POI可以为EXCEL或者PPT 加上文字水印吗?
public static void changeWord(String inputUrl, String outputUrl,int status){
try {
InputStream in = new FileInputStream(inputUrl);
//获取word文档解析对象
XWPFDocument doucument = new XWPFDocument(in);
addWaterMark(doucument,"水印","#d8d8d8");
//获取段落文本对象
List
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void addWaterMark(Object obj, String watermark, String color) {
if (obj instanceof XWPFDocument) {
XWPFDocument doc = (XWPFDocument) obj;
// create header-footer
XWPFHeaderFooterPolicy headerFooterPolicy =doc.createHeaderFooterPolicy();
// create default Watermark - fill color black and not rotated
headerFooterPolicy.createWatermark(watermark);
// get the default header
// Note: createWatermark also sets FIRST and EVEN headers
// but this code does not updating those other headers
XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
XWPFParagraph paragraph = header.getParagraphArray(0);
// get com.microsoft.schemas.vml.CTShape where fill color and rotation is set
paragraph.getCTP().newCursor();
XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(new QName("urn:schemas-microsoft-com:vml", "shape"));
if (xmlobjects.length > 0) {
com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape)xmlobjects[0];
// set fill color
ctshape.setFillcolor(color);
// set rotation
ctshape.setStyle(ctshape.getStyle() + ";rotation:315");
}
} else if (obj instanceof HWPFDocument) {
}
}
你好你的demo下载下来 用WatermarkServiceImpl中addWaterMark 方法加水印会报 数组越界,你在使用的过程中会出现吗? java.lang.IndexOutOfBoundsException at org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTRImpl.getPictArray(Unknown Source)
以下是我解析Word的代码,我尝试过,如果是通过 IO流或者模板去创建 document对象, paragraph.getCTP().getRArray(0).getPictArray(0).这句就会报数组下标越界错误。如果直接调用无参的构造方法,则可以正常的运行并加上水印。随便问一下:POI可以为EXCEL或者PPT 加上文字水印吗? public static void changeWord(String inputUrl, String outputUrl,int status){ try { InputStream in = new FileInputStream(inputUrl); //获取word文档解析对象 XWPFDocument doucument = new XWPFDocument(in); addWaterMark(doucument,"水印","#d8d8d8"); //获取段落文本对象 List paragraphs = doucument.getParagraphs(); for (int i=0;i<paragraphs.size();i++) {//遍历模板中的段落对象找到标记位置 XWPFParagraph xwpfParagraph = paragraphs.get(i); List runs = xwpfParagraph.getRuns(); for (int l=0;l<runs.size();l++) { XWPFRun run = runs.get(l); String s = run.getText(run.getTextPosition()); if (status==1) s = WordAPi.Encrypt(s); else s=WordAPi.Decrypt(s); run.setText(s,0); } } //获取首行run对象 // XWPFRun run = paragraph.createRun(); //设置文本内容 // run.setText(readWord(inputUrl)); File file = new File(outputUrl); FileOutputStream stream = new FileOutputStream(file); doucument.write(stream); stream.close();
} catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void addWaterMark(Object obj, String watermark, String color) { if (obj instanceof XWPFDocument) { XWPFDocument doc = (XWPFDocument) obj; // create header-footer XWPFHeaderFooterPolicy headerFooterPolicy =doc.createHeaderFooterPolicy(); // create default Watermark - fill color black and not rotated headerFooterPolicy.createWatermark(watermark); // get the default header // Note: createWatermark also sets FIRST and EVEN headers // but this code does not updating those other headers XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT); XWPFParagraph paragraph = header.getParagraphArray(0); // get com.microsoft.schemas.vml.CTShape where fill color and rotation is set paragraph.getCTP().newCursor(); XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(new QName("urn:schemas-microsoft-com:vml", "shape")); if (xmlobjects.length > 0) { com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape)xmlobjects[0]; // set fill color ctshape.setFillcolor(color); // set rotation ctshape.setStyle(ctshape.getStyle() + ";rotation:315"); } } else if (obj instanceof HWPFDocument) { } }
你好 这个问题你解决了吗
@YanZhao1 把你的代码和测试文档可以发我邮箱,我们调试下
@YanZhao1
并非每个paragraph 对象都需要通过XML去修改,直接即可
XWPFHeaderFooterPolicy xFooter = new XWPFHeaderFooterPolicy(doucument);
xFooter.createWatermark("水印");
当我使用这种方式加水印时: InputStream in = new FileInputStream(inputUrl); //获取word文档解析对象 XWPFDocument doucument = new XWPFDocument(in); addWaterMark(doucument,"水印","#d8d8d8"); 报错: Exception in thread "main" java.lang.IndexOutOfBoundsException at org.openxmlformats.schemas.wordprocessingml.x2006.main.impl.CTRImpl.getPictArray(Unknown Source) at com.zhibei.utils.PoiUtil.addWaterMark(PoiUtil.java:339) at com.zhibei.utils.PoiUtil.changeWord(PoiUtil.java:290) at com.zhibei.utils.PoiUtil.main(PoiUtil.java:486)