使用 Spring Boot 显示从 MySQL 到 Thymeleaf 的文件(pdf、doc、ppt)

Posted

技术标签:

【中文标题】使用 Spring Boot 显示从 MySQL 到 Thymeleaf 的文件(pdf、doc、ppt)【英文标题】:Display files (pdf, doc, ppt) from MySQL to Thymeleaf with Spring Boot 【发布时间】:2020-12-31 03:21:49 【问题描述】:

我正在尝试在页面上显示一些文档。 我已将它们保存在数据库中,但我不确定如何继续在网站上显示它们并使其可下载。 文件格式为(pdf、doc、ppt)。如果有人可以提出建议,我将不胜感激。

这是文件实体:

@Entity
@Table(name = "chapter_files")
public class File 

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "file_id")
    private Long id;
    
    @Column(name = "file_name")
    private String fileName;
    
    @Column(name = "file")
    @Lob
    private byte[] file;
    
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="chapter_id")
    private Chapter chapter;

这是 mysql 表创建查询:

CREATE TABLE `chapter_files` (
    `file_id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `file_name` VARCHAR(50) NOT NULL,
    `file` LONGTEXT NOT NULL,
    `chapter_id` BIGINT(20) NOT NULL,
    PRIMARY KEY (`file_id`),
    INDEX `FKChapter` (`chapter_id`),
    CONSTRAINT `FKChapter` FOREIGN KEY (`chapter_id`) REFERENCES `chapters` (`chapter_id`)
)

这是将文件保存在数据库中的Service类方法:

public File saveFiles(MultipartFile file, Chapter chapter) 
        File doc = new File();
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());
        doc.setFileName(fileName);
        try 
            doc.setFile(file.getBytes());
            doc.setChapter(chapter);
         catch (IOException e) 
            e.printStackTrace();
        
        return fileRepository.save(doc);
    

我不确定如何在页面上显示文件并使其可下载。如果您有任何建议或我可以阅读的任何文章,我很乐意关注。

【问题讨论】:

【参考方案1】:

这应该适用于您的常规 Spring MVC 应用程序:

步骤如下:

将 HttpServletResponse 注入您的控制器方法 从数据库中读取文件数据 设置内容类型和标题 将字节数组写入输出流
    import org.springframework.stereotype.Controller;
    import org.springframework.util.MimeTypeUtils;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.OutputStream;
    
    @Controller
    @RequestMapping("/download")
    public class DownloadController 
    
        @GetMapping("/file/id")
        public void downloadFile(@PathVariable Long fileId, HttpServletResponse resp) throws IOException 
    
            File dbFile = fileRepository.readFile(fileId);
    
            byte[] byteArray =  dbFile.getFile(); // read the byteArray
    
            resp.setContentType(MimeTypeUtils.APPLICATION_OCTET_STREAM.getType()); 
            resp.setHeader("Content-Disposition", "attachment; filename=" + dbFile.fileName());
            resp.setContentLength(byteArray.length);
    
            OutputStream os = resp.getOutputStream();
            try 
                os.write(byteArray, 0, byteArray.length);
             finally 
                os.close();
            
    
        
    

在您的 Thymeleaf 模板中,您可以使用以下内容创建下载文件的链接:

  <a th:href="@/download/file/id(id=$file.id)">
         <span th:text="$file.fileName">Download</span>
  </a>

如果你想从磁盘读取文件并下载,你可能需要做类似这样的事情:https://github.com/gtiwari333/spring-boot-web-application-seed/blob/master/main-app/src/main/java/gt/app/web/mvc/DownloadController.java

另外,如果您使用的是 SPA,例如:AngularJS/Angular 等客户端,那么您可能需要采用稍微不同的方法。示例请参见此处。

http://ganeshtiwaridotcomdotnp.blogspot.com/2017/01/angularjs-download-file-from-server.html

【讨论】:

输出流write 方法有一个接收字节数组的重载版本。这意味着os.write(byteArray) 的工作方式与指定偏移量和字节数组长度的方式相同。认为少一点代码可能会有所帮助?

以上是关于使用 Spring Boot 显示从 MySQL 到 Thymeleaf 的文件(pdf、doc、ppt)的主要内容,如果未能解决你的问题,请参考以下文章

从 Spring Boot 应用程序连接到 mysql 容器

无法从 Spring Boot Docker 容器连接 mysql Docker 容器

无法从Spring Boot Docker容器连接到本地MySQL数据库服务器

无法使用spring boot连接到mysql数据库

如何从 html 表单中获取“日期和时间”输入并使用 Spring Boot 保存到 MySQL 数据库中?

Spring Boot 从 mysql 创建重复记录