当前位置: 首页 > news >正文

2025年的最后一天,分享我使用go语言开发的电子书转换工具网站

前言

基于 Web 的小说转换工具,支持将 txt 文件转换为 epub、mobi、azw3 等电子书格式

其实这个项目是今年八月做的,一直没有分享。

之前在找txt电子书转换EPUB工具的时候,很多都是有广告的,在GitHub上找到一个go开发的命令行工具:kaf-cli ,挺好用的,不过每次都要输入命令有点麻烦,所以我就用go-gin做成了网站,方便时候。

发在了读书群里,也有很多人在使用。

不过最近这个网站已经让我的服务器不堪重负,只能被迫暂停了。

本文简单分享一下这个网站,作为2025年的收尾吧~

这个项目还催生了 Alpine.js 实现国际化的功能。


本项目是从 ystyle/kaf-cli fork 而来,在保留原有命令行功能的基础上,新增了 Web 可视化界面,提供更便捷的使用体验。

项目地址: https://github.com/Deali-Axy/ebook-generator

主要特性

🌐 Web 功能

  • 📁 文件上传:支持 txt 文件上传,最大 50MB
  • 🔄 格式转换:支持转换为 epub、mobi、azw3 格式
  • 📊 实时进度:通过 SSE 实时查看转换进度
  • 📥 文件下载:转换完成后可下载电子书文件
  • 🗑️ 自动清理:支持手动清理临时文件
  • 📖 API 文档:集成 Swagger UI,方便调试
  • 🎨 可视化界面:简洁易用的 HTML 界面

📚 转换功能

  • 自动识别书名和章节
  • 自动识别字符编码(解决中文乱码)
  • 自定义章节标题识别规则
  • 自定义卷的标题识别规则
  • 自动给章节正文生成加粗居中的标题
  • 段落自动识别和缩进
  • 支持生成 Orly 风格的书籍封面
  • 知轩藏书格式文件名自动提取书名和作者
  • 超快速转换(epub 格式生成 300 章/s 以上速度)

截图

主页面

转换进度和下载

web代码

简单贴一些代码吧,其实我还做了登录注册功能的,不过有bug,前端就没搭配加上去了~

// main 启动Web服务
func main() {// 设置Gin模式if os.Getenv("GIN_MODE") == "" {gin.SetMode(gin.DebugMode)}// 初始化服务管理器serviceManager, err := initServiceManager()if err != nil {log.Fatal("初始化服务管理器失败:", err)}// 启动所有服务if err := serviceManager.Start(); err != nil {log.Fatal("启动服务失败:", err)}// 设置优雅关闭defer func() {if err := serviceManager.Stop(); err != nil {log.Printf("停止服务时出错: %v", err)}}()// 初始化Web服务相关组件initWebServices(serviceManager)// 创建Gin引擎r := gin.Default()// 初始化SEO服务seoService := initSEOService()// 添加中间件r.Use(middleware.CORS())r.Use(middleware.Logger())r.Use(middleware.Recovery())r.Use(middleware.AddSecurityHeaders())r.Use(middleware.AddCacheHeaders())r.Use(middleware.SEOMiddleware(seoService))// 设置文件上传大小限制 (50MB)r.MaxMultipartMemory = 50 << 20// API路由组api := r.Group("/api"){// 基础转换功能api.POST("/upload", handlers.UploadFile)api.POST("/convert", handlers.ConvertBook)api.GET("/status/:taskId", handlers.GetTaskStatus)api.GET("/download/:fileId", handlers.DownloadFile)api.DELETE("/cleanup/:taskId", handlers.CleanupTask)api.GET("/events/:taskId", handlers.GetTaskEvents)// 用户认证相关路由auth := api.Group("/auth"){auth.POST("/register", handlers.Register)auth.POST("/login", handlers.Login)auth.GET("/profile", handlers.AuthMiddleware(), handlers.GetProfile)auth.PUT("/profile", handlers.AuthMiddleware(), handlers.UpdateProfile)auth.POST("/logout", handlers.AuthMiddleware(), handlers.Logout)auth.POST("/refresh", handlers.AuthMiddleware(), handlers.RefreshToken)auth.PUT("/password", handlers.AuthMiddleware(), handlers.ChangePassword)}// 转换历史相关路由(需要认证)history := api.Group("/history")history.Use(handlers.AuthMiddleware()){history.GET("", handlers.GetHistories)history.GET("/stats", handlers.GetHistoryStats)history.DELETE("/:id", handlers.DeleteHistory)}// 转换预设相关路由(需要认证)presets := api.Group("/presets")presets.Use(handlers.AuthMiddleware()){presets.POST("", handlers.CreatePreset)presets.GET("", handlers.GetPresets)presets.GET("/:id", handlers.GetPreset)presets.PUT("/:id", handlers.UpdatePreset)presets.DELETE("/:id", handlers.DeletePreset)}// 批量转换相关路由(需要认证)batch := api.Group("/batch")batch.Use(handlers.AuthMiddleware()){batch.POST("/convert", handlers.BatchConvert)}}// 集成Swagger文档r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))// 静态文件服务r.Static("/static", "./web/static")r.StaticFile("/", "./web/static/index.html")r.StaticFile("/demo", "./web/static/index.html")// SEO相关文件 - 动态生成r.GET("/sitemap.xml", handlers.GenerateSitemap)r.GET("/robots.txt", handlers.GenerateRobotsTxt)// SEO状态监控seo := r.Group("/seo"){seo.GET("/status", handlers.GetSEOStatus)}// 健康检查接口r.GET("/health", func(c *gin.Context) {c.JSON(200, gin.H{"status": "ok"})})// 启动服务port := os.Getenv("PORT")if port == "" {port = "8080"}log.Printf("服务启动在端口: %s", port)log.Printf("Swagger文档地址: http://localhost:%s/swagger/index.html", port)if err := r.Run(":" + port); err != nil {log.Fatal("启动服务失败:", err)}
}

小结

就这样吧,时间不早了,祝大家新年快乐吧~

http://www.jsqmd.com/news/337709/

相关文章:

  • 2026年普拉提教练培训学校及大器械课程推荐 - 品牌2025
  • 2026年深圳离婚纠纷律师电话推荐:资深专家联系指南 - 十大品牌推荐
  • AI英语口语APP的开发
  • 2026年 力士乐PV7-1A/10-14RE01MC0-16液压泵厂家推荐榜:精密动力与稳定性能的工业核心之选 - 品牌企业推荐师(官方)
  • Instagram 养号机器人指南(2026):自动化原理、防封技巧与工具推荐
  • 滑轨铰链哪个品牌好耐用?一文读懂如何选对耐用五金品牌
  • 美国SDE求职辅导哪家强:技术辅导专业榜单 - 技研备忘录
  • 极简主义建筑空镜头素材哪里找?10个网站推荐
  • 缓冲滑轨品牌推荐,如何选对抽屉的“隐形核心”?
  • 全自动汽油氧化安定性测定仪的技术解析与应用价值研究
  • 2026年天津离婚财产纠纷律师联系电话推荐:核心律师联系渠道一览 - 十大品牌推荐
  • 深度测评8个降AIGC网站,千笔·降AIGC助手解决论文AI率过高难题
  • HTTP response
  • 极简版 TeamViewer,一个基于 C# 开发的便携、免费远程桌面工具
  • BUUCTF刷题MISC[五] (53-64)
  • 2026年深圳离婚纠纷律师联系电话推荐:专业律师联系指南 - 十大品牌推荐
  • 【无人机控制】多旋翼无人机横向动力学的鲁棒控制【含Matlab源码 15051期】
  • abc 3
  • 打造低成本红队物联网硬件植入设备指南
  • 2026河南系统窗品牌推荐指南 - 真知灼见33
  • 服务器端请求伪造(SSRF)漏洞解析
  • 2026年天津离婚财产纠纷律师联系电话推荐:专业律师团队联系指引 - 十大品牌推荐
  • 2026年天津离婚财产纠纷律师联系电话推荐:核心律师资源汇总 - 十大品牌推荐
  • 韩国英拓克ID261/70A/220V现场控制器
  • 递归函数 - 练习5
  • 救命神器8个降AI率网站推荐!千笔AI帮你轻松降AIGC
  • AIGC降重全指南:从工具选择到完美定稿
  • 哈尔滨木盒定制制造商哪家好,优质生产商为你揭晓 - myqiye
  • 2026年天津离婚财产纠纷律师联系电话推荐:高效解决财产争议指南 - 十大品牌推荐
  • 韩国英拓克ID261/70A/380V现场控制器