iText导出PDF多表格

iText是一种生成PDF报表的Java组件。通过在服务器端使用Jsp或JavaBean生成PDF报表,客户端采用超链接显示或下载得到生成的报表,这样就很好的解决了B/S系统的报表处理问题。在使用iText的过程中,遇到了一下几个问题。

1.中文不显示

2.没有合适的工具类样式

3.用输出流导出可供浏览器下载的问题

几经度娘最终整合了很多代码,终于汇总成了可以简易使用的工具类

1.中文不显示

    主要是itext版本的问题,itext一开始是只有一个itext的jar包,后来升级后拆分成两个jar包,一个是itextpdf一个是itext-asian。我这边使用的版本是itextpdf-5.5.6.jar和itext-asian-5.2.0.jar。确保itext版本匹配。itext-asian中含有中文字体包,可以直接使用这里的中文字体。当然也推荐这种方式,因为其他方式依赖于环境的字体包。

 //1:使用iTextAsian.jar包中的字体
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font font = new Font(baseFont);

//2:使用Windows系统字体
BaseFont baseFont_zh = BaseFont.createFont("C:\\Windows\\Fonts\\simsunb.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
Font font_zh = new Font(baseFont_zh);

//3:使用资源字体,也就是自己下载的字体
BaseFont baseFont_resources = BaseFont.createFont("\\font\\方正舒体.TIF",BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
Font font_resources = new Font(baseFont_resources)

2.iText工具类

使用工具类可以快速生成表格、段落、标题、分页,并且对这些元素进行基本的设置。

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;

public class PDFUtil {

	static BaseFont baseFont = null;

	static {
		try {
			baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
	}

	/**
	 * PDF大标题字体
	 */
	public static Font PDFTITLEFONT = new Font(baseFont, 16, Font.BOLD);

	/**
	 * PDF小标题字体
	 */
	public static Font PDFTITLEFONT1 = new Font(baseFont, 13, Font.NORMAL);

	/**
	 * 表格宽度百分比
	 */
	public static Integer WIDTHPERCENTAGE = 98;

	/**
	 * 表格标题字体
	 */
	public static Font TITLEFONT = new Font(baseFont, 12, Font.NORMAL);

	/**
	 * 翻页加载表头
	 */
	public static Integer HEADERROWS = 1;

	/**
	 * 翻页不加载表头
	 */
	public static Integer NOHEADERROWS = 0;

	/**
	 * 表格内容字体
	 */
	public static Font CONTENTFONT = new Font(baseFont, 9, Font.NORMAL);

	/**
	 * PDF表格样式
	 */
	private static PdfPCell cell = new PdfPCell();

	/**
	 * 获取表格
	 */
	public static PdfPCell getCell() {
		// 水平居中
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		// 垂直居中
		cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
		// 边距
		cell.setPadding(1);
		// 行高
		cell.setMinimumHeight(22);
		// 不换行
		// cell.setNoWrap(true);
		// 颜色淡化
		// cell.setBorderColor(Color.decode("#EBEEF5"));
		cell.setBorderColor(new BaseColor(1));
		return cell;
	}

	/**
	 * 获取表格并赋值
	 */
	public static PdfPCell getCell(Paragraph content) {
		cell = getCell();
		// 设置内容
		cell.setPhrase(content);
		return cell;
	}

	/**
	 * @Description 生成PDF表格
	 * @param titleNum
	 *            列数
	 * @param tableWidth
	 *            列宽
	 * @param titles
	 *            标题集合
	 * @param contents
	 *            内容集合
	 * @param headerRows
	 *            是否再次加载表头
	 * @return
	 * @throws Exception
	 */
	public static PdfPTable getPDFTable(int[] tableWidth, String[] titles, List<Object> contents, int headerRows)
			throws Exception {
		// 创建表格对象
		// 列数
		PdfPTable table = new PdfPTable(titles.length);

		// 表格宽度百分比
		table.setWidthPercentage(WIDTHPERCENTAGE);

		table.setSpacingBefore(20);

		table.setSpacingAfter(20);

		// 列宽百分比
		if (tableWidth != null)
			table.setWidths(tableWidth);

		// 翻页加载表头
		if (headerRows == HEADERROWS)
			table.setHeaderRows(HEADERROWS);

		// 标题集合
		String[] pdfTitles = titles;
		if (pdfTitles != null && pdfTitles.length > 0) {
			// 标题
			for (String pdfTitle : pdfTitles) {
				PdfPCell title = getCell(new Paragraph(pdfTitle, TITLEFONT));
				table.addCell(title);
			}
		}
		// 内容集合
		if (contents != null && contents.size() > 0) {
			Field[] fields = contents.getClass().getDeclaredFields();
			String[] fieldNames = new String[fields.length];
			for (int i = 0; i < fields.length; i++) {
				fieldNames[i] = fields[i].getName();
			}
		}

		// 内容集合
		if (contents != null && contents.size() > 0) {
			for (Object obj : contents) {
				Field[] fields = obj.getClass().getDeclaredFields();
				String[] fieldNames = new String[fields.length];
				for (int i = 0; i < fields.length; i++) {
					fieldNames[i] = fields[i].getName();
					String firstLetter = fieldNames[i].substring(0, 1).toUpperCase();
					String getter = "get" + firstLetter + fieldNames[i].substring(1);
					Method method = obj.getClass().getMethod(getter, new Class[] {});
					Object value = method.invoke(obj, new Object[] {});
					PdfPCell content = getCell(new Paragraph(String.valueOf(value), CONTENTFONT));
					table.addCell(content);
				}
				// 撑行数,否则最后一行会消失
				table.addCell("");
				table.completeRow();
			}
		}
		return table;
	}

	/**
	 * @param content 段落内容
	 * @param top 上边距
	 * @param bottom 下边距
	 * @param align 居中
	 * @param type 标题类别
	 * @return
	 * @throws Exception
	 */
	public static Paragraph getPDFParagraph(String content, int top, int bottom, int align, int type) throws Exception {
		Paragraph paragraph = null;
		if (type == 1) {
			paragraph = new Paragraph(content, PDFTITLEFONT);
		} else {
			paragraph = new Paragraph(content, PDFTITLEFONT1);
		}
		paragraph.setSpacingAfter(top);
		paragraph.setSpacingBefore(bottom);
		paragraph.setAlignment(align);
		return paragraph;
	}

}
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * @Description 分页工具
 * @author ry
 * @date 2019年7月12日
 */
public class PDFMaker extends PdfPageEventHelper {

    /** 这个PdfTemplate实例用于保存总页数 */
    public PdfTemplate tpl;
    /** 页码字体 */
    public BaseFont helv;

    @Override
    public void onCloseDocument(PdfWriter writer, Document arg1) {
    tpl.beginText();
    tpl.setFontAndSize(helv, 12);
    tpl.setTextMatrix(0, 0);
    tpl.showText("" + (writer.getPageNumber() - 1));
    tpl.endText();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.lowagie.text.pdf.PdfPageEventHelper#onEndPage(com.lowagie.text.pdf
     * .PdfWriter, com.lowagie.text.Document)
     */
    @Override
    public void onEndPage(PdfWriter writer, Document document) {
    PdfContentByte cb = writer.getDirectContent();
    cb.saveState();

    String text = " Page " + writer.getPageNumber() + " of ";
    float textSize = helv.getWidthPoint(text, 9);
    float textBase = document.bottom();
    cb.beginText();
    cb.setFontAndSize(helv, 9);
    // for odd pagenumbers, show t

    cb.setTextMatrix(document.left(), textBase);
    cb.showText(text);
    cb.endText();
    cb.addTemplate(tpl, document.left() + textSize, textBase);
    cb.restoreState();
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * com.lowagie.text.pdf.PdfPageEventHelper#onOpenDocument(com.lowagie.text
     * .pdf.PdfWriter, com.lowagie.text.Document)
     */
    @Override
    public void onOpenDocument(PdfWriter writer, Document arg1) {
    try {
        // initialization of the template
        tpl = writer.getDirectContent().createTemplate(100, 100);

        // tpl.setBoundingBox(new Rectangle(0, 0, 10, 10));
        // initialization of the font
        helv = BaseFont.createFont("Helvetica", BaseFont.WINANSI, false);
    } catch (Exception e) {

    }
    }

}

3.PDF文件流下载

后台返回itext生成的输出流,这里使用工具类生成了多个表格。

public void exportPDFTest() {
		HttpServletRequest request = ServletActionContext.getRequest();
		SysUserInfo user = (SysUserInfo) request.getSession().getAttribute("user");
		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			response.setContentType("text/json");
			String resId = request.getParameter("resId");
			if (resId == null || resId.trim().equals("")) {
				SysLogUtil.saveLog(this.logService, "ID不能为空", user.getAccount(), request,
						String.valueOf(user.getId()));
				return;
			}
			ByteArrayOutputStream baos = new ByteArrayOutputStream();// 构建字节输出流
			// 实例化文档对象
			Document document = new Document(PageSize.A4, 10, 10, 10, 10);
			// 创建 PdfWriter 对象 文件的输出路径+文件的实际名称
			PdfWriter writer = PdfWriter.getInstance(document, baos);// 设置分页
			// writer.setPageEvent(new PDFMaker());
			document.open();// 打开文档
			// 创建一个段落
			document.add(PDFUtil.getPDFParagraph("测试PDF标题", 0, 20, Element.ALIGN_CENTER, 1));
			// 标题
			String[] title = { "ID", "姓名", "年龄", "生日", "出生地", "身份证", "住址" };
			// 列宽
			int tableWidth[] = { 10, 15, 15, 15, 15, 15, 15 };
			Map<String, Object> map = this.service.getPolicyOptimization(Long.parseLong(resId));
			if (map != null) {
				if (map.get("nullList") != null) {
					// 添加一个段落
					document.add(PDFUtil.getPDFParagraph("表格一", 0 ,20, Element.ALIGN_LEFT, 2));
					List list = (List<RawPolicyInfo>) map.get("nullList");
					// 获取PDFTable
					PdfPTable table = PDFUtil.getPDFTable(tableWidth, title, list, 0);
					// 添加进文档
					document.add(table);
					
				}
				if (map.get("ksList") != null) {
					// 添加一个段落
					document.add(PDFUtil.getPDFParagraph("表格二", 0, 20, Element.ALIGN_LEFT, 2));
					List list = (List<RawPolicyInfo>) map.get("ksList");
					// 获取PDFTable
					PdfPTable table = PDFUtil.getPDFTable(tableWidth, title, list, 0);
					// 添加进文档
					document.add(table);
				}
				if (map.get("ryMap") != null) {
					// 添加一个段落
					document.add(PDFUtil.getPDFParagraph("表格三", 0, 20, Element.ALIGN_LEFT, 2));
					Map maps = (Map)map.get("ryMap");
					maps.values();
					for (Object value : maps.values()) {
						List list = (List<RawPolicyInfo>)value;
						// 获取PDFTable
						PdfPTable table = PDFUtil.getPDFTable(tableWidth, title, list, 0);
						document.add(table);
			        }
				}
				if (map.get("hbMap") != null) {
					// 添加一个段落
					document.add(PDFUtil.getPDFParagraph("表格四", 0, 20, Element.ALIGN_LEFT, 2));
					Map maps = (Map)map.get("hbMap");
					maps.values();
					for (Object value : maps.values()) {
						List list = (List<RawPolicyInfo>)value;
						// 获取PDFTable
						PdfPTable table = PDFUtil.getPDFTable(tableWidth, title, list, 0);
						document.add(table);
			        }
				}
				if (map.get("ctMap") != null) {
					// 添加一个段落
					document.add(PDFUtil.getPDFParagraph("表格五", 0, 20, Element.ALIGN_LEFT, 2));
					Map maps = (Map)map.get("ctMap");
					maps.values();
					for (Object value : maps.values()) {
						List list = (List<RawPolicyInfo>)value;
						// 获取PDFTable
						PdfPTable table = PDFUtil.getPDFTable(tableWidth, title, list, 0);
						document.add(table);
			        }
				}
			}
			// 关闭文档
			if (document != null) {
				document.close();
			}
			if (baos != null) {
				try {
					baos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			String fileName = "测试PDF.pdf";
			String agent = (String) request.getHeader("USER-AGENT");
			if (agent != null && agent.indexOf("MSIE") == -1) {
				// FF
				fileName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(fileName.getBytes("UTF-8")))) + "?=";
				response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
			} else {
				// IE
				fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");
				response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
			}
			OutputStream os = response.getOutputStream();
			// 设置文件大小
			// response.setContentLength((int) f.length());
			os.write(baos.toByteArray());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
//jsp页面调用
function exportPDF() {
		var url="exportPDFTest.action?resId="+nowSelectedFw;  
		window.location.href=url;
}

4.效果图

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RedEric

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值