相信很多小伙伴們在做導出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文件加水印的需求。