在项目开发中,文件的在线预览是常见的需求,尤其是对 PDF、Word、Excel 等格式的文件进行无客户端依赖的直接查看。本文将介绍如何通过 MinIO 和 KKFileView 搭建在线文件预览服务,并通过 docker-compose
一键部署。
一、环境准备
1. Docker 安装
在 CentOS 系统上,使用以下命令安装 Docker:
# 更新 yum 包索引
sudo yum update -y
# 安装 Docker
sudo yum install -y docker
# 启动 Docker 并设置开机启动
sudo systemctl start docker
sudo systemctl enable docker
2. 安装 Docker Compose
Docker Compose 是管理多个容器服务的工具,可以用以下命令安装:
# 下载最新版本的 Docker Compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose
# 验证安装
docker-compose --version
二、服务介绍
1. MinIO
MinIO 是一款高性能的对象存储服务,兼容 AWS S3 API,支持存储海量的文件对象。我们将使用它来管理和存储待预览的文件。
2. KKFileView
KKFileView 是一款轻量级文件在线预览服务,支持多种文件格式(如 PDF、Office 文档、图片等)的预览。通过与 MinIO 集成,可以实现从对象存储中读取文件并进行在线预览。
三、使用 Docker Compose 部署 MinIO 和 KKFileView
以下是 docker-compose.yml
文件的完整内容:
# 描述 Compose 文件的版本信息
version: "2.1"
# 定义服务,可以多个
services:
minio:
image: minio/minio:latest
container_name: minio
ports:
- "9090:9000" # MinIO 服务端口
- "9001:9001" # MinIO 控制台地址端口
environment:
MINIO_ROOT_USER: minioadmin # MinIO 管理用户名
MINIO_ROOT_PASSWORD: minioadmin # MinIO 管理密码
volumes:
- /mydata/minio/data:/data # 数据存储挂载路径
command: server /data --console-address ":9001" # 启动命令,指定控制台端口
restart: always # 保证容器自动重启
kkfileview:
image: keking/kkfileview:latest
container_name: kkfileview
ports:
- "8012:8012" # KKFileView 服务端口
restart: always # 保证容器自动重启
部署步骤
- 将
docker-compose.yml
文件保存至/root/minio/
目录下。 - 执行以下命令启动服务:
cd /root/minio/ docker-compose up -d
我这里放在/home/app/minio目录的minio-docker-compose.yml中然后分别执行
docker-compose -f minio-docker-compose.yml up -d minio
docker-compose -f minio-docker-compose.yml up -d kkfileview
- 验证服务是否启动:
docker ps
输出示例:
[root@lps minio]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dc6bfe8f99c6 keking/kkfileview:latest "java -Dfile.encodin…" 7 minutes ago Up 7 minutes 0.0.0.0:8012->8012/tcp, :::8012->8012/tcp kkfileview
02d7a1418809 minio/minio:latest "/usr/bin/docker-ent…" 8 minutes ago Up 8 minutes 0.0.0.0:9001->9001/tcp, :::9001->9001/tcp, 0.0.0.0:9090->9000/tcp, :::9090->9000/tcp minio
四、功能配置
1. 配置 MinIO 存储文件
- 访问 MinIO 控制台:
http://<服务器IP>:9001
- 登录凭据:
- 用户名:
minioadmin
- 密码:
minioadmin
- 用户名:
- 创建一个存储桶(Bucket),用于存储上传的文件。例如,创建
preview
。
然后设置为公开
上传一些测试用例图片或者文件
2. 配置 KKFileView
KKFileView 默认监听 8012
端口,无需复杂配置即可访问:
- 访问地址:
http://<服务器IP>:8012/index
- 上传文件测试:上传文件后,点击“预览”按钮即可在线查看。
3. 集成 MinIO 和 KKFileView
将 MinIO 中的文件链接作为 KKFileView 的输入文件地址进行在线预览:
前端测试demo
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件预览带水印 Demo</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
.container {
max-width: 400px;
margin: 0 auto;
}
input[type="text"] {
width: 100%;
padding: 10px;
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 5px;
box-sizing: border-box;
}
button {
width: 100%;
padding: 10px;
background-color: #007BFF;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #0056b3;
}
/* 模态框样式 */
.modal {
display: none;
position: fixed;
z-index: 1000;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
justify-content: center;
align-items: center;
}
.modal-content {
position: relative;
background: white;
padding: 20px;
width: 80%;
height: 80%;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
border-radius: 8px;
overflow: hidden;
}
.modal-close {
position: absolute;
top: 10px;
right: 10px;
font-size: 20px;
cursor: pointer;
color: #333;
}
iframe {
width: 100%;
height: 100%;
border: none;
}
</style>
</head>
<body>
<h1>文件预览工具</h1>
<form id="previewForm">
<label for="fileUrl">请输入文件的 URL:</label>
<input type="text" id="fileUrl" placeholder="http://example.com/file.docx">
<br><br>
<label for="watermarkText">请输入水印内容:</label>
<input type="text" id="watermarkText" placeholder="请输入水印文本">
<br><br>
<button type="button" onclick="previewFile()">预览文件</button>
</form>
<!-- 模态框结构 -->
<div id="previewModal" class="modal">
<div class="modal-content">
<span class="modal-close" onclick="closeModal()">×</span>
<iframe id="previewFrame" src=""></iframe>
</div>
</div>
<script>
/**
* Base64 编码函数
* @param {string} str - 需要编码的字符串
* @returns {string} Base64 编码后的字符串
*/
function base64Encode(str) {
return btoa(unescape(encodeURIComponent(str)));
}
/**
* 文件预览功能
*/
function previewFile() {
// 获取用户输入的文件 URL 和水印内容
const fileUrl = document.getElementById('fileUrl').value.trim();
const watermarkText = document.getElementById('watermarkText').value.trim();
// 验证输入
if (!fileUrl) {
alert('请输入文件的 URL!');
return;
}
// 默认水印内容
const watermark = watermarkText || '默认水印';
try {
// 对 URL 进行 Base64 编码
const encodedUrl = base64Encode(fileUrl);
// 构造预览链接(水印不编码,直接明文传递)
const previewUrl = `http://192.168.246.239:8012/onlinePreview?url=${encodedUrl}&watermarkTxt=${encodeURIComponent(watermark)}`;
// 在模态框中显示预览内容
const iframe = document.getElementById('previewFrame');
iframe.src = previewUrl;
// 打开模态框
openModal();
} catch (error) {
alert('编码失败,请检查输入内容是否有效!');
console.error(error);
}
}
/**
* 打开模态框
*/
function openModal() {
const modal = document.getElementById('previewModal');
modal.style.display = 'flex';
}
/**
* 关闭模态框
*/
function closeModal() {
const modal = document.getElementById('previewModal');
modal.style.display = 'none';
// 清空 iframe 内容,避免页面卡顿
const iframe = document.getElementById('previewFrame');
iframe.src = '';
}
</script>
</body>
</html>
五、总结
通过 MinIO 和 KKFileView,我们实现了高效的文件存储和在线预览功能。MinIO 提供对象存储服务,KKFileView 提供预览能力,两者结合满足了多种办公场景需求。借助 docker-compose
,我们实现了快速部署和服务管理,为开发和运维提供了便利。