作为一个每天和 PDF、图片、视频打交道的全栈开发者,我受够了打开电脑就要面对一堆付费软件的弹窗。PDF 转 Word 要充会员、图片压缩有次数限制、视频转 GIF 要下 App……一年下来,光软件订阅费就要花掉上千块。
于是去年下半年,我决定自己动手,用 Next.js + Spring Boot 搭了一个在线工具箱。目前集成了 42+ 个工具,覆盖 PDF 处理、图片/音视频编辑、格式转换、开发工具等 9 大类,全部免费开放基础额度。这篇文章记录一下技术选型和实现过程中踩过的坑。
一、技术架构总览
项目采用前后端分离架构,前端负责页面渲染和纯前端计算,后端负责文件处理和格式转换。
前端技术栈
• Next.js 13 (Pages Router) —— SSR + SSG 利于 SEO,API Routes 处理文件上传
• React 18 + TypeScript —— 类型安全,组件化开发
• TailwindCSS —— 原子化 CSS,快速迭代 UI
• pdf-lib —— 浏览器端 PDF 合并/拆分,敏感文件无需上传服务器
• FFmpeg.wasm(调研中)—— 纯前端视频处理,减少服务端压力
后端技术栈
• Java 17 + Spring Boot 3.2 —— 主服务框架
• MyBatis + MySQL 8.0 —— 用户、订单、工具配置数据
• Redis —— 热点缓存、限流令牌桶、用户额度计数
• Python 3.9 + pdf2docx/PyMuPDF/Pillow —— PDF/图片处理脚本
• FFmpeg —— 视频压缩、格式转换、GIF 生成
• Nginx —— 反向代理、SSL 证书、静态资源缓存
二、前端架构:一个页面如何承载 40+ 个工具
最开始我想给每个工具都写一个独立页面,但维护成本太高。42 个工具就是 42 个页面,一旦 UI 改版要改 42 次,不可接受。最终方案是「动态路由 + 配置化渲染」:
// 动态路由匹配所有工具页面 // pages/tools/[code].tsx const PURE_FRONTEND_TOOLS = [ 'batch_rename', 'qrcode_generator', 'chart_generator', 'regex_tester', 'markdown_editor', 'mind_map', 'flowchart' ]; export default function ToolDetailPage() { const router = useRouter(); const { code } = router.query; const backendCode = code.replace(/-/g, '_'); if (PURE_FRONTEND_TOOLS.includes(backendCode)) { router.replace('/tools/' + backendCode); return; } // 服务端工具动态获取配置渲染 const [tool, setTool] = useState(null); // 根据 toolCode 拉取工具配置和渲染对应表单 }
路由用短横线(SEO 友好),请求后端时转下划线(Java 命名规范)。纯前端工具直接走独立页面;需要服务端处理的工具走动态路由,根据后端返回的配置自动渲染上传区、参数表单和结果展示区。
三、后端架构:Spring Boot + Python 混合处理
文件格式转换的本质是「用专业工具处理文件」,Python 生态在 PDF、图片、音视频处理上有成熟库,而 Java 在 Web 服务、事务管理、权限控制上更擅长。所以最终采用 Java 主服务 + Python 脚本 的混合架构。
Java 主服务职责
• 接收 HTTP 请求,处理用户认证、额度校验 • 文件上传与临时存储(24 小时自动清理) • 调用 Python 脚本进行格式转换 • 返回处理结果 URL,支持断点续传和进度查询 • 限流防刷、订单管理、会员体系
Python 脚本职责
• PDF 转换:pdf2docx 实现 PDF 转 Word,PyMuPDF 实现 PDF 转图片/文本 • 图片处理:Pillow 实现压缩、格式转换、批量编辑、水印添加 • 视频处理:FFmpeg 命令行实现转码、压缩、GIF 生成 • 所有脚本通过 ProcessBuilder 调用,带超时控制和异常处理
// Spring Boot 调用 Python 脚本的简化示例 @Service public class PdfConvertService { public ConvertResult convertToDocx(File file) { ProcessBuilder pb = new ProcessBuilder( pythonPath, 'pdf_to_docx.py', file.getAbsolutePath() ); pb.redirectErrorStream(true); Process process = pb.start(); boolean finished = process.waitFor(120, TimeUnit.SECONDS); if (!finished) { process.destroyForcibly(); throw new RuntimeException('转换超时'); } // 读取输出文件并返回 URL } }
四、核心功能展示
目前平台已上线 42+ 个工具,按使用场景分为 9 大类:
- PDF 处理:PDF 转 Word/图片/HTML/文本、PDF 压缩、PDF 合并拆分
- Office 文档:Word 转 PDF、Excel 转 PDF、PPT 转 PDF/图片、Word 合并拆分
- 图片处理:图片压缩(支持网页/移动端/社交分享预设)、格式转换、批量编辑(水印/裁剪/滤镜/去背景)
- 音视频:视频转 GIF、音频提取、视频压缩、视频格式转换
- 设计可视化:思维导图、流程图、图表生成器、配色工具箱、截图美化、条形码生成
- 开发工具:正则表达式测试、编码解码、JSONPath 查询、SQL 格式化、Cron 解析、CSS 动画生成
- 计算转换:单位换算、IP 子网计算、财务计算、世界时钟
- 效率办公:二维码生成、批量重命名、屏幕录制、文件加密、电子签名、番茄钟
- 文本处理:文本处理工具箱、Markdown 编辑器
五、技术亮点与踩坑记录
亮点1:纯前端 PDF 处理
很多用户不愿意把敏感 PDF 上传到第三方服务器。针对这个痛点,我用 pdf-lib 实现了浏览器端 PDF 合并和拆分,文件完全在本地处理,不上传服务器。
// 前端 PDF 合并实现 const mergePdfsInFrontend = async (files) => { const { PDFDocument } = await import('pdf-lib'); const mergedPdf = await PDFDocument.create(); for (const file of files) { const pdf = await PDFDocument.load(await file.arrayBuffer()); const pages = await mergedPdf.copyPages(pdf, pdf.getPageIndices()); pages.forEach(p => mergedPdf.addPage(p)); } const blob = await mergedPdf.save(); return URL.createObjectURL(blob); };
踩坑:pdf-lib 对大文件(>50MB)处理时容易内存溢出,最终方案是「小文件纯前端,大文件走服务端」,用文件大小作为分界策略。
亮点2:FFmpeg 调用封装
视频处理是资源密集型操作,FFmpeg 参数复杂。我封装了一套参数模板,用户只需要选择「轻度/标准/强力」三档压缩,后台自动映射到对应的 CRF 值和预设。
// FFmpeg 视频压缩参数映射 Map<String, String[]> compressProfiles = Map.of( 'low', new String[]{'-crf', '23', '-preset', 'medium'}, 'medium', new String[]{'-crf', '28', '-preset', 'fast'}, 'high', new String[]{'-crf', '35', '-preset', 'fast'} );
亮点3:基于 Redis 的限流防刷
工具站容易被爬虫和恶意刷量,我用 Redis 实现了令牌桶限流:每个 IP 每秒允许 N 个请求,超出后返回 429。同时结合用户额度体系,未登录用户单工具限 1 次,登录用户每月 3 次免费额度,会员无限次。
// 简化版令牌桶限流 public boolean allowRequest(String key, int maxRequests, int windowSeconds) { String redisKey = 'rate_limit:' + key; Long current = redisTemplate.opsForValue().increment(redisKey); if (current == 1) { redisTemplate.expire(redisKey, windowSeconds, TimeUnit.SECONDS); } return current <= maxRequests; }
六、免费额度与商业模式
平台采用「免费额度 + 会员付费」模式。普通用户每个工具每月有 3 次免费额度,签到还能获得通用次数。日常轻度使用完全不用花钱。
如果需要高频使用,会员价格也很接地气:月卡 19.9(首月 9.9)、年卡 99.9、三年卡 199、永久卡 499。年卡算下来每天 2 毛 7,比动辄几百块的年费软件便宜太多了。
七、后续计划
- 陆续开源部分前端组件(PDF 处理、图片编辑等纯前端模块) 2. 接入 FFmpeg.wasm,实现更多视频处理的纯前端化 3. 增加更多开发者工具(API 测试、代码对比、Git 命令查询等) 4. 优化移动端体验,目前主要适配 PC 端
写在最后
这个项目从构想到上线花了大概 3 个月,目前已经稳定运行,日活 1000+。如果你也有类似的工具需求,或者对某个功能的实现感兴趣,欢迎评论区交流。
项目地址:gjupai.com,后续会逐步开源核心模块,欢迎关注 有问题评论区见,看到都会回复。