`
362217990
  • 浏览: 51901 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

Java解决Itext pdf中文不显示问题

阅读更多
最近在项目需要,需要将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>
分享到:
评论

相关推荐

    itextpdf 解决中文不显示问题

    itextpdf 再创将pdf格式文件的时候中文不显示或者乱码问题的解决 其实目前最新版本的itexpdf即使加了asian的辅助包也不能解决中文不显示问题 因为自己试过 可能方式不对 这个绝对显示 显示不了的 分不要

    iText生成pdf解决中文不显示

    iText生成pdf解决中文不显示字库,pdf凉字不显示,由于生成iText插件生成pdf的时候中文会显示不出来,遇到过的是"凉"字,查到是字体库的原因,网上下载字体库msyh.ttc,生成的时候指定字体库,就可以解决了,小bug一...

    JAVA使用itextpdf实现HTML转PDF

    本主题聚焦于使用Java的iTextPDF库来完成这个任务。iTextPDF是一个强大的Java库,允许开发人员创建、修改和优化PDF文档。 首先,我们需要了解HTML和PDF之间的差异。HTML是一种标记语言,用于构建和设计网页,而PDF...

    itext导出pdf不显示中文 ITextRenderer不显示中文

    通过以上步骤,你应该能够成功解决iText导出PDF时中文不显示的问题。如果仍然遇到问题,可能是其他因素,如PDF阅读器不支持、PDF版本不兼容等。此时,需要进一步排查和调整相关设置。 总之,处理iText与中文字符的...

    解决Itext生成PDF中文不换行的jar

    为了解决"Java使用Itext生成PDF中文不换行"的问题,我们可以采取以下几种策略: 1. **设置字体和编码**:确保使用支持中文的字体,如SimSun、Arial Unicode MS等,并正确设置PDF的编码为UTF-8。Itext中的`Font`类...

    java使用itextpdf、itext-asian对pdf文件加水印

    在Java中使用iTextPDF和iText-Asian添加中文水印,你需要完成以下几个步骤: 1. **引入依赖**:在你的项目中,你需要添加iTextPDF和iText-Asian的依赖。如果是Maven项目,可以在pom.xml文件中添加如下依赖: ```xml...

    Itext导出PDF,中文不显示字体

    Itext导出PDF,中文不显示字体,在body上设置font-family: "Arial Unicode MS",同时在java中引入fontResolver.addFont("/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); 就可以显示中文了

    java使用itext导出PDF文本绝对定位(实现方法)

    java使用iText导出PDF文本绝对定位(实现方法) iText是一个流行的Java类库,用于生成PDF文档。下面我们将探讨如何使用iText在Java中导出PDF文本,并实现绝对定位。 iText简介 iText是一个开源的Java类库,用于...

    adobe pdf编辑器 java利用itextpdf根据模板导出pdf配套资源

    2. **引入iTextPDF库**:在Java项目中添加iTextPDF依赖。如果是Maven项目,可以在pom.xml中添加对应的依赖条目。 3. **读取模板**:使用PdfReader类读取模板PDF文件,获取AcrobatReader对象,该对象可以访问PDF的...

    java使用itext实现pdf文件下载

    &lt;artifactId&gt;itextpdf &lt;version&gt;5.5.13 ``` 接下来,我们将探讨如何生成PDF文件。以下是一个简单的例子,展示如何创建一个包含简单文本的PDF文档: ```java import com.itextpdf.text.Document; import ...

    iText生成pdf解决中文不显示字库,这是个中文字库

    iText生成pdf解决中文不显示字库,pdf凉字不显示,由于生成iText插件生成pdf的时候中文会显示不出来,遇到过的是"凉"字,查到是字体库的原因,网上下载字体库msyh.ttc,生成的时候指定字体库,就可以解决了,小bug一...

    iTextpdf支持中文

    在iTextpdf中,可能需要指定支持中文的字体(如SimSun、Arial Unicode MS等),并确保数据正确编码为UTF-8,以避免乱码问题。 使用iTextpdf库,开发者可以实现以下功能: 1. **创建PDF**:从头开始创建全新的PDF...

    java通过itext操作pdf模板写入pdf合同数据

    &lt;artifactId&gt;itextpdf &lt;version&gt;5.x.x&lt;/version&gt; &lt;!-- 替换为实际版本号 --&gt; ``` 确保使用的版本与项目兼容,并已正确导入。 4. **操作PDF** - **读取模板**:使用`PdfReader`类读取PDF模板文件,创建`...

    itextpdf中文帮助文档.pdf

    **iTextPDF中文帮助文档** iTextPDF是一款广泛使用的开源Java库,用于创建、修改PDF文档。这个中文帮助文档提供了关于如何使用iTextPDF库在Java项目中处理PDF的详细指南,适合对PDF操作有一定需求的开发者。iText...

    如何解决java html转pdf图片不显示问题的源码范例(由浅入深代码范例和详细说明).docx

    的 PDF 文档,然后使用 PdfWriter 将文档写入指定的输出文件。接着,我们设置了 PdfWriter 的 ...如果遇到其他问题,例如字体、CSS 样式等,可能需要查阅 iText 和 FlyingSaucer 的官方文档,了解更多的定制选项。

    iText PDF中文字体文件.rar

    本教程将深入探讨如何在Java中使用iText PDF插件处理中文字符,以及如何引入中文字体文件,创建不同大小和风格的中文字体。 首先,让我们理解`iText PDF`。iText是一个开源的Java库,它提供了一系列API用于构建PDF...

    itext-2.1.7源码包以及 解决iText生成pdf时中文标点存在行首问题的修改class

    "itext-2.1.7源码包以及 解决iText生成pdf时中文标点存在行首问题的修改class" 这个标题提到了两个关键点。首先,`itext-2.1.7`是开源Java库iText的一个版本,用于创建、修改和操作PDF文档。这个版本的源码包提供了...

    Java 使用iText7生成带页码的PDF文件(同时生成目录,但是不会合并两个PDF)

    implementation 'com.itextpdf:itext7-core:7.x.y' // 替换x.y为最新版本号 implementation 'com.itextpdf:itext-layout:7.x.y' // 同样替换x.y } ``` 执行`gradle build`或者刷新Gradle项目后,相关jar包会自动...

    java使用IText导出PDF(包含图片、表格、文字等等Demo和依赖包)

    &lt;artifactId&gt;itextpdf &lt;version&gt;5.x.x&lt;/version&gt; &lt;!-- 请根据最新版本号替换 --&gt; ``` 确保版本号是最新的,以便利用其所有功能和修复的bug。 接下来,我们探讨如何在PDF中插入文本。使用`Document`对象作为容器...

Global site tag (gtag.js) - Google Analytics