1.前端界面(我使用的是ant design vue)
点击上传
//详情请查看 ant desgin vue 官网
2.请求的后台使用的是(Springboot)
controller类为:
/**
* 文件上传
* @param request
* @param response
* @return
*/
@PostMapping(value = "/uploadAttachment")
public Result> upload(HttpServletRequest request, HttpServletResponse response) {
//组装返回的json内容
Result> result = new Result<>();
//获取request请求中的文件内容
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
//保存到Spring的MultipartFile类中
MultipartFile file = multipartRequest.getFile("file");// 获取上传文件对象
//存入数据库,并返回ID(这里使用对象返回的)
LimsDbFile limsDbFile = attachmentService.addlimsFiledb(file);
//返回文件的信息
if(limsDbFile!=null){
//返回文件的id
result.setMessage(limsDbFile.getId());
}else {
result.setMessage("文件上传失败");
}
return result;
}
service类:
public LimsDbFile addlimsFiledb(MultipartFile file) {
LimsDbFile limsDbFile = null;
try {
//LobHandler 接口为操作 BLOB/CLOB 提供了统一访问接口
LobHandler lobHandler = new DefaultLobHandler();
//使用jdk中的uuid 生成主键
String id = UUID.randomUUID().toString().replaceAll("-", "");
//获取请求传入的文件流
InputStream inputStream = file.getInputStream();
//把文件流转换成字节流
byte[] filebyte = AttachmentServiceImpl.toByteArray(inputStream);
//要插入的sql
String sql = "INSERT INTO LIMS_DB_FILE (ID, FILE_NAME , FILE_IMAGE) VALUES(?,?,?)";
//使用AbstractLobCreatingPreparedStatementCallback抽象类保存字节到blob字段。此处也可以直接使用jdbc插入的方法
AbstractLobCreatingPreparedStatementCallback callback = new AbstractLobCreatingPreparedStatementCallback(lobHandler) {
protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException {
ps.setString(1, id);
ps.setString(2, file.getOriginalFilename());
ps.setBytes(3, filebyte);
}
};
jdbcTemplate.execute(sql,callback);
//实例化返回对象
limsDbFile = new LimsDbFile();
limsDbFile.setId(id);
limsDbFile.setFileName(file.getOriginalFilename());
} catch (IOException e) {
e.printStackTrace();
}
return limsDbFile;
}
转换inputstream为字节流的方法:
public static byte[] toByteArray(InputStream input) throws IOException {
//声明字节输出流
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[1024*4];
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
以上便是文件上传的步骤操作
3.文件下载前端代码
//在界面上写个button执行一下方法
DownloadAttament(record){
if (this.selectedRowKeys.length <= 0) {
this.$message.warning('请选择一条记录!');
return;
}else {
console.log(record.fileId);
window.location.href = window._CONFIG['domianURL']+"/message/message/DowloadFile?fileId="+record.fileId;
}
}
4.后台请求的controller
/**
* 文件下载
* @param response
* @return
*/
@RequestMapping(value = "/DowloadFile")
public void DowloadFile(HttpServletResponse response, Attachment attachment) {
//声明字节输出流
ByteArrayOutputStream baos= null;
//声明转换后的字节数组
byte[] pdfBytes = null;
//声明到客户端的输出流
OutputStream toClient = null;
//获取旧文件字节流
LimsDbFile limsDbFile = attachmentService.getlimsFiledb(attachment.getFileId());
try {
//写出新的pdf到字节输出流类
baos = new ByteArrayOutputStream();
//调用 使用itext写的方法类(此处水印可以通过传入参数配置成动态的,并且只能给pdf添加水印)
WaterMark.addWaterMark(limsDbFile.getFileImage(),baos,"我的第一个测试水印");
//把写出的字节输出流转换成字节
pdfBytes = baos.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
try {
//充值response请求
response.reset();
//设置response 返回的头部请求,拼接查询出来的文件名称
response.addHeader("Content-Disposition", "attachment;filename=" + new String(limsDbFile.getFileName().getBytes(), "ISO8859-1"));
//设置输出文件的大小
response.addHeader("Content-Length", "" + pdfBytes.length);
//获取respose输出流
toClient = new BufferedOutputStream(response.getOutputStream());
//把文件输出流到客户端
baos.writeTo(toClient);
//此处注释代码为旧文件写出时的操作,输出这个文件没有水印。
// toClient.write(limsDbFile.getFileImage());
toClient.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (toClient != null) {
try {
toClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(baos!=null){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
5.获取文件字节时调用的service类
public LimsDbFile getlimsFiledb(String Filedbid) {
byte[] file = null;
String filename =null;
String sql = "SELECT * FROM LIMS_DB_FILE WHERE ID = ?";
Connection conn = null;
ResultSet rs = null;
PreparedStatement psmt = null;
//使用jdbc模板jdbcTemplate 查询出数据并映射到实体类
LimsDbFile limsDbFile = jdbcTemplate.queryForObject(sql,new BeanPropertyRowMapper(LimsDbFile.class),Filedbid);
return limsDbFile;
}
6.添加水印的时候生成水印的类
package org.jeecg.modules.util;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.*;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.UUID;
public class WaterMark {
/**
* 添加文字水印,并附加UUID
* @param bytesrcFile 接收的文件inputstream流
* @param baos 加水印后输出到字节流
* @param text 文本内容
* @throws Exception
*/
public static void addWaterMark(byte[] bytesrcFile, ByteArrayOutputStream baos, String text) throws Exception {
// 待加水印的文件(如果是物理磁盘就传入String类型的路径,如果是从数据库读取的字节流如下)
PdfReader reader = new PdfReader(bytesrcFile);
// 加完水印的文件(如果是写入物理磁盘,则传入String类型的路径,如果是写入字节输出流如下)
PdfStamper stamper = new PdfStamper(reader, baos);
int total = reader.getNumberOfPages() + 1;
PdfContentByte content;
// 设置透明度
PdfGState gs = new PdfGState();
gs.setFillOpacity(0.3f);
// 设置字体(中文写法)
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
// 循环对每页插入水印
for (int i = 1; i < total; i++)
{
// 水印的起始
content = stamper.getOverContent(i);
content.setGState(gs);
content.setFontAndSize(base, 32);
// 开始
content.beginText();
// 设置颜色 默认为黑色
content.setColorFill(BaseColor.BLACK);
// 开始写入水印(可写入多个水印)
content.showTextAligned(Element.ALIGN_MIDDLE, text, 180,
340, 45);
content.showTextAligned(Element.ALIGN_MIDDLE, UUID.randomUUID().toString(), 140,
240, 45);
content.endText();
}
stamper.close();
}
public static void main(String[] args) throws Exception{
//这块测试可以编辑一下方法,那方法改成两String类型的路径
String fileSrc = "D:\\qqq.pdf";
String destFile = "D:\\aaa.pdf";
String text = "这个是一个测试的水印";
// addWaterMark(fileSrc,destFile,text);
}
}
7.如果要使用itext生成水印则需要在maven中引用如下包
com.itextpdf
itextpdf
5.4.3
com.itextpdf
itext-asian
5.2.0