SpringBoot实现PPT格式文件上传并在线预览功能
作者:Just do Java 发布时间:2023-07-22 14:44:56
标签:SpringBoot,PPT,文件上传,预览
1、需要引入依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.15</version>
</dependency>
<!--其他格式转换为PDF -->
<dependency>
<groupId>fr.opensagres.xdocreport</groupId>
<artifactId>xdocreport</artifactId>
<version>1.0.6</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
2、上传文件到本地文件夹中
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<Object> uploadFileToLocal(@RequestParam("multipartFile") MultipartFile multipartFile) {
if (multipartFile == null) {
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
File file = null;
try {
File dir = new File(basePath);
if (!dir.exists()) {
dir.mkdir();
}
file = new File(basePath + File.separator + multipartFile.getOriginalFilename());
if (!file.exists()) {
multipartFile.transferTo(file);
}
} catch (IOException e) {
e.printStackTrace();
}
return ResponseEntity.ok(FileVo.builder().size(multipartFile.getSize()).path(file.getAbsolutePath()).build());
}
basePath为定义的常量: private static final String basePath = “C:\tempFile”;
通过上传接口,可在C盘的tempfile目录下找到上传的文件,首先我们先上传一个PPT文件,上传成功会返回文件的绝对路径地址以及文件大小,绝对地址将作为在线预览文件接口的参数。
3、在线预览PPT文件
@GetMapping("/showPPT")
public void showPPT(@RequestParam("path") String path,HttpServletResponse response) throws IOException {
byte[] buffer = new byte[1024 * 4];
String type = path.substring(path.lastIndexOf(".") + 1);
//转换pdf文件,如存在则直接显示pdf文件
String pdf = path.replace(type, "pdf");
File pdfFile = new File(pdf);
if (pdfFile.exists()) {
outFile(buffer, pdfFile, response);
} else {
FileInputStream in = new FileInputStream(path);
ZipSecureFile.setMinInflateRatio(-1.0d);
XMLSlideShow xmlSlideShow = new XMLSlideShow(in);
in.close();
// 获取大小
Dimension pgsize = xmlSlideShow.getPageSize();
// 获取幻灯片
List<XSLFSlide> slides = xmlSlideShow.getSlides();
List<File> imageList = new ArrayList<>();
for (int i = 0; i < slides.size(); i++) {
// 解决乱码问题
List<XSLFShape> shapes = slides.get(i).getShapes();
for (XSLFShape shape : shapes) {
if (shape instanceof XSLFTextShape) {
XSLFTextShape sh = (XSLFTextShape) shape;
List<XSLFTextParagraph> textParagraphs = sh.getTextParagraphs();
for (XSLFTextParagraph xslfTextParagraph : textParagraphs) {
List<XSLFTextRun> textRuns = xslfTextParagraph.getTextRuns();
for (XSLFTextRun xslfTextRun : textRuns) {
xslfTextRun.setFontFamily("宋体");
}
}
}
}
//根据幻灯片大小生成图片
BufferedImage img = new BufferedImage(pgsize.width, pgsize.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = img.createGraphics();
graphics.setPaint(Color.white);
graphics.fill(new Rectangle2D.Float(0, 0, pgsize.width, pgsize.height));
// 将PPT内容绘制到img上
slides.get(i).draw(graphics);
//图片将要存放的路径
String absolutePath = basePath + File.separator+ (i + 1) + ".jpg";
File jpegFile = new File(absolutePath);
if (!jpegFile.exists()) {
// 判断如果图片存在则不再重复创建,建议将图片存放到一个特定目录,后面会统一删除
FileOutputStream fileOutputStream = new FileOutputStream(jpegFile);
ImageIO.write(img, "jpg", fileOutputStream);
}
// 图片路径存放
imageList.add(jpegFile);
}
File file = png2Pdf(imageList, pdf);
outFile(buffer, file, response);
}
}
private void outFile(byte[] buffer, File pdfFile, HttpServletResponse response) throws IOException {
ByteArrayOutputStream out;
int n = 0;
FileInputStream fileInputStream = new FileInputStream(pdfFile);
out = new ByteArrayOutputStream();
ServletOutputStream outputStream = response.getOutputStream();
while ((n = fileInputStream.read(buffer)) != -1) {
out.write(buffer, 0, n);
}
outputStream.write(out.toByteArray());
outputStream.flush();
}
//将图片列表转换为PDF格式文件并存储
public File png2Pdf(List<File> pngFiles, String pdfFilePath) {
Document document = new Document();
File pdfFile = null;
long startTime = System.currentTimeMillis();
try {
pdfFile = new File(pdfFilePath);
if (pdfFile.exists()) {
return pdfFile;
}
PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
document.open();
pngFiles.forEach(pngFile -> {
try {
Image png = Image.getInstance(pngFile.getCanonicalPath());
png.scalePercent(50);
document.add(png);
} catch (Exception e) {
System.out.println("png2Pdf exception");
}
});
document.close();
return pdfFile;
} catch (Exception e) {
System.out.println(String.format("png2Pdf %s exception", pdfFilePath));
} finally {
if (document.isOpen()) {
document.close();
}
// 删除临时生成的png图片
for (File pngFile : pngFiles) {
try {
FileUtils.delete(pngFile);
} catch (IOException e) {
e.printStackTrace();
}
}
long endTime = System.currentTimeMillis();
System.out.println("png2Pdf耗时:" + (endTime - startTime));
}
return null;
}
核心思路:将PPT文件读取每一页幻灯片,将幻灯片转换为图片格式,最后将所有图片放到一个pdf文件中形成一个pdf文件用于在线预览。预览时会在同级目录下创建一个相同文件名后缀为pdf的文件,每次预览会先查找文件是否存在,存在则直接预览,不存在则会走上面的处理。
4、预览效果
来源:https://blog.csdn.net/pengyangyan/article/details/123086763


猜你喜欢
- C# 自带的HttpWebRequest效率太低,对于自组HTTP封包不好操作。在写超级SQL注入工具时,研究了很长一段时间如何使用Sock
- 前言上一节我们搭建起了服务注册中心,为各个服务提供者和消费者提供一个桥梁,这一节我们搭建一个服务提供者,注册到注册中心开源地址:https:
- 本文实例为大家分享了Java实现简单邮件发送的具体代码,供大家参考,具体内容如下需要的jar包:activation-1.1.1.jarma
- 接口可以声明事件。 下面的示例演示如何在类中实现接口事件。 这些规则基本上都与实现任何接口方法或属性时的相同。在类中实现接口事件在类中声明事
- PowerPoint幻灯片中可插入公式,用于在幻灯片放映时演示相关内容的论证、推算的依据,能有效地为演讲者提供论述的数据支撑。通过后端程序代
- 题目要求:两人比赛,A,B,每人最开始分得6张手牌,手牌大小为从1到9 A先出牌,B后出牌,若出牌在桌面上存在,在出牌人获得两张相同牌中间的
- Feign调用中的两种Header传参方式在Spring Cloud Netflix栈中,各个微服务都是以HTTP接口的形式暴露自身服务的,
- 一:回顾反射机制这种重点回顾一下反射Method!为什么要回顾反射机制呢?因为我们后面要手写一个简易的Spring框架,便于我们理解其中的核
- Rsa加密RSA是目前最有影响力的公钥加密算法,RSA也是第一个既能用于数据加密也能用于数字签名的算法。该算法基于一个十分简单的数论事实:将
- Jenkins是一个开源软件项目,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能Jenkins是基于Java开发的一种持续集成工具
- 在使用jsoup爬取其他网站数据的时候,发现class是带空格的多选择,如果直接使用doc.getElementsByClass(“clas
- 你知道String、StringBuilder、Stringbuffer的区别吗?当你创建字符串的时候,有考虑过该使用哪个吗?别急,这篇文章
- 因为工作原因需要读取json文件,最先是使用url方式不符合要求pass。又使用本地方式读取。记录一下方便后期查看。 注:因为资料都是从网上
- 我就废话不多说了,大家还是直接看代码吧~private LineRenderer line1; &
- 本文实例为大家分享了Android实现简单顶部标题栏的具体代码,供大家参考,具体内容如下实现功能:1)自定义View标题栏布局;2)灵活的可
- 一、定义泛型类void Main(){ //实例化泛型类时,才指定具体的类型 MyGen
- 前言Java线程池中提交任务运行,通常使用execute()方法就足够了。那如果想要实现在主线程中阻塞获取线程池任务运行的结果,该怎么办呢?
- 前言腾讯动漫app v8.1.6 工具:jadx、frida、pixel3 安卓10提示:以下是本篇文章正文内容,案例可供参考一、问题1.1
- 这篇文章主要介绍了Jmeter如何添加循环控制器,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以
- 当我们在做前后端分离的开发时,在使用fetch交换数据的时候,提示Access-Control-Allow-Origin跨域问题,解决方案跟