EPBU/MOBI转PDF

--痛苦

--不爱BB 直接上码。 

 

写了一个java方法,转epub 或者mobi 为 pdf的方法 (单个转换)

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

public class EbookConverter {

    public static void main(String[] args) {
        try {
            // 桌面路径
            String userHome = System.getProperty("user.home");
            String desktopPath = userHome + File.separator + "Desktop";

            // 输入文件名(包括扩展名)
            String inputFileName = "example.epub"; // 修改为实际文件名

            // 输入文件路径
            String inputFilePath = desktopPath + File.separator + inputFileName;

            // 输出文件路径(更改扩展名为 .pdf)
            String outputFileName = inputFileName.substring(0, inputFileName.lastIndexOf('.')) + ".pdf";
            String outputFilePath = desktopPath + File.separator + outputFileName;

            // 转换文件
            convertEbookToPdf(inputFilePath, outputFilePath);
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void convertEbookToPdf(String inputFilePath, String outputFilePath) throws IOException, InterruptedException {
        // 判断文件格式
        String fileExtension = getFileExtension(inputFilePath).toLowerCase();

        if (!fileExtension.equals("epub") && !fileExtension.equals("mobi")) {
            throw new IllegalArgumentException("Unsupported file format. Only EPUB and MOBI are supported.");
        }

        // 使用 Calibre 的 ebook-convert 工具
        String command = String.format("ebook-convert \"%s\" \"%s\"", inputFilePath, outputFilePath);

        // 启动进程
        Process process = Runtime.getRuntime().exec(command);
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        // 记录开始时间
        long startTime = System.currentTimeMillis();

        // 读取输出并显示进度
        String line;
        while ((line = reader.readLine()) != null || (line = errorReader.readLine()) != null) {
            // 这里我们假设输出包含进度信息,可以根据具体的输出格式进行调整
            if (line.contains("%")) {
                System.out.println(line); // 打印带有百分比的行
            }
        }

        int exitCode = process.waitFor();

        // 记录结束时间
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;

        if (exitCode != 0) {
            throw new IOException("Error during conversion process. Exit code: " + exitCode);
        }

        System.out.println("Conversion successful: " + outputFilePath);
        System.out.println("Time taken: " + (duration / 1000) + " seconds");
    }

    private static String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
            return fileName.substring(dotIndex + 1);
        }
        return "";
    }
}

 

代码说明

  1. 启动进程:使用Runtime.getRuntime().exec(command)启动ebook-convert命令,并创建BufferedReader对象读取进程的标准输出和错误输出。
  2. 记录时间:在转换开始时记录开始时间,转换完成后记录结束时间,并计算耗时。
  3. 读取输出:在while循环中读取进程输出,并假设输出包含进度信息(例如百分比)。实际情况下,ebook-convert的输出格式需要根据具体情况调整解析方式。
  4. 显示进度:将包含百分比信息的行打印到控制台,模拟显示进度。
  5. 显示耗时:转换完成后,打印耗时信息。

注意事项

  • 进度信息ebook-convert工具的标准输出可能不包含详细的进度信息,需根据实际输出格式进行解析和调整。
  • 错误处理:在实际应用中,应增加更多的错误处理逻辑,例如捕获和处理可能的异常情况。
  • 优化:如果需要更详细和准确的进度更新,可以考虑使用支持更丰富反馈信息的转换工具或库。

 写了一个java方法,转epub 或者mobi 为 pdf的方法 (批量转换)

 以下是一个Java程序,用于批量将指定目录下的所有EPUB或MOBI文件转换为PDF文件,并将转换后的PDF文件保存到同一目录中,保持相同的文件名但后缀为PDF。

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

public class BatchEbookConverter {

    public static void main(String[] args) {
        // 指定要处理的目录路径
        String directoryPath = "C:\\Users\\Administrator\\Downloads\\pdf"; // 修改为实际目录路径

        File directory = new File(directoryPath);

        System.out.println("目录路径"+directoryPath);
        if (!directory.isDirectory()) {
            System.err.println("The provided path is not a directory.");
            System.exit(1);
        }

        File[] files = directory.listFiles((dir, name) -> name.toLowerCase().endsWith(".epub") || name.toLowerCase().endsWith(".mobi"));

        if (files == null || files.length == 0) {
            System.out.println("No EPUB or MOBI files found in the directory.");
            return;
        }

        for (File file : files) {
            String inputFilePath = file.getAbsolutePath();
            String outputFilePath = inputFilePath.substring(0, inputFilePath.lastIndexOf('.')) + ".pdf";

            try {
                convertEbookToPdf(inputFilePath, outputFilePath);
            } catch (IOException | InterruptedException e) {
                System.err.println("Failed to convert file: " + inputFilePath);
                e.printStackTrace();
            }
        }
    }

    public static void convertEbookToPdf(String inputFilePath, String outputFilePath) throws IOException, InterruptedException {
        // 判断文件格式
        String fileExtension = getFileExtension(inputFilePath).toLowerCase();

        if (!fileExtension.equals("epub") && !fileExtension.equals("mobi")) {
            throw new IllegalArgumentException("Unsupported file format. Only EPUB and MOBI are supported.");
        }

        // 使用 Calibre 的 ebook-convert 工具
        String command = String.format("ebook-convert \"%s\" \"%s\"", inputFilePath, outputFilePath);

        // 启动进程
        Process process = Runtime.getRuntime().exec(command);
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        BufferedReader errorReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));

        // 记录开始时间
        long startTime = System.currentTimeMillis();

        // 读取输出并显示进度
        String line;
        while ((line = reader.readLine()) != null || (line = errorReader.readLine()) != null) {
            // 这里我们假设输出包含进度信息,可以根据具体的输出格式进行调整
            if (line.contains("%")) {
                System.out.println(line); // 打印带有百分比的行
            }
        }

        int exitCode = process.waitFor();

        // 记录结束时间
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;

        if (exitCode != 0) {
            throw new IOException("Error during conversion process. Exit code: " + exitCode);
        }

        System.out.println("Conversion successful: " + outputFilePath);
        System.out.println("Time taken: " + (duration / 1000) + " seconds");
    }

    private static String getFileExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex > 0 && dotIndex < fileName.length() - 1) {
            return fileName.substring(dotIndex + 1);
        }
        return "";
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/633927.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【HarmonyOS4学习笔记】《HarmonyOS4+NEXT星河版入门到企业级实战教程》课程学习笔记(八)

课程地址&#xff1a; 黑马程序员HarmonyOS4NEXT星河版入门到企业级实战教程&#xff0c;一套精通鸿蒙应用开发 &#xff08;本篇笔记对应课程第 15 节&#xff09; P15《14.ArkUI组件-状态管理state装饰器》 回到最初的 Hello World 案例&#xff0c;首先验证 如果删掉 State…

【BSP开发经验】用户态栈回溯技术

前言 在内核中有一个非常好用的函数dump_stack, 该函数在我们调试内核的过程中可以打印出函数调用关系&#xff0c;该函数可以帮助我们进行内核调试&#xff0c;以及让我们了解内核的调用关系。同时当内核发生崩溃的时候就会自己将自己的调用栈输出到串口。 栈回溯非常有利于我…

动态规划(算法)---01.斐波那契数列模型_第N个泰波那契数

前言&#xff1a; 有一个很著名的公式 “程序数据结构算法”。 算法是模型分析的一组可行的&#xff0c;确定的&#xff0c;有穷的规则。通俗的说&#xff0c;算法也可以理解为一个解题步骤&#xff0c;有一些基本运算和规定的顺序构成。但是从计算机程序设计的角度看&#xff…

【计算机网络实验】TCP协议的抓包分析:三次握手四次挥手UDP和TCP的区别(超详细教程)

计算机网络实验——TCP协议抓包分析 文章目录 计算机网络实验——TCP协议抓包分析一、基础知识点1、运输层两个重要协议的特点对比&#xff08;TCP和UDP&#xff09;2、TCP报文的格式3、常见的TCP报文标识字段&#xff08;FLAG字段&#xff09;4、TCP连接的建立过程及理解——三…

RPC原理技术

RPC原理技术 背景介绍起源组件实现工作原理 背景 本文内容大多基于网上其他参考文章及资料整理后所得&#xff0c;并非原创&#xff0c;目的是为了需要时方便查看。 介绍 RPC&#xff0c;Remote Procedure Call&#xff0c;远程过程调用&#xff0c;允许像调用本地方法一样调…

LiveGBS流媒体平台GB/T28181用户手册-电子地图:视频标记在地图上播放、云台控制、语音对讲

LiveGBS流媒体平台GB/T28181用户手册-电子地图:视频标记在地图上播放、云台控制 1、电子地图1.1、播放1.2、云台控制对讲 2、搭建GB28181视频直播平台 1、电子地图 1.1、播放 1.2、云台控制对讲 点击 后&#xff0c;如果是球机就可以云台控制&#xff0c;支持对讲的摄像头&…

【openlayers系统学习】1.3交互-修改要素(features)

三、修改要素 Modifying features 修改要素 现在我们有一种方法可以让用户将数据加载到编辑器中&#xff0c;我们希望让他们编辑功能。为此&#xff0c;我们将使用 Modify​ 交互&#xff0c;将其配置为修改矢量源上的功能。 首先&#xff0c;在 main.js​ 中导入 Modify​ …

使用字节豆包大模型在 Dify 上实现最简单的 Agent 应用(四):AI 信息检索

这篇文章&#xff0c;我们继续聊聊&#xff0c;如何折腾 AI 应用&#xff0c;把不 AI 的东西&#xff0c;“AI 起来”。在不折腾复杂的系统和环境的前提下&#xff0c;快速完成轻量的 Agent 应用。 写在前面 在上一篇文章《使用 Dify、Meilisearch、零一万物模型实现最简单的…

Leetcode 876. 链表的中间结点

题目描述 给你单链表的头结点 head &#xff0c;请你找出并返回链表的中间结点。 如果有两个中间结点&#xff0c;则返回第二个中间结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[3,4,5] 解释&#xff1a;链表只有一个中间结点&#xff0c…

【关键字】——register在C语言中的使用

register——寄存器 了解register之前&#xff0c;应该先认识认识寄存器&#xff0c;何为寄存器&#xff1f; 在计算机中&#xff0c;数据可以存储在远程二级存储&#xff08;网盘&#xff0c;服务器&#xff09;&#xff0c;本地二级存储&#xff08;本地磁盘&#xff09;&am…

Linux多线程系列三: 生产者消费者模型,信号量使用,基于阻塞队列和环形队列的这两种生产者消费者代码的实现

Linux多线程系列三: 生产者消费者模型,信号量,基于阻塞队列和环形队列的这两种生产者消费者代码的实现 一.生产者消费者模型的理论1.现实生活中的生产者消费者模型2.多线程当中的生产者消费者模型3.理论 二.基于阻塞队列的生产者消费者模型的基础代码1.阻塞队列的介绍2.大致框架…

零基础小白撸空投攻略:空投流程是什么样的? 如何操作?

在Web3的世界中&#xff0c;空投&#xff08;Airdrop&#xff09;是一种常见的营销和推广策略&#xff0c;通过向特定用户群体免费分发代币&#xff0c;项目方希望能够吸引更多的用户和关注。对于许多刚刚接触加密货币和区块链的新手来说&#xff0c;都会疑惑空投的流程究竟是什…

CTFshow之文件上传web入门151关-161关解密。包教包会!!!!

这段时间一直在搞文件上传相关的知识&#xff0c;正好把ctf的题目做做写写给自字做个总结&#xff01; 不过有一个确定就是所有的测试全部是黑盒测试&#xff0c;无法从代码层面和大家解释&#xff0c;我找个时间把upload-labs靶场做一做给大家讲讲白盒的代码审计 一、实验准…

STM32自己从零开始实操02:输入部分原理图

一、触摸按键 1.1指路 项目需求&#xff1a; 4个触摸按键&#xff0c;主控芯片 TTP224N-BSBN&#xff08;嘉立创&#xff0c;封装 TSSOP-16&#xff09;&#xff0c;接入到 STM32 的 PE0&#xff0c;PE1&#xff0c;PE2&#xff0c;PE3。 1.2走路 1.2.1数据手册重要信息提…

Redis常见数据类型(4) - hash, List

hash 命令小结 命令执行效果时间复杂度hset key field value设置值O(1)hget key field获取值O(1)hdel key field [field...]删除值O(k), k是field个数hlen key计算field个数O(1)hgetall key获取所有的field-valueO(k), k是field的个数hmget field [field...]批量获取field-va…

Orcle查询组合字段重复的数据

oracle拼接字符串 在Oracle中&#xff0c;可以使用||运算符或CONCAT函数来拼接字符串。 使用||运算符&#xff1a; SELECT Hello, || World! AS concatenated_string FROM dual;使用CONCAT函数&#xff1a; SELECT CONCAT(Hello, , World!) AS concatenated_string FROM d…

智慧医疗时代:探索互联网医院开发的新篇章

在智慧医疗时代&#xff0c;互联网医院开发正引领着医疗服务的创新浪潮。通过将先进的技术与医疗服务相结合&#xff0c;互联网医院为患者和医生提供了全新的互动方式&#xff0c;极大地提升了医疗服务的便捷性和效率。本文将深入探讨互联网医院的开发&#xff0c;介绍其技术实…

如何彻底搞懂迭代器(Iterator)设计模式?

说起迭代器&#xff08;Iterator&#xff09;&#xff0c;相信你并不会陌生&#xff0c;因为我们几乎每天都在使用JDK中自带的各种迭代器。那么&#xff0c;这些迭代器是如何构建出来的呢&#xff1f;就需要用到了今天内容要介绍的迭代器设计模式。在日常开发过程中&#xff0c…

多尺度注意力机制突破性成果!低成本、高性能兼备

与传统的注意力机制相比&#xff0c;多尺度注意力机制引入了多个尺度的注意力权重&#xff0c;让模型能够更好地理解和处理复杂数据。 这种机制通过在不同尺度上捕捉输入数据的特征&#xff0c;让模型同时关注局部细节和全局结构&#xff0c;以提高对细节和上下文信息的理解&a…

开源大模型与闭源大模型:技术哲学的较量

目录 前言一、 开源大模型的优势1. 社区支持与合作1.1 全球协作网络1.2 快速迭代与创新1.3 共享最佳实践 2. 透明性与可信赖性2.1 审计与验证2.2 减少偏见与错误2.3 安全性提升 3. 低成本与易访问性3.1 降低研发成本3.2 易于定制化3.3 教育资源丰富 4. 促进标准化5. 推动技术进…