PDF文档转换成mobi格式forkindle并解决排版问题.docx

上传人:b****8 文档编号:9557307 上传时间:2023-02-05 格式:DOCX 页数:21 大小:4.24MB
下载 相关 举报
PDF文档转换成mobi格式forkindle并解决排版问题.docx_第1页
第1页 / 共21页
PDF文档转换成mobi格式forkindle并解决排版问题.docx_第2页
第2页 / 共21页
PDF文档转换成mobi格式forkindle并解决排版问题.docx_第3页
第3页 / 共21页
PDF文档转换成mobi格式forkindle并解决排版问题.docx_第4页
第4页 / 共21页
PDF文档转换成mobi格式forkindle并解决排版问题.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

PDF文档转换成mobi格式forkindle并解决排版问题.docx

《PDF文档转换成mobi格式forkindle并解决排版问题.docx》由会员分享,可在线阅读,更多相关《PDF文档转换成mobi格式forkindle并解决排版问题.docx(21页珍藏版)》请在冰豆网上搜索。

PDF文档转换成mobi格式forkindle并解决排版问题.docx

PDF文档转换成mobi格式forkindle并解决排版问题

PDF文档转换成mobi格式(forkindle),并解决排版问题

∙0.前言

∙1.下载和安装calibre

∙2.PDF导入calibre,并转换为azw3格式

∙3.编辑电子书,获取HTML内容和图片

∙4.程序处理HTML文档

∙5.将HTML文档导入calibre,并转换成azw3格式

∙6.编辑azw3文档

∙7.将azw3文档转换成mobi格式

∙8.附录

0.前言

正式介绍之前,先回答下面几个问题:

1.为什么要将PDF转换成mobi?

想要将PDF转换成mobi格式,初衷在于想在kindle上面看一些从网上获取到的PDF文档。

直接将PDF导入kindle本来也可以,但是效果不是很好——要么竖着看,但是字体很小;要么横着看,字体会大一些,但是总感觉比较别扭,而且PDF的一页需要在kindle上翻3页。

kindle支持azw3、mobi等格式,但是不支持直接将azw3格式的文档直接导入到kindle,所以需要将PDF文档转换成mobi格式

2.为什么不直接用在线转换工具?

其实网上有很多工具支持将PDF转换成mobi格式,但是效果都很差:

1.章节标题和正文内容没有区别;

2.正文内容格式混乱,在kindle上看是以PDF的一行进行的分段,行首也没有空格

3.

3.将PDF转换成mobi格式,我大概怎么做?

将PDF转换成mobi格式,我主要是借助于calibre工具:

4.转换效果如何?

转换之后效果如下图,其中对章节标题和段落划分进行了处理:

1.下载和安装calibre

calibre下载地址:

https:

//calibre-

根据自己的系统下载安装即可

2.PDF导入calibre,并转换为azw3格式

打开calibre,点击菜单栏的“添加数据”,选择PDF格式文件,点击“Open”

在calibre的主窗口中选中刚导入的图书,点击菜单栏的“转换书籍”,在弹出的转换窗口,将输出格式选择为“AZW3”,然后点击“确定”。

转换过程可能会持续一小段时间,看calibre主窗口右下角的任务执行结束即转换完成

【注】这里有一个坑,图书转换的设置,目录针对章节有一个默认的最大值,需要根据图书的实际情况进行调整。

我一般将两个值分别设置为1000,50

3.编辑电子书,获取HTML内容和图片

在calibre主窗口选中目标电子书,点击菜单栏的“编辑书籍”打开编辑书籍窗口

在编辑书籍窗口,选中文本下的“part0000.html”,点击右键,选择“导出part0000.html”

同样的方式,全选图片下的所有图片,然后导出

4.程序处理HTML文档

由上一步可以看到,直接由PDF转换得到的HTML文档,PDF里面的每一行转换之后在HTML文档中都独立成了一段,而且段首也没有空格,章节标题也没有突出展示。

针对这个问题,于是自己写了一段Java代码,主要是根据语义对文档内容进行分段,同时将标题突出,然后将每一张的起始位置独立成页。

具体的代码见文末,里面也有比较详细的注释,有一些特殊情况的处理可以根据自己的要求适当修改代码。

5.将HTML文档导入calibre,并转换成azw3格式

首先,将calibre中已有的同名电子书删掉,操作方式是:

在calibre主窗口,选中要删除的电子书,右键,选择“移除书籍”>“移除选定书籍”,之后在弹出窗口做二次确认

然后,将处理之后的HTML文档导入到calibre,操作方式同第2章。

最后,由于直接导入的HTML文档是ZIP格式,不能直接进行编辑,所以需要再次将文档转换成azw3格式,操作方式同第3章。

可以看到,导入HTML文档之后,图书的封面丢失了,可以在转换的时候,直接修改封面图(可以用第3章导出保存的图片),如下图:

6.编辑azw3文档

这一步是非必须的,但是如果电子书中有插图,那么就需要在这一步进行补充。

另外也可以在文件预览中检查各个HTML文件,如有必要,也可以进行简单编辑。

进入编辑操作同第3章所介绍,这里主要介绍一下补充图片。

在编辑书籍窗口,点击菜单栏的“新增文件”按钮。

然后在弹出框选择“导入文件”,选择需要导入的图片。

注意,文件的路径最终要是“images/xx”格式。

最后点击“确定”。

如果有多张图片,则重复上面的操作。

目前calibre不支持批量导入。

编辑完成之后,点击编辑书籍窗口菜单栏的“保存”按钮进行保存。

7.将azw3文档转换成mobi格式

在calibre主窗口,选中电子书,点击“转换书籍”,在弹出窗口中,输入格式选择“AZW3”

,输出格式选择“MOBI”。

点击“确定”。

然后等转换任务结束。

转换结束之后,在calibre主窗口,选中电子书,在右侧边栏,点击“点击打开”即可获取到mobi格式的电子书。

然后将其共享至kindle就可以了。

8.附录

推荐的PDF电子书网址:

(大家有其他好的电子书链接也欢迎评论区共享。

HTML格式文档处理代码:

packagecom.amwalle.walle.util;

importorg.springframework.util.StringUtils;

importjava.io.*;

importjava.util.*;

importjava.util.regex.Matcher;

importjava.util.regex.Pattern;

publicclassPDFConverter{

publicstaticvoidmain(String[]args)throwsIOException{

Scannerscanner=newScanner(System.in);

System.out.println('请输入要转换的文件路径:

');

StringfilePath=scanner.nextLine();

System.out.println(filePath);

convert(filePath);

}

publicenumHeaderLevel{

Part('H1','.*第.*部分.*'),

Chapter('H2','(.*第.*章.*)|(.*[1-9].*)');

privateStringheaderLevel;

privateStringexpression;

HeaderLevel(StringheaderLevel,Stringexpression){

this.headerLevel=headerLevel;

this.expression=expression;

}

publicstaticStringgetHeaderLevel(Stringinput){

if(StringUtils.isEmpty(input)||(!

input.contains('')&&!

input.contains(''))){

returnnull;

}

Stringdummy=preHandleHeader(input);

for(HeaderLevellevel:

HeaderLevel.values()){

Patternpattern=Ppile(level.expression);

Matchermatcher=pattern.matcher(dummy);

if(matcher.find()){

returnlevel.headerLevel;

}

}

returnnull;

}

privatestaticStringpreHandleHeader(Stringinput){

Stringdummy=input;

if(input.contains('')&&input.contains('

')){

dummy=dummy.substring(dummy.indexOf('')+4,dummy.indexOf('

'));

}elseif(input.contains('')&&input.contains('

')){

dummy=dummy.substring(dummy.indexOf('')+20,dummy.indexOf('

'));

}

dummy=dummy.replaceAll('','');

dummy=dummy.replaceAll('','');

dummy=dummy.replaceAll('','');

dummy=dummy.replaceAll('','');

dummy=removeSpace(dummy);

returndummy;

}

publicStringgetHeaderLevel(){

returnheaderLevel;

}

publicvoidsetHeaderLevel(StringheaderLevel){

this.headerLevel=headerLevel;

}

publicStringgetExpression(){

returnexpression;

}

publicvoidsetExpression(Stringexpression){

this.expression=expression;

}

}

publicstaticvoidconvert(StringfilePath)throwsIOException{

Filefile=newFile(filePath);

if(!

file.isFile()||!

file.canRead()||!

file.getName().endsWith('.html')){

System.out.println('请输入正确的html文件路径,并保证文件可读!

');

}

Stringtitle=file.getName();

title=title.replace('.html','');

FileoutFile=newFile(filePath.replace('.html','1.html'));

if(outFile.exists()){

outFile.delete();

outFile.createNewFile();

}

try(Scannerscanner=newScanner(file,'UTF-8');BufferedWriteroutWriter=newBufferedWriter(newFileWriter(outFile))){

Setcatalog=newHashSet<>();

StringBufferoutput=newStringBuffer();

booleanisIndentationNeeded=false;

intcount=0;

while(scanner.hasNextLine()){

count++;

//有些文件太大,需要在中间存一下文件

if(count>=10000){

outWriter.append(output);

count=0;

output.delete(0,output.length());

}

Stringline=scanner.nextLine();

//目录前面的内容(封面、版权等)

if(catalog.isEmpty()&&!

line.startsWith('

output.append(line).append('\n');

continue;

}

//处理目录:

目录数据存set用于后续增加标题格式

if(line.endsWith('

')){

if(catalog.isEmpty()){

output.delete(output.length()-1,output.length());

Stringheader=output.toString();

StringcatalogTitle=header.substring(header.lastIndexOf('\n')+1);

//格式化目录标题,增加目录前的分页

if(catalogTitle.contains('目录')||catalogTitle.contains('Contents')){

catalogTitle='

'+catalogTitle+'

'+'\n';

output.delete(header.lastIndexOf('\n')+1,output.length());

output.append(addPagination(title));

output.append(catalogTitle);

}else{

output.append('\n');

output.append(addPagination(title));

}

}

line=line.replaceAll('part0000\\.html','');

output.append(line).append('\n');

Stringtemp=line.substring(line.lastIndexOf('\'>')+2,line.indexOf('

'));

temp=removeSpace(temp);

catalog.add(temp);

continue;

}

if(StringUtils.isEmpty(line)){

output.append('\n');

continue;

}

//处理章节标题

if(isLineATitle(line,catalog)){

isIndentationNeeded=true;

StringtitleLevel=HeaderLevel.getHeaderLevel(line);

if(HeaderLevel.Part.headerLevel.equals(titleLevel)){

output.append(addPagination(title));

output.append('

').append(line).append('

').append('\n');

continue;

}

if(HeaderLevel.Chapter.headerLevel.equals(titleLevel)){

output.append(addPagination(title));

output.append('

').append(line).append('

').append('\n');

continue;

}

output.append('

').append(line).append('

').append('\n');

continue;

}

//首行缩进

if(isIndentationNeeded){

line=line.replace('','

2em;\'>');

line=line.replace('

','');

output.append(line).append('\n');

isIndentationNeeded=false;

continue;

}

//文本内容分段

if(isParagraphEnd(line)){

isIndentationNeeded=true;

line=line.replace('','');

line=line.replace('

','');

output.append(line).append('\n');

continue;

}

//普通行处理:

去掉换行

if(line.startsWith('')&&line.endsWith('

')){

line=line.replace('','');

line=line.replace('

','');

output.append(line);

continue;

}

output.append(line).append('\n');

}

outWriter.append(output);

System.out.println('********************************************');

System.out.println('Done!

生成的新文件路径:

');

System.out.println(outFile.getPath());

}catch(FileNotFoundExceptione){

System.out.println('Fileconvertfailed!

');

e.printStackTrace();

}

}

privatestaticStringremoveSpace(Stringinput){

Stringresult=input.trim().replaceAll('\\.','').replaceAll('·','');

result=result.replaceAll('\\s*','').replaceAll('\\u00a0','').replaceAll((char)12288+'','');

returnresult;

}

privatestaticStringaddPagination(Stringtitle){

return'\n'+

'\n'+

'\n'+

'

lang=\'zh-cn\'xmlns=\'http:

//www.w3.org/1999/xhtml\'>\n'+

'\n'+

''+title+'\n'+

'\n'+

'\n'+

'\n'+

'

songti;\'>\n'+

'\n';

}

privatestaticbooleanisLineATitle(Stringinput,Setcatalog){

if(StringUtils.isEmpty(input)||(!

input.contains('')&&!

input.contains(''))){

returnfalse;

}

Stringdummy=HeaderLevel.preHandleHeader(input);

for(StringcatalogEntry:

catalog){

if(StringUtils.isEmpty(catalogEntry)){

continue;

}

if(catalogEntry.equals(dummy)){

returntrue;

}

}

returnfalse;

}

privatestaticbooleanisParagraphEnd(Stringinput){

Patternpattern=Ppile('.*(\\w

)$');

Matchermatcher=pattern.matcher(input);

if(matcher.matches()){

returnfalse;

}

//句子结尾的标点符号:

./!

/?

/……/'」(英文+中文)

Patternpattern1=Ppile('.*(([\\.|!

|\\?

|\'|\\u3002|\\uff01|\\uff1f|\\u2026|\\u201d|\\u300d])|(\\.))

$');

Matchermatcher1=pattern1.matcher(input);

returnmatcher1.matches();

}

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1