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
0
投稿
猜你喜欢
- 过年微信红包很火,最近有个项目也要做抢红包,于是写了个红包的生成算法。红包生成算法的需求预先生成所有的红包还是一个请求随机生成一个红包简单来
- Android Build类的详解及简单实例一、类结构:java.lang.Object? android.os.Build二、类概述:从系
- 井字棋游戏要求在3乘3棋盘上,每行都相同或者每列都相同再或者对角线相同,则胜出.因此我们可以使用一个二维数组来表示棋盘,判断胜负只需要判断数
- 本文实例为大家分享了Flutter自定义圆盘取色器的具体代码,供大家参考,具体内容如下下面展示一些 内联代码片。圆盘取色器效果图完整代码im
- 前言最近在工作中需要编译android下的动态库,本以为是一件简单的事,没想到因为工具,以及google本身被墙的原因,折腾了好久。在win
- 今天给大家介绍一下SpringBoot中JPA的一些常用操作,例如:增删改查、分页、排序、事务操作等功能。下面先来介绍一下JPA中一些常用的
- 本文实例为大家分享了OpenCV实现人脸识别程序的具体代码,供大家参考,具体内容如下//Haar特征检测,人脸识别算法,是用xml作为训练后
- 本文实例为大家分享了Android微信摇一摇功能的实现方法,供大家参考,具体内容如下import java.util.ArrayList;
- 库从本质上来说是一种可执行代码的二进制格式,可以被载入内存中执行。库分静态库和动态库两种。 一、静态库和动态库的区别1. 静态函数库这类库的
- 开发环境win10Android Studio效果用于多级菜单展示,或选择。如 每个省,市,县;如 树木的病虫害;关键代码 @overrid
- 机器学习 机器学习的目的是把数据转换成信息。 机器学习通过从数据里提取规则或模式来把数据转成信息。 人脸识别 人脸识别通过级联分类器对特征的
- 报错翻译: compileSdkVersion android-24”需要JDK 1.8或更高版本编译。报错现象如下图:原因:st
- Pom依赖<parent> <groupId>org.springframework.bo
- 初学C++的朋友经常在类中看到public,protected,private以及它们在继承中表示的一些访问范围,很容易搞糊涂。今天本文就来
- 前言目前正在做的项目,为了增加用户的体验度,准备增加一些动画效果,其中底部栏中间按钮的点击事件参考了闲鱼的动效,便在此基础上仿写了该动效,并
- 这节主要完成一些基本的增删改查以及Service、Dao和Action的抽取。1. Service层的抽取  
- 1. 在原有工程目录右键-> new ->Module->:2. 选择library:3. 一路next,最后finish
- 1.根据单个分隔字符用split截取例如string st="GT123_1";string[] sArray=st.s
- 前言RefreshIndicator是Flutter里常见的下拉刷新组件,使用是比较方便的。但由于产品兄弟对其固定的刷新样式很是不满,而且代
- 背景实际开发中,常常需要将比较复杂的 JSON 字符串转换为对应的 Java 对象。这里记录下解决方案。如下所示,是入侵事件检测得到的 JS