相信很多小伙伴们在做导出pdf或者excel文件时会被要求在文件上加上水印,本篇博客就来讲讲如何为pdf和excel加水印。
导出pdf加水印
其实在导出pdf时加上水印并不难,因为itext提供了添加水印的方法,而且能设置水印的位置角度等等,直接来看一下代码
public void createPDF(String filename) throws IOException { Document document = new Document(PageSize.A4); try { PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename)); document.addTitle("example of PDF"); document.open(); PdfPTable table = createTable(writer); document.add(table); // 加入水印 PdfContentByte waterMar = writer.getDirectContentUnder(); // 开始设置水印 waterMar.beginText(); // 设置水印透明度 PdfGState gs = new PdfGState(); // 设置填充字体不透明度为0.2f gs.setFillOpacity(0.2f); // 设置水印字体参数及大小 (这里在上一篇博客中已经讲过了) BaseFont baseFont = BaseFont.createFont(JavaPdfHelloWorld.class.getResource("/simsun.ttf").getPath(), BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED); waterMar.setFontAndSize(baseFont,30); // 设置透明度 waterMar.setGState(gs); // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度 waterMar.showTextAligned(Element.ALIGN_RIGHT, "我是水印" , 350, 730, 45); //结束设置 waterMar.endText(); waterMar.stroke(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } finally { document.close(); } }
createTable()方法的代码就不贴了,就是生成一个pdf表格,这在之前的博客中已经提过了。
导出excel加水印
接下来我们着重看一下excel文件怎么加水印,现在业界对excel文件读写大多采用poi这个东西,而poi没有提供添加水印的方法,所以要怎么办呢,我在网上搜索了好久也没找到能直接拿来用的办法,但是看到有人提供思路,先准备一份打了水印的模版Excel,然后加载该模版,再将内容输出到该模版中,以达到为Excel添加水印的目的。这个思路看起来的确可行,然后就开干了,先看代码
public class ExcelUtilTest{ public void createExcel(HttpServletResponse response)throws Exception { //获取excel文件 File finalXlsxFile = new File("src/main/resources/watermark.xlsx"); //获取excel文件流 FileInputStream inputStream = new FileInputStream(finalXlsxFile); //根据文件流创建XSSFWorkbook对象 XSSFWorkbook wb = new XSSFWorkbook(inputStream); XSSFSheet sheet = wb.getSheetAt(0); sheet.setDefaultColumnWidth(16);//设置默认列宽 sheet.setDefaultRowHeightInPoints(20);//设置默认行高 for(int j = 0;j < 5;j++) { XSSFRow row = sheet.createRow(j); for(int i = 0;i<5;i++) { XSSFCell cell=row.createCell(i); cell.setCellValue("第"+j+"行第"+i+"列"); } } //输出Excel文件 OutputStream output= response.getOutputStream(); response.reset(); String fileName = "水印测试文件"; response.setHeader("Content-Disposition", "attachment; filename=" +new String(fileName.getBytes("UTF-8"), "iso-8859-1")+".xlsx"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8"); wb.write(output); output.close(); } }
这个代码换一下文件地址可以直接拿来用,值得注意的是这是用springboot以附件形式导出的,不是用java程序生成的,也就是说我还有一个controller文件,只是没贴出来。
和我们直接生成excel文件代码有所不同的是下面两句代码,如果是直接生成excel文件这构造方法参数是空的,然后getSheetAt()方法改为createSheet()方法即可
XSSFWorkbook wb = new XSSFWorkbook(inputStream);
XSSFSheet sheet = wb.getSheetAt(0);
至于如何设计excel文件上的水印这个网上教程很多,随便找一个来看就行,我就不赘述了,看一下效果如何
这是原始excel
这是生成后的excel
如果要将其打包部署的话,不能直接根据文件来获取inputStream,需要将代码改一改,将最上面两句代码改成springboot提供的获取类路径下文件流的方法,然后文件文件要放在类路径下。当然,这个在打包所有需要通过文件路径来获取文件的springboot项目情况都适用。
InputStream finalXlsxFile = new ClassPathResource("watermark.xlsx").getInputStream();
总结
相对pdf生成水印的方法,excel这个方法还是有很多不足之处的,比如生成水印的位置不能通过代码更改,如果有多个sheet不能全都加上去(除非事先知道有几个sheet),生成后的excel中的水印可以随意拖动位置(这个貌似可以改进)。总之这份代码是非常简陋的,只能解决最简单的为导出excel文件加水印的需求。