最近打算用java代码生成一个pdf,结果找到了itextpdf, 感觉还是很强大的,只是网传不支持中文。引用了itextAsia 搞了好半天中文居然乱码。
网上的各种方法他能生成中文,但是我还是乱码,无奈之下研究了一下字符集,一切从Charset.defaultCharset()这个方法开始。
System.out.println(Charset.defaultCharset());输出结果如果是GBK,那么不好意思,你乱码是正常的,如果是UTF8,恭喜你你没乱码纯属侥幸。 听说网上要下载什么extrajars-2.3.zip,简直弱爆了,其实什么都不用下载,只需要:
implementation group: 'com.itextpdf', name: 'itextpdf', version: '+'
implementation group: 'com.itextpdf', name: 'itext-asian', version: '+'
如果你想指定版本:
implementation group: 'com.itextpdf', name: 'itextpdf', version: '5.4.4'
implementation group: 'com.itextpdf', name: 'itext-asian', version: '5.2.0'
其实乱不乱码跟版本没什么关系。
执行如下程序会乱码:
public static void main(String[] args) throws Exception{
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("createSamplePDF.pdf"));
BaseFont bfChinese = BaseFont.createFont( "STSongStd-Light" , "UniGB-UCS2-H" , false);
Font font = new Font(bfChinese, 14, Font.NORMAL);
document.addAuthor("WESTDREAM");
document.addTitle("Test iText");
document.addSubject("This is an iText demo");
document.addKeywords("iText keywords");
document.addCreator("Using iText");
document.open();
document.add(new Paragraph("你dfds的范德萨发好3333", font));
document.close();
System.out.println(Charset.defaultCharset().name());
}
控制台会输出GBK就会乱码,如果你的控制台恰好输出UTF8,就不会乱码。
如果我们改变defaultCharset那么一切解决,但是不巧的是,你的程序将依赖运行环境,这样做不太好,下文后面有更改方式。
既然不想改变defaultCharset,那么就将字符串变成utf编码不就行了吗:
document.add(new Paragraph("你dfds的范德萨发好3333", font)); //乱码
document.add(new Paragraph(new String("你dfds的范德萨发好3333".getBytes(), "utf8"), font));//不会乱码
这么做的好处是,不管你的系统用的是什么字符编码,我都转成utf8,所以问题解决,不需要导入字体,只需要这两个包包就行了。 如果一刀切,配置一个环境变量:
windows直接修改jdk编码在系统变量→新建 “JAVA_TOOL_OPTIONS” 变量,值为“-Dfile.encoding=UTF-8”
linux我没试过,我不喜欢这种依赖环境的方式, 所以准备一个工具方法吧:
public static String getUTF8String(String string){
if (string != null){
try{
return new String(string.getBytes(), "utf8");
}catch (Exception e){
e.printStackTrace();
}
}
return "hah string to utf8 fail";
}