最近在项目需要,需要将html内容转换成pdf的文件,采用itextpdf总是不显示中文。
找了很多方法都没搞定,然后在网上看到了有个帖子说改源码解决这个问题,但是经过测试还是没有搞定。
并且个人不建议改源码,然后自己研究源码,借鉴了他的思路,可以不用改源码即可解决中文问题。
第一部:
maven 引入依赖的jar包
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
根据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<String, String> rules = t.getCSS();
for (Entry<String, String> 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
<p><span style="font-size:12.0pt; font-family:MS Mincho; color:red">長空abc</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Broken Sword),</span>
<span style="font-size:12.0pt; font-family:MS Mincho">秦王殘劍</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Flying Snow),</span>
<span style="font-size:12.0pt; font-family:MS Mincho">飛雪</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Moon), </span>
<span style="font-size:12.0pt; font-family:MS Mincho">如月</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(the King), and</span>
<span style="font-size:12.0pt; font-family:MS Mincho">秦王</span>
<span style="font-size:12.0pt; font-family:Times New Roman,serif">(Sky).</span></p>
分享到:
相关推荐
iText生成pdf解决中文不显示字库,pdf凉字不显示,由于生成iText插件生成pdf的时候中文会显示不出来,遇到过的是"凉"字,查到是字体库的原因,网上下载字体库msyh.ttc,生成的时候指定字体库,就可以解决了,小bug一...
itextpdf 再创将pdf格式文件的时候中文不显示或者乱码问题的解决 其实目前最新版本的itexpdf即使加了asian的辅助包也不能解决中文不显示问题 因为自己试过 可能方式不对 这个绝对显示 显示不了的 分不要
java解决Itext生成PDF中文不换行的问题
java使用itextpdf、itext-asian对pdf文件加中文文字水印,此demo只提供参考,希望给需要的朋友带来帮助,谢谢支持!
java实现html转pdf,包含后端代码,html测试页面,pom依赖,jar包,如页面过于复杂需调整页面,有些样式itextpdf不支持,请寻找其它样式替换。
itext导出pdf不显示中文 ITextRenderer不显示中文,终极解决方案!!!绝对能解决!!!
Java使用iText PDF插件导出PDF文档时,需引入中文字体文件,并创建不同大小风格的中文字体
如何解决java html转pdf图片不显示问题的源码范例(由浅入深代码范例和详细说明)
adobe pdf编辑器,解压安装即可使用,配合java利用itextpdf根据模板导出pdf文章中只做模板的方法;
java使用itext实现pdf文件下载小案例,通过系统路径下载,和通过浏览器下载
内含maven仓库在文件itext.txt文件中,含架包,需要先用adobe来生成pdf模板
itext 生成pdf 目录,itext 生成pdf 目录,itext 生成pdf 目录
由于工作需要,小研究了下itext,在此和大家分享下,互相探讨,也希望能帮得上哪位朋友。...功能:java生成pdf,支持中文,可以插入图片,可以添加超链 接连到其他网址。 内附代码及详细说明和需要的jar包
Itext导出PDF,中文不显示字体,在body上设置font-family: "Arial Unicode MS",同时在java中引入fontResolver.addFont("/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); 就可以显示中文了
1、解决HTML转pdf 中文、数字、英文不能换行的问题,修改的源码包 重新计算了右边距。 2、html转pdf 参考我的另外一篇博文https://blog.csdn.net/qq_38616723/article/details/125188407?spm=1001.2014.3001.5502
1、itext将静态html转pdf中文显示及换行问题 2、itext将静态html转pdf 字体问题 3、html转pdf 参考我的另外一篇博文https://blog.csdn.net/qq_38616723/article/details/125188407?spm=1001.2014.3001.5502
java运用iText生成PDF所需的jar包: core-renderer.jar, itext-asian.jar, itextpdf-2.0.8.jar, itextpdf-asian-cmaps.jar 已打包中文字体可直接使用
JAVA基于ITEXT实现的PDF报表系统,程序下载只是作为参考和学习,不是可以直接使用的。
下面小编就为大家带来一篇java使用itext导出PDF文本绝对定位(实现方法)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧