spring MVC接口-下载PDF文件添加水印
PDF文件下载接口动态添加水印, 本文以七牛云存储为例
主要步骤
- Java获取url文件流
- 文件流动态添加水印
- 文件流下载
核心代码
添加maven
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
1.通过url获取文件输出流
这里是写死的PDF文件, 其他文件请自行测试
/**
* 通过url获取 OutputStream
*
* @param outputStream
* @param url
* @throws IOException
*/
public static void getFile(OutputStream outputStream, String url) throws IOException {
RestTemplate restTemplate = new RestTemplate();
final String APPLICATION_PDF = "application/pdf";
HttpHeaders headers = new HttpHeaders();
InputStream inputStream = null;
try {
List list = new ArrayList<>();
list.add(MediaType.valueOf(APPLICATION_PDF));
headers.setAccept(list);
ResponseEntity<byte[]> response = restTemplate.exchange(
url,
HttpMethod.GET,
new HttpEntity<byte[]>(headers),
byte[].class);
byte[] result = response.getBody();
inputStream = new ByteArrayInputStream(result);
int len = 0;
byte[] buf = new byte[1024];
while ((len = inputStream.read(buf, 0, 1024)) != -1) {
outputStream.write(buf, 0, len);
}
outputStream.flush();
} finally {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.close();
}
}
}
2.添加水印
需要将第一步的输出流转为输入流, 然后进行水印添加
/**
* outputStream转inputStream
*/
public static ByteArrayInputStream parse(OutputStream out) throws Exception {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
baos = (ByteArrayOutputStream) out;
ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
return swapStream;
}
/**
* InputStream pdf文件加文字水印转成 OutputStream
*
* @param is
* @param text
* @param os 这里传入的是response响应输出流
* @throws Exception
*/
public static void addTextfMark(InputStream is, String text, OutputStream os) throws Exception {
PdfReader reader = new PdfReader(is, "pdf".getBytes());
// 如果是web项目,直接下载应该放到response的流里面
PdfStamper stamp = new PdfStamper(reader, os);
int pageSize = reader.getNumberOfPages();
// 每页的高度
float pageHeight = reader.getPageSize(1).getHeight();
// 每页的宽度
float pageWidth = reader.getPageSize(1).getWidth();
try {
// 每页显示多少行
int lineNum = (int) (pageHeight / IAMGE_HEIGHT); // 行数
// 每两行显示两个 左边一个,右边一个
int middleX = (int) pageWidth / 2;
int middleH = (int) pageHeight / 2;
// 循环每一页
for (int i = 1; i <= pageSize; i++) {
// 循环每一页的每一行
for (int j = 0, k = 0; j < lineNum; j = j + 2, k++) {
PdfContentByte under = stamp.getOverContent(i);// 在图片上
under.beginText();
// 支持中文 仅 5.2.0版本
BaseFont bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",BaseFont.EMBEDDED);
under.setFontAndSize(bf, 40);
under.setTextMatrix(10, 10);
// 设置透明度
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.2f);//设置透明度为0.2
under.setGState(gs);
under.setColorFill(BaseColor.GRAY);
under.showTextAligned(Element.ALIGN_LEFT, text, middleX / 2, middleH / 2, 45);
under.showTextAligned(Element.ALIGN_LEFT, text, middleX + middleX / 2, middleH + middleH / 2, 45);
// 0 0 0 表示左下脚 最后一个0是角度,0表示横着 45 表示斜着
under.showTextAligned(Element.ALIGN_LEFT, text, middleX / 2, middleH / 2, 45);
under.showTextAligned(Element.ALIGN_LEFT, text, middleX + middleX / 2, middleH + middleH / 2, 45);
under.endText();
}
}
} catch (Exception e) {
throw e;
} finally {
stamp.close();// 关闭
reader.close();
}
}
3.完整方法调用过程
/**
* 下载处理PDF附件
*
* @param response
* @param fileName
* @param resourceUrl
* @param content
* @throws Exception
*/
public static void downloadFile(String viewType, HttpServletResponse response, String fileName, String resourceUrl, String content) throws Exception {
viewType = StringUtil.isNotEmpty(viewType)?viewType:"attachment";
if(!"attachment".equals(viewType) && !"inline".equals(viewType)){
throw new BizException("文件查看类型有误");
}
response.setContentType("application/pdf");//attachment
response.setHeader("Content-disposition", viewType+";filename=" + new String(fileName.getBytes(), "iso-8859-1"));
OutputStream ouputStream = response.getOutputStream();
OutputStream ouputStreamTemp = new ByteArrayOutputStream();
CRMUtil.getFile(ouputStreamTemp, resourceUrl);
InputStream bis = PDFUtils.parse(ouputStreamTemp);
PDFUtils.addTextfMark(bis, content, ouputStream);
ouputStream.flush();
ouputStream.close();
}
接口
/**
* 下载附件
*
* @param request
* @param response
*/
@GetMapping("/download")
public void disclosureDownload(HttpServletRequest request,HttpServletResponse response,
@RequestParam(name = "ticket", required = false) String ticket,
@RequestParam(name = "viewType", required = false) String viewType, // inline/attachment
@RequestParam(name = "disclosureId", required = false) String disclosureId){
try {
PDFUtils.downloadFile(viewType, response,"文件名", resourceUrl, "水印文字");
} catch (Exception e) {
e.printStackTrace();
throw new BizException("附件下载失败:"+e.getMessage());
}
}