java导出pdf不现实中文_Java解决Itext pdf中文不显示问题

[/** * AsianTest.java */ import java.io.FileOutputStream; import java.io.IOException; import com.lowagie.text.*; import com.lowagie.text.pdf.PdfWrit

最近在项目需要,需要将html内容转换成pdf的文件,采用itextpdf总是不显示中文。

找了很多方法都没搞定,然后在网上看到了有个帖子说改源码解决这个问题,[一、重写Breaker,添加中文识别// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.// Jad home page: http://kpdus.tripod.com/jad.html// Decompiler opt但是经过测试还是没有搞定。

并且个人不建议改源码,然后自己研究源码,借鉴了他的思路,可以不用改源码即可解决中文问题。

第一部:

maven 引入依赖的jar包

com.itextpdf

itextpdf

5.5.9

com.itextpdf.tool

xmlworker

5.5.9

com.itextpdf

itext-asian

5.2.0

根据ChunkCssApplier重写apply方法

@SuppressWarnings("deprecation")

public class MyChunkCssApplier extends ChunkCssApplier {

public static BaseFont chinessFont = null;

static {

try {

// 中文支持,需要引入 itext-asian.jar

chinessFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* 判断是否存在中文

* @param str

* @return

*/

private static boolean isChinese(String str){

if(str == null ){

return false;

}

//存在中文

String regex = ".*[\\u4e00-\\u9faf].*";

return Pattern.matches(regex, str);

}

/**

*

* 重写apply方法

*/

@Override

public Chunk apply(Chunk c, Tag t) {

Font f = applyFontStyles(t);

// 增加此段代码 如果中文 ,则返回中文字体

if (null != chinessFont && isChinese(c.getContent())) {

f = new Font(chinessFont, f.getSize(), f.getStyle(), f.getColor());

}

// 下面代码从源码中copy

float size = f.getSize();

Map rules = t.getCSS();

for (Entry entry : rules.entrySet()) {

String key = entry.getKey();

String value = entry.getValue();

if (CSS.Property.FONT_STYLE.equalsIgnoreCase(key)) {

if (value.equalsIgnoreCase(CSS.Value.OBLIQUE)) {

c.setSkew(0, 12);

}

} else if (CSS.Property.LETTER_SPACING.equalsIgnoreCase(key)) {

String letterSpacing = rules.get(CSS.Property.LETTER_SPACING);

float letterSpacingValue = 0f;

if (utils.isRelativeValue(value)) {

letterSpacingValue = utils.parseRelativeValue(letterSpacing, f.getSize());

} else if (utils.isMetricValue(value)){

letterSpacingValue = utils.parsePxInCmMmPcToPt(letterSpacing);

}

c.setCharacterSpacing(letterSpacingValue);

} else if (null != rules.get(CSS.Property.XFA_FONT_HORIZONTAL_SCALE)) { // only % allowed; need a catch block NumberFormatExc?

c.setHorizontalScaling(Float.parseFloat(rules.get(CSS.Property.XFA_FONT_HORIZONTAL_SCALE).replace("%", "")) / 100);

}

}

// following styles are separate from the for each loop, because they are based on font settings like size.

if (null != rules.get(CSS.Property.VERTICAL_ALIGN)) {

String value = rules.get(CSS.Property.VERTICAL_ALIGN);

if (value.equalsIgnoreCase(CSS.Value.SUPER) || value.equalsIgnoreCase(CSS.Value.TOP) || value.equalsIgnoreCase(CSS.Value.TEXT_TOP)) {

c.setTextRise((float) (size / 2 + 0.5));

} else if (value.equalsIgnoreCase(CSS.Value.SUB) || value.equalsIgnoreCase(CSS.Value.BOTTOM) || value.equalsIgnoreCase(CSS.Value.TEXT_BOTTOM)) {

c.setTextRise(-size / 2);

} else {

c.setTextRise(utils.parsePxInCmMmPcToPt(value));

}

}

String xfaVertScale = rules.get(CSS.Property.XFA_FONT_VERTICAL_SCALE);

if (null != xfaVertScale) {

if (xfaVertScale.contains("%")) {

size *= Float.parseFloat(xfaVertScale.replace("%", "")) / 100;

c.setHorizontalScaling(100 / Float.parseFloat(xfaVertScale.replace("%", "")));

}

}

if (null != rules.get(CSS.Property.TEXT_DECORATION)) {

String[] splitValues = rules.get(CSS.Property.TEXT_DECORATION).split("\\s+");

for (String value : splitValues) {

if (CSS.Value.UNDERLINE.equalsIgnoreCase(value)) {

c.setUnderline(null, 0.75f, 0, 0, -0.125f, PdfContentByte.LINE_CAP_BUTT);

}

if (CSS.Value.LINE_THROUGH.equalsIgnoreCase(value)) {

c.setUnderline(null, 0.75f, 0, 0, 0.25f, PdfContentByte.LINE_CAP_BUTT);

}

}

}

if (null != rules.get(CSS.Property.BACKGROUND_COLOR)) {

c.setBackground(HtmlUtilities.decodeColor(rules.get(CSS.Property.BACKGROUND_COLOR)));

}

f.setSize(size);

c.setFont(f);

Float leading = null;

if(rules.get(CSS.Property.LINE_HEIGHT) != null) {

String value = rules.get(CSS.Property.LINE_HEIGHT);

if(utils.isNumericValue(value)) {

leading = Float.parseFloat(value) * c.getFont().getSize();

} else if (utils.isRelativeValue(value)) {

leading = utils.parseRelativeValue(value, c.getFont().getSize());

} else if (utils.isMetricValue(value)){

leading = utils.parsePxInCmMmPcToPt(value);

}

}

if (leading != null) {

c.setLineHeight(leading);

}

return c;

}

}

新增一个ParserHTML.java

/**

* Hello world!

*

*/

public class ParserHTML

{

public static final String HTML = "D:/test/hero.html";

public static final String DEST = "D:/test/hero.pdf";

// public static final String HTML = "resources/xml/hero2.html";

// public static final String DEST = "results/xmlworker/asian2.pdf";

/**

* Creates a PDF with the words "Hello World"

* @param file

* @throws IOException

* @throws DocumentException

*/

public void createPdf(String file) throws IOException, DocumentException {

// step 1

Document document = new Document();

// step 2

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));

// step 3

document.open();

// step 4

// CSS

CSSResolver cssResolver = new StyleAttrCSSResolver();

CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream("body {font-family:tsc fming s tt}".getBytes()));

cssResolver.addCss(cssFile);

// 将ChunkCssApplier 设置为自定义的

CssAppliers cssAppliers = new CssAppliersImpl();

cssAppliers.setChunkCssAplier(new MyChunkCssApplier());

HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);

htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());

// Pipelines

PdfWriterPipeline pdf = new PdfWriterPipeline(document, writer);

HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);

CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);

// XML Worker

XMLWorker worker = new XMLWorker(css, true);

XMLParser p = new XMLParser(worker);

p.parse(new FileInputStream(HTML), Charset.forName("UTF-8"));

// step 5

document.close();

}

/**

* Main method

*/

public static void main(String[] args) throws IOException, DocumentException {

File file = new File(DEST);

file.getParentFile().mkdirs();

new ParserHTML().createPdf(DEST);

}

}

模板 hero.html

長空abc

(Broken Sword),

秦王殘劍

(Flying Snow),

飛雪

(Moon),

如月

(the King), and

秦王

(Sky).

[Ubuntu10.04终于来了,鄙人认为10.04是一个堪称完美的linux。赞一个~~!使用的过程中,在阅读pdf时发现中文不显示或有乱码出现的现象。特将方解决方法记下,以备忘。方

版权声明:本文为weixin_28757113原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。