0、前言
引文(链接在文末)的代码只能转图片和英文字体,对于中文和其它语言不支持(输出白页)。为此,我将在下文做出补充。
1、创建一个Gradle项目
然后在build.gradle中导入依赖,如果poi的包无法使用可以尝试把poi-ooxml改为poi试试
dependencies {
//testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
compile group: 'com.itextpdf', name: 'itextpdf', version: '5.5.11'
}
2、代码演示
在我展示的代码中,去掉了粗体斜体及图片等细节数据的pdf输出,以便展示代码逻辑,至于定制详情请自行参考引文或其他资料。
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import com.itextpdf.text.pdf.BaseFont;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Font;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.PageSize;
public class WordToPdfConverter{
//使用的字体,需要配置字体文件路径
public static final String FONT = "D:\\workdata\\fonts\\STKAITI.TTF";
public static void main(String[] args){
selectFiles();
}
public static void selectFiles(){
JFileChooser chooser = new JFileChooser();
//配置描述信息和过滤后缀名
FileNameExtensionFilter filter = new FileNameExtensionFilter("Microsoft Word 2007+", "doc");
chooser.setFileFilter(filter);
chooser.setMultiSelectionEnabled(true);
int returnVal = chooser.showOpenDialog(null);
if(returnVal == JFileChooser.APPROVE_OPTION) {
File[] Files=chooser.getSelectedFiles();
System.out.println("Please wait...");
for( int i=0;i<Files.length;i++){
String wordfile=Files[i].toString();
convertWordToPdf(wordfile,wordfile.substring(0,wordfile.indexOf('.'))+".pdf");
}
System.out.println("Conversion complete");
}
}
public static void convertWordToPdf(String src, String desc){
try{
//创建文件输入流和关联Word文档
FileInputStream fs=new FileInputStream(src);
XWPFDocument doc=new XWPFDocument(fs);
//定制纸张边距
Document pdfdoc=new Document(PageSize.A4,75,72,72,72);
PdfWriter pwriter=PdfWriter.getInstance(pdfdoc, new FileOutputStream(desc));
//设置行间距
pwriter.setInitialLeading(20);
//获得word文档的所有段落
List<XWPFParagraph> plist=doc.getParagraphs();
pdfdoc.open();
for (int i = 0; i < plist.size(); i++) {
XWPFParagraph pa = plist.get(i);
List<XWPFRun> runs = pa.getRuns();
//使用支持目标语言的FONT,设置字体大小为14
Font f = FontFactory.getFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 14);
for (int j = 0; j < runs.size(); j++) {
XWPFRun run=runs.get(j);
String text=run.getText(-1);
byte[] bs;
if (text!=null){
bs=text.getBytes();
String str=new String(bs,"UTF-8");
Chunk chObj1=new Chunk(str,f);
pdfdoc.add(chObj1); /*添加段落文字*/
}
}
pdfdoc.add(new Chunk(Chunk.NEWLINE)); /*换新行*/
}
pdfdoc.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
3、选择字体
在路径C:\Windows\Fonts可以找到字体文件,选择支持目标文字的字体后拷贝到其它位置,再到上述代码配置FONT路径即可
如果本地没有的字体,可以在GOOGLE NOTE下载 GOOGLE NOTO (需要翻墙)
4、使用效果
能看到效果还是不错的,不过我没有在代码判断获取删除线的信息,删除线没有复刻过到pdf中。
5、扩展与小结
①扩展
如果要转换图片、粗体、翻页,需要参考引文,或者使用POI(读取某种文字信息)和设置Chunk(输出时的块)属性。达到更多效果。
②小结
小编还未探索office自带的pdf转换原理,它能精准复刻且无需选择支持目标语言的字体(我猜测类似于把office页面转为图像的技术,还欢迎各位大佬指教)可惜不支持批量转换,只能靠自己开发。
但是就市面上的pdf批量转换工具的使用效果,或者POI和itextpdf包使用方式来说,在Java开发时都需要用代码读取word文件的数据信息(颜色、字体各方面都需要),再定制输出到pdf中,而这个定制同样是需要编码判断和设定的。也不难解释那些市面上的pdf工具很难保持原有版式,甚至有的因为没有字体定制,连异国文字的编码问题都无法解决。
6、项目合作和技术交流
如果需要定制pdf转换工具可以通过csdn联系本人。有更好的技术方案也欢迎一起交流
附、参考文献