You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin PDF Viewer 1.0.2版本字节转PDF及StreamResource复用问题咨询

Vaadin PDF Viewer 1.0.2 字节数据显示与保存解决方案

针对无法升级到修复版本、StreamResource无法二次使用的问题,提供以下几种可行方案:

方案1:自定义可重复读取的资源实现

创建自定义Resource类,确保每次访问都生成新的输入流,避免流读取一次后耗尽:

import com.vaadin.flow.server.StreamResource;
import com.vaadin.flow.server.StreamResourceWriter;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;

public class ReusableByteArrayResource extends StreamResource {
    private final byte[] content;

    public ReusableByteArrayResource(String filename, byte[] content) {
        super(filename, (StreamResourceWriter) outputStream -> {
            try (ByteArrayInputStream inputStream = new ByteArrayInputStream(content)) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
            } catch (IOException e) {
                throw new RuntimeException("写入PDF内容失败", e);
            }
        });
        this.content = content;
    }
}

替换原StreamResource使用:

byte[] pdfBytes = ...; // 你的PDF字节数据
String filename = "document.pdf";
ReusableByteArrayResource pdfResource = new ReusableByteArrayResource(filename, pdfBytes);
pdfViewer.setSrc(pdfResource);

方案2:使用临时文件作为资源载体

将字节数据写入临时文件,利用FileResource支持多次读取的特性:

import com.vaadin.flow.server.FileResource;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

// 创建临时PDF文件
File tempFile = File.createTempFile("pdf-viewer-", ".pdf");
try (FileOutputStream fos = new FileOutputStream(tempFile)) {
    fos.write(pdfBytes);
} catch (IOException e) {
    throw new RuntimeException("创建临时PDF文件失败", e);
}

// 设置JVM退出时自动删除文件
tempFile.deleteOnExit();

// 绑定到PDF Viewer
FileResource pdfResource = new FileResource(tempFile);
pdfViewer.setSrc(pdfResource);

可选:在视图销毁时手动清理临时文件,避免磁盘占用:

addDetachListener(event -> {
    if (tempFile.exists()) {
        tempFile.delete();
    }
});

方案3:自定义下载按钮绕过组件内置逻辑

隐藏组件自带下载按钮,添加自定义按钮直接用Vaadin原生下载功能:

  1. 隐藏内置按钮(添加到视图样式):
:host ::part(toolbar-download) {
    display: none;
}
  1. 添加自定义下载按钮:
Button downloadBtn = new Button("下载PDF", e -> {
    StreamResource resource = new StreamResource(filename, () -> new ByteArrayInputStream(pdfBytes));
    UI.getCurrent().download(resource);
});
add(downloadBtn, pdfViewer);

内容的提问来源于stack exchange,提问作者RabiaKırım

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:22:46