通过文件路径获取文件,对不同类型的文件进行不同处理,将Word文件转成pdf文件预览,并早呢更加水印,暂不支持Excel文件,如果浏览器不支持PDF文件预览需要下载插件。文中currentUser.getUserid(),即为增加的水印内容,需要替换掉,字符串类型的。
加水印用的包是pdfbox,不是itext7,这两个包有的方法名一致,但是穿的参数类型不一致,引用的包不对,会报错。BufferedImage引用的是java.awt.image.BufferedImage引用成pdfbox的也会报错,有报错的参数注意一下引用的包。
java
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.24</version>
</dependency>
java
@RequestMapping("previewFile")
public void download(String src,HttpServletRequest request,HttpServletResponse response) throws Exception {
String filePath = src;
System.out.println("filePath:" + filePath);
File f = new File(filePath);
if (!f.exists()) {
response.sendError(404, "File not found!");
return;
}
String fileName = f.getName();
String extension = getFileExtension(f.getName());
BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
byte[] bs = new byte[1024];
int len = 0;
response.reset(); // 非常重要
URL u = new URL("file:///" + filePath);
//String contentType = u.openConnection().getContentType();
String contentType = "";
if(extension.equals("pdf")){
contentType = "application/pdf";
br = addWatermarkToPdf(filePath, currentUser.getUserid());
}else if (extension.equals("txt")){
contentType = "text/plain";
}else if (extension.equals("doc") || extension.equals("docx")){
contentType = "application/pdf";
try {
br = convertToPdf(filePath,currentUser.getUserid());
}catch (Exception e){
}
}else if (extension.equals("jpg") || extension.equals("jpeg")){
contentType = "image/jpeg";
br = createWatermarkedImage(filePath, currentUser.getUserid());
}else if (extension.equals("png")){
contentType = "image/png";
br = createWatermarkedImage(filePath, currentUser.getUserid());
}else if (extension.equals("gif")){
contentType = "image/gif";
br = createWatermarkedImage(filePath, currentUser.getUserid());
}
//Document docsss = new Document(filePath);
response.setContentType(contentType+"; charset=UTF-8");
response.setHeader("Content-Disposition", "inline;filename="
+ fileName);
// 文件名应该编码成utf-8,注意:使用时,我们可忽略这句
OutputStream out = response.getOutputStream();
while ((len = br.read(bs)) > 0) {
out.write(bs, 0, len);
}
out.flush();
out.close();
br.close();
}
public static BufferedInputStream createWatermarkedImage(String imagePath, String watermarkText) throws IOException {
// 读取原始图片
File file = new File(imagePath);
BufferedImage targetImg = ImageIO.read(new FileInputStream(file));
int height = targetImg.getHeight();
int width = targetImg.getWidth();
//-------------------------文字水印 start----------------------------
BufferedImage waterMarkImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 创建画笔
Graphics2D graphics2D = waterMarkImage.createGraphics();
// 绘制原始图片
graphics2D.drawImage(targetImg, 0, 0, width, height, null);
// 设置水印颜色
graphics2D.setColor(new Color(255, 255, 255, 255));
double scale = 1.0;
if(width < height){
scale = (double) width / height;
}
int fontSize = (int) Math.ceil((double) (height / 25) * scale);
// 设置字体 画笔字体样式为微软雅黑,加粗,文字大小按比例给
graphics2D.setFont(new Font("微软雅黑", Font.BOLD, fontSize));
float alpha = 0.7f; // 设置透明度为50%
AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
graphics2D.setComposite(composite);
// 水印旋转度
graphics2D.rotate(Math.toRadians(-25), (double) width / 2, (double) height / 2);
int x = -width * 3;
int y;
// 计算水印文字的宽度
FontMetrics fontMetrics = graphics2D.getFontMetrics();
int watermarkWidth = fontMetrics.stringWidth(watermarkText);
// 水印横向间隔
int positionWidth = (int)(width * 0.12);
// 水印竖向间隔
int positionHeight = (int)(height * 0.12);
while (x < width * 3) {
y = -height * 3;
while (y < height * 3) {
graphics2D.drawString(watermarkText, x, y);
y += fontSize + positionWidth;
}
x += watermarkWidth + positionHeight;
}
graphics2D.dispose();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(waterMarkImage, "png", outputStream);
byte[] imageBytes = outputStream.toByteArray();
return new BufferedInputStream(new ByteArrayInputStream(imageBytes));
}
public static BufferedInputStream addWatermarkToPdf(String filePath,String userId) throws IOException {
// 加载PDF文档
PDDocument document = PDDocument.load(new File(filePath));
try {
// 遍历所有页面
for (PDPage page : document.getPages()) {
// 获取页面的媒体框(即页面的大小)
PDRectangle mediaBox = page.getMediaBox();
float pageWidth = mediaBox.getWidth();
float pageHeight = mediaBox.getHeight();
// 创建内容流,使用APPEND模式
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);
// 设置水印字体和大小
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 36);
// 设置水印颜色(RGB)
contentStream.setNonStrokingColor(200, 200, 200);
// 设置文本水印的参数
String watermarkText = userId;
PDType1Font font = PDType1Font.HELVETICA_BOLD;
float fontSize = 20;
float textWidth = font.getStringWidth(watermarkText) / 1000 * fontSize;
float textHeight = fontSize;
float xStep = pageWidth / 4; // 文本在x轴上的重复间隔
float yStep = pageHeight / 12; // 文本在y轴上的重复间隔,可以根据需要调整
// 绘制文本水印
for (float y = 0; y < pageHeight; y += yStep) {
for (float x = 0; x < pageWidth; x += xStep) {
// 设置文本颜色(RGB),这里使用白色以确保在红色背景上可见
contentStream.setStrokingColor(255, 255, 255);
// 设置字体和大小
contentStream.beginText();
contentStream.setFont(font, fontSize);
contentStream.newLineAtOffset(x, y);
// 设置文本旋转
//contentStream.newLineAtOffset(xx, yy);
//contentStream.setTextMatrix(0, -0.5f, 0.5f, 0, 0, 0);
contentStream.setTextMatrix(0.5f, 0.5f, -0.5f, 0.5f, x, y);
contentStream.showText(watermarkText);
contentStream.endText();
}
}
// 关闭内容流
contentStream.close();
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
document.save(outputStream);
document.close();
return new BufferedInputStream(new ByteArrayInputStream(outputStream.toByteArray()));
// 保存并关闭PDF文档
//document.save(new File("watermarked.pdf"));
//document.close();
} finally {
if (document != null) {
document.close();
}
}
}
public static String getFileExtension(String fileName) {
if (fileName == null || fileName.isEmpty()) {
return "";
}
int dotIndex = fileName.lastIndexOf('.');
if (dotIndex == -1 || dotIndex == fileName.length() - 1) {
// No dot found or dot is at the end (e.g., "file.")
return "";
}
return fileName.substring(dotIndex + 1);
}
public static BufferedInputStream convertToPdf(String wordFilePath,String userId) throws Exception {
// 加载Word文档
Document doc = new Document(wordFilePath);
// 创建一个字节数组输出流来保存PDF内容
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
// 设置PDF保存选项(可选,这里使用默认设置)
PdfSaveOptions saveOptions = new PdfSaveOptions();
// 将文档保存为PDF格式到字节数组输出流中
doc.save(byteArrayOutputStream, saveOptions);
if (byteArrayOutputStream.size() == 0) {
throw new IllegalArgumentException("ByteArrayOutputStream is empty");
}
// 将ByteArrayOutputStream的内容转换为ByteArrayInputStream
ByteArrayInputStream bais = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
// 使用PDDocument.load方法将流转换为PDDocument对象
PDDocument pdDocument = PDDocument.load(bais);
// 关闭ByteArrayInputStream
bais.close();
// 将字节数组转换为字节输入流
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
// 返回BufferedInputStream
return addWatermarkToWord(pdDocument,userId);
}
public static BufferedInputStream addWatermarkToWord(PDDocument document,String userId) throws IOException {
// 加载PDF文档
//PDDocument document = PDDocument.load(new File(filePath));
try {
// 遍历所有页面
for (PDPage page : document.getPages()) {
// 获取页面的媒体框(即页面的大小)
PDRectangle mediaBox = page.getMediaBox();
float pageWidth = mediaBox.getWidth();
float pageHeight = mediaBox.getHeight();
// 创建内容流,使用APPEND模式
PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true, true);
// 设置水印字体和大小
contentStream.setFont(PDType1Font.HELVETICA_BOLD, 36);
// 设置水印颜色(RGB)
contentStream.setNonStrokingColor(200, 200, 200);
// 设置文本水印的参数
String watermarkText = userId;
PDType1Font font = PDType1Font.HELVETICA_BOLD;
float fontSize = 20;
float textWidth = font.getStringWidth(watermarkText) / 1000 * fontSize;
float textHeight = fontSize;
float xStep = pageWidth / 4; // 文本在x轴上的重复间隔
float yStep = pageHeight / 12; // 文本在y轴上的重复间隔,可以根据需要调整
// 绘制文本水印
for (float y = 0; y < pageHeight; y += yStep) {
for (float x = 0; x < pageWidth; x += xStep) {
// 设置文本颜色(RGB),这里使用白色以确保在红色背景上可见
contentStream.setStrokingColor(255, 255, 255);
// 设置字体和大小
contentStream.beginText();
contentStream.setFont(font, fontSize);
contentStream.newLineAtOffset(x, y);
// 设置文本旋转
//contentStream.newLineAtOffset(xx, yy);
//contentStream.setTextMatrix(0, -0.5f, 0.5f, 0, 0, 0);
contentStream.setTextMatrix(0.5f, 0.5f, -0.5f, 0.5f, x, y);
contentStream.showText(watermarkText);
contentStream.endText();
}
}
// 关闭内容流
contentStream.close();
}
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
document.save(outputStream);
document.close();
return new BufferedInputStream(new ByteArrayInputStream(outputStream.toByteArray()));
// 保存并关闭PDF文档
//document.save(new File("watermarked.pdf"));
//document.close();
} finally {
if (document != null) {
document.close();
}
}
}