【问题标题】:Display files (pdf, doc, ppt) from MySQL to Thymeleaf with Spring Boot使用 Spring Boot 显示从 MySQL 到 Thymeleaf 的文件(pdf、doc、ppt)
【发布时间】: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);
    }

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

【问题讨论】:

    标签: mysql spring-boot thymeleaf multifile-uploader


    【解决方案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) 的工作方式与指定偏移量和字节数组长度的方式相同。认为少一点代码可能会有所帮助?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多