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

如何在Java Swing中打开/查看.doc/.pdf及数据库存储的对应文件?

我来帮你搞定这两个Java Swing里处理文档的问题,都是开发中常碰到的场景,咱们一步步拆解:

一、在Java Swing应用中打开/查看本地的.doc/.pdf文件

处理PDF文件

有两种常见方式:内嵌到Swing界面查看或者调用系统默认程序打开。

1. 内嵌查看(推荐用Apache PDFBox)

PDFBox是Apache的开源库,能直接把PDF页面渲染成图片,放到Swing组件里展示。
首先你需要引入依赖(Maven为例):

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.32</version>
</dependency>

然后写个简单的示例代码,把PDF渲染到JScrollPane里:

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import javax.swing.*;
import java.awt.*;
import java.io.File;

public class PdfViewer extends JFrame {
    public PdfViewer(File pdfFile) {
        setTitle("PDF Viewer");
        setSize(800, 600);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        try (PDDocument document = PDDocument.load(pdfFile)) {
            PDFRenderer renderer = new PDFRenderer(document);
            JPanel panel = new JPanel(new GridLayout(document.getNumberOfPages(), 1));

            for (int i = 0; i < document.getNumberOfPages(); i++) {
                Image image = renderer.renderImageWithDPI(i, 96); // 96DPI和屏幕匹配
                panel.add(new JLabel(new ImageIcon(image)));
            }

            add(new JScrollPane(panel));
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "加载PDF失败:" + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new PdfViewer(new File("your-file.pdf")).setVisible(true));
    }
}

2. 调用系统默认程序打开

如果不需要内嵌,直接让系统自带的PDF阅读器打开更简单,用Java的Desktop类:

import java.awt.Desktop;
import java.io.File;

public class OpenPdfWithSystem {
    public static void openPdf(File pdfFile) {
        if (Desktop.isDesktopSupported()) {
            try {
                Desktop.getDesktop().open(pdfFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

处理.doc文件

Java没有原生支持doc格式,得借助第三方库,或者直接调用系统程序:

1. 读取文本内容并内嵌展示(用Apache POI HWPF)

HWPF是POI专门处理旧版.doc文件的组件,能读取文本内容(格式可能会丢失,要保留复杂格式的话比较麻烦)。
先引入依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-scratchpad</artifactId>
    <version>5.2.3</version>
</dependency>

然后写代码读取并显示在JTextPane里:

import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.extractor.WordExtractor;
import javax.swing.*;
import java.io.File;

public class DocViewer extends JFrame {
    public DocViewer(File docFile) {
        setTitle("DOC Viewer");
        setSize(800, 600);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        JTextPane textPane = new JTextPane();
        textPane.setEditable(false);
        add(new JScrollPane(textPane));

        try (HWPFDocument document = new HWPFDocument(docFile.toPath())) {
            WordExtractor extractor = new WordExtractor(document);
            textPane.setText(extractor.getText());
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "加载DOC失败:" + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new DocViewer(new File("your-file.doc")).setVisible(true));
    }
}

2. 调用系统默认程序打开

和PDF一样,用Desktop类直接打开,简单省心:

import java.awt.Desktop;
import java.io.File;

public class OpenDocWithSystem {
    public static void openDoc(File docFile) {
        if (Desktop.isDesktopSupported()) {
            try {
                Desktop.getDesktop().open(docFile);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
二、打开/查看存储在数据库(longblob)中的.pdf/.doc文件

核心思路是:把数据库里的二进制Blob数据导出到临时文件,然后就可以用上面本地文件的处理方法来查看了。毕竟大多数文档处理库都是基于文件路径或输入流工作的,临时文件是最通用的方案。

步骤1:从数据库读取Blob数据并写入临时文件

假设你的FileAttachment类有getFileData()方法返回Blob对象(或者直接返回InputStream),Dao层的方法大概是这样:

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Blob;

public class FileDao {
    // 假设这是你从数据库获取FileAttachment的方法
    public FileAttachment getFileAttachmentById(long id) {
        // 这里写你的JDBC/JPA查询逻辑,返回FileAttachment对象
        return null;
    }

    // 把Blob转成临时文件
    public File blobToTempFile(Blob blob, String fileExtension) throws Exception {
        // 创建临时文件,比如temp-xxxx.pdf
        File tempFile = File.createTempFile("temp-", "." + fileExtension);
        tempFile.deleteOnExit(); // 程序退出时自动删除临时文件

        try (InputStream is = blob.getBinaryStream();
             FileOutputStream fos = new FileOutputStream(tempFile)) {
            byte[] buffer = new byte[1024];
            int bytesRead;
            while ((bytesRead = is.read(buffer)) != -1) {
                fos.write(buffer, 0, bytesRead);
            }
        }
        return tempFile;
    }
}

步骤2:用临时文件打开文档

拿到临时文件后,就可以复用上面本地文件的代码了,比如查看PDF:

public class DbDocumentViewer {
    public static void viewPdfFromDb(long fileId) {
        FileDao dao = new FileDao();
        FileAttachment attachment = dao.getFileAttachmentById(fileId);

        try {
            File tempPdf = dao.blobToTempFile(attachment.getFileData(), "pdf");
            // 用之前的内嵌查看方法
            SwingUtilities.invokeLater(() -> new PdfViewer(tempPdf).setVisible(true));
            // 或者调用系统程序:OpenPdfWithSystem.openPdf(tempPdf);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "加载数据库中的PDF失败:" + e.getMessage());
            e.printStackTrace();
        }
    }

    public static void viewDocFromDb(long fileId) {
        FileDao dao = new FileDao();
        FileAttachment attachment = dao.getFileAttachmentById(fileId);

        try {
            File tempDoc = dao.blobToTempFile(attachment.getFileData(), "doc");
            // 用内嵌查看方法
            SwingUtilities.invokeLater(() -> new DocViewer(tempDoc).setVisible(true));
            // 或者调用系统程序:OpenDocWithSystem.openDoc(tempDoc);
        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, "加载数据库中的DOC失败:" + e.getMessage());
            e.printStackTrace();
        }
    }
}

注意点

  • 临时文件记得设置deleteOnExit(),避免磁盘占用过多;也可以在关闭查看窗口时手动删除。
  • 如果你的FileAttachment类存储的是byte[]而不是Blob,那直接把byte[]写入临时文件就行,逻辑更简单。
  • 大文件的话,建议用流的方式逐步写入,不要一次性加载到内存里,避免OOM。

内容的提问来源于stack exchange,提问作者Anirudh Lou

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 07:22:41