目前4.0版本poi对水印支持的不友好,包括office和wps对水印支持的也不有好,本文通过页眉来实现水印的开发.
第一步确定页眉是否可以使用
如果,页眉是可以插入图片,但是poi目前只支持字符串类型:
Header header = sheet.getHeader();header.setLeft("我是页眉");
代码生成出来的页眉也只是在打印预览的时候可以看到,xlsx本身是可以解压的,既然可以插入字符串的页眉,我们可以修改xlsx本身来判断页眉的定位,xlsx解压后,这个drawings就是,页眉的配置,这个大家可以解压一个插入页眉的图片试一下
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
这个vmlDrawing1.vml就是上面的内容也就是图片的描述,其中id="RH" 是页眉不的左中右,这个是wsp的配置,office还可以这个有点不一样不过大体都是一个概念
这样我们就可以通过改动xlsx里面的xml文件来实现我们自己的页眉了
首先,header设置为图片格式
Header header = sheet.getHeader();header.setLeft("&G"); // wps显示为&[图片]
然后我们定义我们自己的vmlDrawing
@Overrideprotected void commit() throws IOException { PackagePart part = getPackagePart(); OutputStream out = part.getOutputStream(); try { "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " ); doc.save(out, DEFAULT_XML_OPTIONS); out.close(); } catch (Exception ex) { ex.printStackTrace(); }}
下一步就是把这个对象插入到workbook
public static void putWaterRemarkToExcel(Sheet sheet, String waterRemarkPath, String position) throws Exception { int pictureIdx = sheet.getWorkbook().addPicture(IOUtils.toByteArray(POICacheManager.getFile(waterRemarkPath)), Workbook.PICTURE_TYPE_PNG); OPCPackage opcpackage = ((XSSFWorkbook) sheet.getWorkbook()).getPackage(); PackagePartName partname = PackagingURIHelper.createPartName("/xl/drawings/vmlDrawing" + pictureIdx + ".vml"); PackagePart part = opcpackage.createPart(partname, "application/vnd.openxmlformats-officedocument.vmlDrawing"); VmlDrawing vmldrawing = new VmlDrawing(part); //创建页眉,位置LEFT,下面headerPos填写对应的 Header header = sheet.getHeader(); switch (position){ case "LEFT": header.setLeft("&G"); vmldrawing.setHeaderPos("LH"); break; case "CENTER": header.setCenter("&G"); vmldrawing.setHeaderPos("CH"); break; case "RIGHT": header.setRight("&G"); vmldrawing.setHeaderPos("RH"); break; default: throw new ExcelExportException("输入的position参数不合法"); } XSSFPictureData picData = (XSSFPictureData) sheet.getWorkbook().getAllPictures().get(pictureIdx); String rIdPic = vmldrawing.addRelation(null, XSSFRelation.IMAGES, picData).getRelationship().getId(); ByteArrayInputStream is = new ByteArrayInputStream(picData.getData()); java.awt.Dimension imageDimension = ImageUtils.getImageDimension(is, picData.getPictureType()); IOUtils.closeQuietly(is); vmldrawing.setRIdPic(rIdPic); vmldrawing.setPictureTitle(waterRemarkPath); vmldrawing.setImageDimension(imageDimension); String rIdExtLink = ((XSSFSheet) sheet).addRelation(null, XSSFRelation.VML_DRAWINGS, vmldrawing).getRelationship().getId(); ((XSSFSheet) sheet).getCTWorksheet().addNewLegacyDrawingHF().setId(rIdExtLink);}
通过上面的办法我们就可以给excel插入页眉继而实现水印的效果,最终效果,可以通过调整图片的大小实现不同的水印效果
具体代码参考 https://gitee.com/lemur/easypoi/里面的水印代码