利用iText将html转为pdf设置不同的样式以及报表

本教程只是作为自己的总结使用,主要参考于官网的文档:https://developers.itextpdf.com/

这个是一系列的介绍的方式,转化pdf入门请转入:利用itext将html文件转化pdf文件

这里我们介绍几个关于pdf输出的形式。

1、将生成的pdf文件作为输出的媒体形式

在这里面引入MediaDeviceDescription属性,用来设置ConverterProperties添加在转化的过程中。

如果设置为print的方式,意味着所有的文件的都是黑白的颜色,消除了所有的彩色。

package com.ctbri.test3;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.css.media.MediaDeviceDescription;
import com.itextpdf.html2pdf.css.media.MediaType;

/**
 * 转换的方式用print的方式
 */
public class C03E02_Print {

	public static final String BASEURI = "src/main/resources/html/";
	public static final String SRC = String.format("%ssxsw.html", BASEURI);
	public static final String TARGET = "target/results/ch03/";
	public static final String DEST = String.format("%ssxsw_print.pdf", TARGET);

	public static void main(String[] args) throws IOException {
		File file = new File(TARGET);
		file.mkdirs();
		new C03E02_Print().createPdf(BASEURI, SRC, DEST);
	}

	public void createPdf(String baseUri, String src, String dest) throws IOException {
		ConverterProperties properties = new ConverterProperties();
		properties.setBaseUri(baseUri);
		// 设置媒体的描述方式
		MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.PRINT);
		properties.setMediaDeviceDescription(mediaDeviceDescription);
		HtmlConverter.convertToPdf(new FileInputStream(src), new FileOutputStream(dest), properties);
	}
}

2、设置生成的pdf所属的媒体设别样式(pdf大小)

2.1 适合于桌面应用

修改pdf的默认大小以及适合的媒体显示的方式,如下面代码中的介绍。

package com.ctbri.test3;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.css.media.MediaDeviceDescription;
import com.itextpdf.html2pdf.css.media.MediaType;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfWriter;

/**
 * 创建的pdf适合于桌面设备查看
 */
public class C03E03_Wide {

	public static final String BASEURI = "src/main/resources/html/";
	public static final String SRC = String.format("%ssxsw.html", BASEURI);
	public static final String TARGET = "target/results/ch03/";
	public static final String DEST = String.format("%ssxsw_wide.pdf", TARGET);

    public static void main(String[] args) throws IOException {
        File file = new File(TARGET);
        file.mkdirs();
        new C03E03_Wide().createPdf(BASEURI, SRC, DEST);
    }

    public void createPdf(String baseUri, String src, String dest) throws IOException { 
    	PdfWriter writer = new PdfWriter(dest);
    	PdfDocument pdf = new PdfDocument(writer);
    	pdf.setTagged();
    	//设置纸张的大小,并且设置默认的pdf大小
    	PageSize pageSize = PageSize.A4.rotate();
    	pdf.setDefaultPageSize(pageSize);
    	ConverterProperties properties = new ConverterProperties();
    	properties.setBaseUri(baseUri);
    	// 设置pdf的显示方式,用sreen代替print
    	MediaDeviceDescription mediaDeviceDescription = new MediaDeviceDescription(MediaType.SCREEN);
    	mediaDeviceDescription.setWidth(pageSize.getWidth());
    	properties.setMediaDeviceDescription(mediaDeviceDescription);
        HtmlConverter.convertToPdf(new FileInputStream(src), pdf, properties);
    }
}

2.2 适合于移动设备

public void createPdf(String baseUri, String src, String dest) throws IOException { 
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    pdf.setTagged();
    PageSize pageSize = new PageSize(440, 2000);
    pdf.setDefaultPageSize(pageSize);
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri);
    MediaDeviceDescription mediaDeviceDescription
        = new MediaDeviceDescription(MediaType.SCREEN);
    mediaDeviceDescription.setWidth(pageSize.getWidth());
    properties.setMediaDeviceDescription(mediaDeviceDescription);
    HtmlConverter.convertToPdf(new FileInputStream(src), pdf, properties);
}

2 创建报表

2.1 利用XSLT将xml转化为html

文中参考的xml文件来源于:xml源文件   xsl原文件

package com.ctbri.test4;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;

/**
 * Creates a PDF document from an XML file using XSLT to convert the XML to
 * HTML.
 */
public class C04E01_MovieTable {

	public static final String BASEURI = "src/main/resources/html/";
	// xml文件路径
	public static final String XML = "src/main/resources/xml/movies.xml";
	// xsl文件路径
	public static final String XSL = "src/main/resources/xml/movies_table.xsl";
	public static final String TARGET = "target/results/ch04/";
	public static final String DEST = String.format("%smovie_table.pdf", TARGET);

	public static void main(String[] args) throws IOException, TransformerException {
		File file = new File(TARGET);
		file.mkdirs();
		C04E01_MovieTable app = new C04E01_MovieTable();
		app.createPdf(app.createHtml(XML, XSL), BASEURI, DEST);
	}

	/**
	 * Creates the PDF file.
	 */
	public void createPdf(byte[] html, String baseUri, String dest) throws IOException {
		ConverterProperties properties = new ConverterProperties();
		properties.setBaseUri(baseUri);
		HtmlConverter.convertToPdf(new ByteArrayInputStream(html), new FileOutputStream(dest), properties);
	}

	/**
	 * 通过xml文件上执行xstl转化创建html文件
	 */
	public byte[] createHtml(String xmlPath, String xslPath) throws IOException, TransformerException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		Writer writer = new OutputStreamWriter(baos);
		StreamSource xml = new StreamSource(new File(xmlPath));
		StreamSource xsl = new StreamSource(new File(xslPath));
		TransformerFactory factory = TransformerFactory.newInstance();
		Transformer transformer = factory.newTransformer(xsl);
		transformer.transform(xml, new StreamResult(writer));
		writer.flush();
		writer.close();
		return baos.toByteArray();
	}
}

2.2 、创建背景颜色以及header、footer

主要内容参见下面代码中的注释以及后面的解释:

/**
 * Creates a PDF document from an XML file using XSLT to convert the XML to HTML
 */
public class C04E02_MovieTable2 {

	public static final String BASEURI = "src/main/resources/html/";
	/** The XML containing all the data. */
	public static final String XML = "src/main/resources/xml/movies.xml";
	/** The XSLT needed to transform the XML to HTML. */
	public static final String XSL = "src/main/resources/xml/movies_table.xsl";
	public static final String TARGET = "target/results/ch04/";
	public static final String DEST = String.format("%smovie_table2.pdf", TARGET);
	public static final String STATIONERY = "src/main/resources/pdf/stationery.pdf";

	/**
	 * The main method
	 */
	public static void main(String[] args) throws IOException, TransformerException {
		File file = new File(TARGET);
		file.mkdirs();
		C04E02_MovieTable2 app = new C04E02_MovieTable2();
		app.createPdf(app.createHtml(XML, XSL), BASEURI, STATIONERY, DEST);
	}

	/**
	 * Creates the PDF file.
	 */
	public void createPdf(byte[] html, String baseUri, String stationery, String dest) throws IOException {
		ConverterProperties properties = new ConverterProperties();
		properties.setBaseUri(baseUri);
		PdfWriter writer = new PdfWriter(dest);
		PdfDocument pdf = new PdfDocument(writer);
		IEventHandler handler = new Background(pdf, stationery);
		pdf.addEventHandler(PdfDocumentEvent.START_PAGE, handler);
		HtmlConverter.convertToPdf(new ByteArrayInputStream(html), pdf, properties);
	}

	/**
	 * Creates an HTML file by performing an XSLT transformation on an XML file.
	 * @param xmlPath  the path to the XML file.
	 * @param xslPath  the path to the XSL file
	 * @return the resulting HTML as a byte[]
	 */
	public byte[] createHtml(String xmlPath, String xslPath) throws IOException, TransformerException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		Writer writer = new OutputStreamWriter(baos);
		StreamSource xml = new StreamSource(new File(xmlPath));
		StreamSource xsl = new StreamSource(new File(xslPath));
		TransformerFactory factory = TransformerFactory.newInstance();
		Transformer transformer = factory.newTransformer(xsl);
		transformer.transform(xml, new StreamResult(writer));
		writer.flush();
		writer.close();
		return baos.toByteArray();
	}

	/**
	 * 通过实现 IEventHandler 接口来显示添加背景颜色以及每一页的数字
	 */
	class Background implements IEventHandler {

		/** The Form XObject that will be added as the background for every page. */
		PdfXObject stationery;

		/**
		 * 实例化background对象
		 */
		public Background(PdfDocument pdf, String src) throws IOException {
			PdfDocument template = new PdfDocument(new PdfReader(src));		//实例化pdfDocument
			PdfPage page = template.getPage(1);					//获得template的第一页
			stationery = page.copyAsFormXObject(pdf);			//复制获取的pdf并且作为PdfXObject对象
			template.close();
		}

		//用来处理事件
		public void handleEvent(Event event) {
			PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
			//实例化一个pdfDocument对象
			PdfDocument pdf = docEvent.getDocument();
			PdfPage page = docEvent.getPage();
			PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdf);
			pdfCanvas.addXObject(stationery, 0, 0);				//添加一个单一的pdf作为背景
			Rectangle rect = new Rectangle(36, 32, 36, 64);			//添加数字的位置
			Canvas canvas = new Canvas(pdfCanvas, pdf, rect);		//利用之前创建的pdfCanvas创建一个更加高级的对象
			//将新的页面添加到高级额Canvas中,并且设置字码的大小和颜色
			canvas.add(new Paragraph(String.valueOf(pdf.getNumberOfPages())).setFontSize(48).setFontColor(Color.WHITE));
			canvas.close();
		}
	}

那个怎么出发handEven事件呢?具体的方法写在createPdf中

  1. 首先创建background的实例对象,并且命名为IEventHandler对象的handler。
  2. 实例化的PdfDocument 对象利用addEventHandler()方法将对象添加到方法中去

2.3 、将html文件转化到一个单一的pdf文件中

如何自定义一个pdf的长度,设置pdf的长度:

public void createPdf(byte[] html, String baseUri, String dest)
    throws IOException {
    ConverterProperties properties = new ConverterProperties();
    properties.setBaseUri(baseUri); 
    PdfWriter writer = new PdfWriter(dest);
    PdfDocument pdf = new PdfDocument(writer);
    pdf.setDefaultPageSize(new PageSize(595, 14400));
    Document document = HtmlConverter.convertToDocument(
        new ByteArrayInputStream(html), pdf, properties);
    EndPosition endPosition = new EndPosition();
    LineSeparator separator = new LineSeparator(endPosition);
    document.add(separator);
    document.getRenderer().close();
    PdfPage page = pdf.getPage(1);
    float y = endPosition.getY() - 36;
    page.setMediaBox(new Rectangle(0, y, 595, 14400 - y));
    document.close();
}

2.4、为报表加上书签

类似与word里面的添加目录

只需要在ConverterProperties 中添加上

OutlineHandler outlineHandler = OutlineHandler.createStandardHandler();
    public void createPdf(byte[] html, String baseUri, String dest) throws IOException {
    	ConverterProperties properties = new ConverterProperties();
    	properties.setBaseUri(baseUri);
    	OutlineHandler outlineHandler = new OutlineHandler();
    	//h1设置为一级标题
        outlineHandler.putTagPriorityMapping("h1", 1);
        //将p设置为二级标题
        outlineHandler.putTagPriorityMapping("p", 2);
    	properties.setOutlineHandler(outlineHandler);
    	HtmlConverter.convertToPdf(new ByteArrayInputStream(html), new FileOutputStream(dest), properties);
    }


你可能感兴趣的:(java,iText)