和poi是否有版本冲突_poi的excel图片水印生成

当前POI 4.0版本不支持直接创建水印,由于Office和WPS对水印支持有限,本文介绍了一种通过修改页眉来实现水印的方法。通过将页眉设置为图片格式,然后修改xlsx的XML文件插入自定义的vmlDrawing,最终实现在Excel中添加水印的效果。详细代码可参考给出的链接。
摘要由CSDN通过智能技术生成

目前4.0版本poi对水印支持的不友好,包括office和wps对水印支持的也不有好,本文通过页眉来实现水印的开发.

第一步确定页眉是否可以使用

c119430510de84052a425d40ed53a17d.png

如果,页眉是可以插入图片,但是poi目前只支持字符串类型:

Header          header     = sheet.getHeader();header.setLeft("我是页眉");
2bb820b9c63075e860aa8cf76525982e.png

代码生成出来的页眉也只是在打印预览的时候可以看到,xlsx本身是可以解压的,既然可以插入字符串的页眉,我们可以修改xlsx本身来判断页眉的定位,xlsx解压后,这个drawings就是,页眉的配置,这个大家可以解压一个插入页眉的图片试一下

cb07b2078db872672fcfc5e301dd229f.png
<?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插入页眉继而实现水印的效果,最终效果,可以通过调整图片的大小实现不同的水印效果

bc35b4d3008d5409ea581d447fc92318.png

具体代码参考 https://gitee.com/lemur/easypoi/里面的水印代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值