cn.afterturn.easypoi.util.PoiWatermarkUtil Maven / Gradle / Ivy
package cn.afterturn.easypoi.util;
import cn.afterturn.easypoi.cache.manager.POICacheManager;
import cn.afterturn.easypoi.exception.excel.ExcelExportException;
import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.ss.usermodel.Header;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.ImageUtils;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFPictureData;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.xmlbeans.XmlObject;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
/**
* 水印工具类,WPS仅支持打印水印
* 参考 https://jingyan.baidu.com/article/6d704a137cd29d28db51ca87.html
*
* @author jueyue on 20-4-29.
*/
public class PoiWatermarkUtil {
/**
* 为Excel打上水印工具函数仅支持XLSX格式
* @param sheet 需要打水印的Excel
* @param waterRemarkPath 水印地址,classPath,目前只支持png格式的图片,
* 因为非png格式的图片打到Excel上后可能会有图片变红的问题,且不容易做出透明效果。
* @param position 位置 LEFT,CENTER,RIGHT
* @throws IOException
*/
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打上水印工具函数仅支持XLSX格式
* @param sheet 需要打水印的Excel
* @param waterRemarkPath 水印地址,classPath,目前只支持png格式的图片,
*
因为非png格式的图片打到Excel上后可能会有图片变红的问题,且不容易做出透明效果。
* @throws IOException
*/
public static void putWaterRemarkToExcel(Sheet sheet, String waterRemarkPath) throws Exception {
putWaterRemarkToExcel(sheet,waterRemarkPath,"LEFT");
}
static class VmlDrawing extends POIXMLDocumentPart {
String rIdPic = "";
String pictureTitle = "";
java.awt.Dimension imageDimension = null;
String headerPos = "";
VmlDrawing(PackagePart part) {
super(part);
}
void setRIdPic(String rIdPic) {
this.rIdPic = rIdPic;
}
void setPictureTitle(String pictureTitle) {
this.pictureTitle = pictureTitle;
}
void setHeaderPos(String headerPos) {
this.headerPos = headerPos;
}
void setImageDimension(java.awt.Dimension imageDimension) {
this.imageDimension = imageDimension;
}
@Override
protected void commit() throws IOException {
PackagePart part = getPackagePart();
OutputStream out = part.getOutputStream();
try {
// WPS测试通过版本
/*XmlObject doc = XmlObject.Factory.parse(
"" +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" " +
" "
);*/
XmlObject doc = XmlObject.Factory.parse(
""
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
+ " "
);
doc.save(out, DEFAULT_XML_OPTIONS);
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}