Browse Source

XLSX水印工具类

master
jueyue 4 years ago
parent
commit
6318b414dd
4 changed files with 203 additions and 6 deletions
  1. +5
    -1
      easypoi-base/pom.xml
  2. +3
    -3
      easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/ExcelImportService.java
  3. +2
    -2
      easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiExcelTempUtil.java
  4. +193
    -0
      easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiWatermarkUtil.java

+ 5
- 1
easypoi-base/pom.xml View File

@@ -106,5 +106,9 @@
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-annotation</artifactId>
</dependency>
</dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
</dependencies>
</project>

+ 3
- 3
easypoi-base/src/main/java/cn/afterturn/easypoi/excel/imports/ExcelImportService.java View File

@@ -156,8 +156,8 @@ public class ExcelImportService extends ImportBaseService {
ImportParams params,
Map<String, PictureData> pictures) throws Exception {
List collection = new ArrayList();
Map<String, ExcelImportEntity> excelParams = new HashMap<String, ExcelImportEntity>();
List<ExcelCollectionParams> excelCollection = new ArrayList<ExcelCollectionParams>();
Map<String, ExcelImportEntity> excelParams = new HashMap<>();
List<ExcelCollectionParams> excelCollection = new ArrayList<>();
String targetId = null;
i18nHandler = params.getI18nHandler();
boolean isMap = Map.class.equals(pojoClass);
@@ -482,7 +482,7 @@ public class ExcelImportService extends ImportBaseService {
importResult.setWorkbook(removeSuperfluousRows(successBook, failRow, params));
importResult.setFailWorkbook(removeSuperfluousRows(book, successRow, params));
} else {
importResult.setWorkbook(successBook);
importResult.setWorkbook(book);
}
importResult.setFailList(failCollection);
importResult.setVerifyFail(verifyFail);


+ 2
- 2
easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiExcelTempUtil.java View File

@@ -8,8 +8,8 @@ import java.util.HashMap;
import java.util.Map;

/**
* poi 4.0 07版本在 shift操作下有bug,移动了单元格以及单元格样式,没有移动cell
* cell还是复用的原的cell,导致wb输出的时候没有输出值
* poi 4.0 07版本在 shift操作下有bug,移动了单元格以及单元格样式,没有移动cell
* cell还是复用的原的cell,导致wb输出的时候没有输出值
* 等待修复的时候删除这个问题
*
* @author by jueyue on 19-6-17.


+ 193
- 0
easypoi-base/src/main/java/cn/afterturn/easypoi/util/PoiWatermarkUtil.java View File

@@ -0,0 +1,193 @@
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格式的图片,
* <p> 因为非png格式的图片打到Excel上后可能会有图片变红的问题,且不容易做出透明效果。 <p>
* @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格式的图片,
* <p> 因为非png格式的图片打到Excel上后可能会有图片变红的问题,且不容易做出透明效果。 <p>
* @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(

"<xml xmlns:oa=\"urn:schemas-microsoft-com:office:activation\"" +
" xmlns:p=\"urn:schemas-microsoft-com:office:powerpoint\"" +
" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"" +
" xmlns:o=\"urn:schemas-microsoft-com:office:office\"" +
" xmlns:v=\"urn:schemas-microsoft-com:vml\">" +
" <o:shapelayout v:ext=\"edit\">" +
" <o:idmap v:ext=\"edit\" data=\"1\"/>" +
" </o:shapelayout>" +
" <v:shape id=\""+headerPos+"\" " +
" o:spid=\"_x0000_s1028\" o:spt=\"75\" alt=\"" + pictureTitle + "\"" +
" type=\"#_x0000_t75\"" +
" style=\"position:absolute;left:0pt;top:0pt;margin-left:0pt;margin-top:0pt;height:" + (int) imageDimension.getHeight() + "pt;width:" + (int) imageDimension.getWidth() + "pt;\"" +
" filled=\"f\" o:preferrelative=\"t\" stroked=\"f\" coordsize=\"21600,21600\">" +
" <v:path/>" +
" <v:fill on=\"f\" focussize=\"0,0\"/>" +
" <v:stroke on=\"f\"/>" +
" <v:imagedata o:relid=\"" + rIdPic + "\" o:title=\"" + pictureTitle + "\"/>" +
" <o:lock v:ext=\"edit\" rotation=\"t\" aspectratio=\"t\"/>" +
" </v:shape>" +
"</xml>"

);*/
XmlObject doc = XmlObject.Factory.parse(

"<xml xmlns:v=\"urn:schemas-microsoft-com:vml\""
+ " xmlns:o=\"urn:schemas-microsoft-com:office:office\""
+ " xmlns:x=\"urn:schemas-microsoft-com:office:excel\">"
+ " <o:shapelayout v:ext=\"edit\">"
+ " <o:idmap v:ext=\"edit\" data=\"1\"/>"
+ " </o:shapelayout><v:shapetype id=\"_x0000_t75\" coordsize=\"21600,21600\" o:spt=\"75\""
+ " o:preferrelative=\"t\" path=\"m@4@5l@4@11@9@11@9@5xe\" filled=\"f\" stroked=\"f\">"
+ " <v:stroke joinstyle=\"miter\"/>"
+ " <v:formulas>"
+ " <v:f eqn=\"if lineDrawn pixelLineWidth 0\"/>"
+ " <v:f eqn=\"sum @0 1 0\"/>"
+ " <v:f eqn=\"sum 0 0 @1\"/>"
+ " <v:f eqn=\"prod @2 1 2\"/>"
+ " <v:f eqn=\"prod @3 21600 pixelWidth\"/>"
+ " <v:f eqn=\"prod @3 21600 pixelHeight\"/>"
+ " <v:f eqn=\"sum @0 0 1\"/>"
+ " <v:f eqn=\"prod @6 1 2\"/>"
+ " <v:f eqn=\"prod @7 21600 pixelWidth\"/>"
+ " <v:f eqn=\"sum @8 21600 0\"/>"
+ " <v:f eqn=\"prod @7 21600 pixelHeight\"/>"
+ " <v:f eqn=\"sum @10 21600 0\"/>"
+ " </v:formulas>"
+ " <v:path o:extrusionok=\"f\" gradientshapeok=\"t\" o:connecttype=\"rect\"/>"
+ " <o:lock v:ext=\"edit\" aspectratio=\"t\"/>"
+ " </v:shapetype><v:shape id=\"" + headerPos + "\" o:spid=\"_x0000_s1025\" type=\"#_x0000_t75\""
+ " style='position:absolute;margin-left:0;margin-top:0;"
+ "width:" + (int) imageDimension.getWidth() + "px;height:" + (int) imageDimension.getHeight() + "px;"
+ "z-index:1'>"
+ " <v:imagedata o:relid=\"" + rIdPic + "\" o:title=\"" + pictureTitle + "\"/>"
+ " <o:lock v:ext=\"edit\" rotation=\"t\"/>"
+ " </v:shape></xml>"

);
doc.save(out, DEFAULT_XML_OPTIONS);
out.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}

}

}

Loading…
Cancel
Save