使用itext将xml转换为pdf(一)

一、整体思路

1.因为项目中打印pdf多为表格,所以将所有组件统一使用表格处理。对单元格的边框做处理,达到普通文本的目的

2.xml定义表格的格式及普通文本内容,使用{{变量名称}}来表示需要使用变量替换。

3.考虑到一个pdf中可能有多个数据源,所以使用map来传递参数。

二、实现

1.xml及dtd定义。

这里有一个问题没有解决,那就是dtd文件的位置。先附上代码,待会说问题

我用eclipse新建的java project,新建文件夹xml-config并加入build path,然后在xml-config下直接存储xml文件,NewFile.xml文件内容如下:







	
		
				<text>事务所基本信息</text>
			
				
						
						
						
						
						
						
						
						
						
						
						
基本情况
名称 {{cpafName}}
所属行政区划 {{divisionProvince}} 组织形式 {{orgForm}}
执业许可批准日期 {{approDate}} 统一社会信用代码 {{regisCno}}
执业许可批准文号 {{rna}} 执业证书编号 {{cpafCno}}
注册资本(出资总额)(单位:万元) {{totalInves}} 分所数量 {{cpafbNum}}
国际网络名称(如有) {{internetName}}
经营场所 {{officeLocation}}
通讯地址 {{address}}
报备业务联系人 {{reporter}} 电子邮箱 {{email}}
报备业务联系电话 {{phone}}
<text>测试横向页面</text>
基本情况
名称 {{cpafName}}
所属行政区划 {{divisionProvince}} 组织形式 {{orgForm}}
执业许可批准日期 {{approDate}} 统一社会信用代码 {{regisCno}}
执业许可批准文号 {{rna}} 执业证书编号 {{cpafCno}}
注册资本(出资总额)(单位:万元) {{totalInves}} 分所数量 {{cpafbNum}}
国际网络名称(如有) {{internetName}}
经营场所 {{officeLocation}}
通讯地址 {{address}}
报备业务联系人 {{reporter}} 电子邮箱 {{email}}
报备业务联系电话 {{phone}}

dtd文件内容如下











dtd主要是对xml内容的约束与检查。问题是,不管是单独将dtd放在xml-config,还是工程根目录下,都会报错,说在另一个位置找不到dtd,但是在两个位置都放dtd,则可以运行。至今不知道为什么。

2.将xml中的内容翻译为bean

Tablepage

package com.ufgov.pdf.entity;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

/**
 * 对应xml中的tablepage标签
 * 
 * @author lihh
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "tablepage")
@XmlType(propOrder = { "title", "tableList" })
public class Tablepage {

	@XmlElement(name = "title")
	private Title title;

	@XmlElementWrapper(name = "tables")
	@XmlElement(name = "table")
	private List tableList;

	public Title getTitle() {
		return title;
	}

	public void setTitle(Title title) {
		this.title = title;
	}

	public List
getTableList() { return tableList; } public void setTableList(List
tableList) { this.tableList = tableList; } }

Title

package com.ufgov.pdf.entity;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = { "text" })
public class Title {

	@XmlElement(name = "text", required = true)
	private String text;

	@XmlAttribute(name = "align")
	private String align;

	@XmlAttribute(name = "v-align")
	private String vAlign;

	@XmlAttribute(name = "font-family")
	private String fontFamily;

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getAlign() {
		return align;
	}

	public void setAlign(String align) {
		this.align = align;
	}

	public String getvAlign() {
		return vAlign;
	}

	public void setvAlign(String vAlign) {
		this.vAlign = vAlign;
	}

	public String getFontFamily() {
		return fontFamily;
	}

	public void setFontFamily(String fontFamily) {
		this.fontFamily = fontFamily;
	}

}

Table

package com.ufgov.pdf.entity;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;

/**
 * 对应xml中的table标签
 * 
 * @author lihh
 *
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "table", propOrder = { "title", "trList" })
public class Table {

	@XmlElement(name = "title")
	private Title title;

	@XmlElementWrapper(name = "trs")
	@XmlElement(name = "tr")
	private List
trList; @XmlAttribute(name = "cols") private String cols; @XmlAttribute(name = "font-family") private String fontFamily; @XmlAttribute(name = "entity") private String entity; @XmlAttribute(name = "rotate") private String rotate; public String getRotate() { return rotate; } public void setRotate(String rotate) { this.rotate = rotate; } public Title getTitle() { return title; } public void setTitle(Title title) { this.title = title; } public List getTrList() { return trList; } public void setTrList(List trList) { this.trList = trList; } public String getCols() { return cols; } public void setCols(String cols) { this.cols = cols; } public String getFontFamily() { return fontFamily; } public void setFontFamily(String fontFamily) { this.fontFamily = fontFamily; } public String getEntity() { return entity; } public void setEntity(String entity) { this.entity = entity; } }

Tr

package com.ufgov.pdf.entity;

import java.util.List;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "tr",propOrder= {"tdList"})
public class Tr {

	@XmlElementWrapper(name = "tds")
	@XmlElement(name = "td")
	private List
tdList; public List getTdList() { return tdList; } public void setTdList(List tdList) { this.tdList = tdList; } }

Td

package com.ufgov.pdf.entity;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "td", propOrder = { "text" })
public class Td {

	@XmlAttribute(name = "rowspan")
	private String rowspan;

	@XmlAttribute(name = "border-width")
	private String borderWidth;

	@XmlAttribute(name = "colspan")
	private String colspan;

	@XmlAttribute(name = "align")
	private String align;

	@XmlAttribute(name = "v-align")
	private String vAlign;

	@XmlElement(name = "text")
	private String text;

	public String getBorderWidth() {
		return borderWidth;
	}

	public void setBorderWidth(String borderWidth) {
		this.borderWidth = borderWidth;
	}
	
	public String getSText() {
		return text;
	}

	public void setString(String text) {
		this.text = text;
	}

	public String getRowspan() {
		return rowspan == null ? "1" : rowspan;
	}

	public void setRowspan(String rowspan) {
		this.rowspan = rowspan;
	}

	public String getColspan() {
		return colspan == null ? "1" : colspan;
	}

	public void setColspan(String colspan) {
		this.colspan = colspan;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public String getAlign() {
		return align;
	}

	public void setAlign(String align) {
		this.align = align;
	}

	public String getvAlign() {
		return vAlign;
	}

	public void setvAlign(String vAlign) {
		this.vAlign = vAlign;
	};

}

上述实体需要用到XmlAccessorType等注解,不懂的话可以百度。

3.下边是工具类

a.xml转为bean

这个是从网上找的jaxb2的用法

package com.ufgov.pdf.util;

import java.io.StringReader;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;

/**
 * Jaxb2工具类
 */
public class JaxbUtil {

	/**
	 * xml转换成JavaBean
	 * 
	 * @param xml
	 * @param c
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static  T converyToJavaBean(String xml, Class c) {
		T t = null;
		try {
			JAXBContext context = JAXBContext.newInstance(c);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			t = (T) unmarshaller.unmarshal(new StringReader(xml));
		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}

//	/**
//	 * JavaBean转换成xml 默认编码UTF-8
//	 * 
//	 * @param obj
//	 * @param writer
//	 * @return
//	 */
//	public static String convertToXml(Object obj) {
//		return convertToXml(obj, "UTF-8");
//	}

//	/**
//	 * JavaBean转换成xml
//	 * 
//	 * @param obj
//	 * @param encoding
//	 * @return
//	 */
//	public static String convertToXml(Object obj, String encoding) {
//		String result = null;
//		try {
//			JAXBContext context = JAXBContext.newInstance(obj.getClass());
//			Marshaller marshaller = context.createMarshaller();
//			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
//			marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
//
//			StringWriter writer = new StringWriter();
//			marshaller.marshal(obj, writer);
//			result = writer.toString();
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//
//		return result;
//	}

}

b.数据库测试用类

package com.ufgov.pdf.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Map;

public class DBHelper {

    /**
     * 将下划线风格替换为驼峰风格
     *
     * @param inputString
     * @return
     */
    private static String underlineToCamelhump(String inputString) {
        StringBuilder sb = new StringBuilder();

        boolean nextUpperCase = false;
        for (int i = 0; i < inputString.length(); i++) {
            char c = inputString.charAt(i);
            if (c == '_') {
                if (sb.length() > 0) {
                    nextUpperCase = true;
                }
            } else {
                if (nextUpperCase) {
                    sb.append(Character.toUpperCase(c));
                    nextUpperCase = false;
                } else {
                    sb.append(Character.toLowerCase(c));
                }
            }
        }
        return sb.toString();
    }
	public static Map getData(String sql) throws ClassNotFoundException, SQLException {
		Class.forName("oracle.jdbc.driver.OracleDriver");
		String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
		String user = "test";
		String password = "1";
		Connection conn = DriverManager.getConnection(url, user, password);
		Statement stmt = conn.createStatement();
		ResultSet rs = stmt.executeQuery(sql);
		ResultSetMetaData data = rs.getMetaData();
		Map map = null;
		while (rs.next()) {
			 map = new HashMap();
			for (int i = 1; i <= data.getColumnCount(); i++) {// 数据库里从 1 开始

				String c = data.getColumnName(i);
				String v = rs.getString(c);
				System.out.println(c + ":" + v + "\t");
				map.put(underlineToCamelhump(c), v);
			}
			System.out.println("======================");
		}
		rs.close();
		stmt.close();
		conn.close();
		return map;
	}
	
	public static void main(String[] args) throws ClassNotFoundException, SQLException {
		String sql  = "select * from cpa_cpaf_bir t where t.report_no ='CG201700042045'";
		System.out.println(getData(sql));
	}
}

c.核心转换类

package com.ufgov.pdf.util;

import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.ufgov.pdf.entity.Table;
import com.ufgov.pdf.entity.Tablepage;
import com.ufgov.pdf.entity.Td;
import com.ufgov.pdf.entity.Title;
import com.ufgov.pdf.entity.Tr;

/**
 * 到处pdf帮助类 Created by lihhz on 2017/10/16.
 */
public class PdfHelper {

	/**
	 * xml与数据装配页面
* 核心方法,负责输出文档 * * @param tablepage * xml结构 * @param map * 数据结构 * @throws Exception */ public static void convert(Tablepage tablepage, Map> map) throws Exception { // TODO:这里要设置一个文件名称,暂时先写死 // Title title = tablepage.getTitle(); // String fileName = title.getText() + ".pdf"; String fileName = "测试文档.pdf"; BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); Font font = new Font(baseFont, 10, Font.NORMAL); // TODO:这个地方如果拿到注会用的话,要改成使用response输出 File file = new File(fileName); FileOutputStream out = new FileOutputStream(file); // TODO:这个A4要不要做配置? Rectangle rectPageSize = new Rectangle(PageSize.A4); Document document = new Document(rectPageSize, -50, -50, 10, 20); PdfWriter.getInstance(document, out); document.open(); // PdfPTable table_title1 = new PdfPTable(1); // setTitle(document, title, table_title1); List tableList = tablepage.getTableList(); // TODO:这个地方可以做成静态数据,也可以不做,只是为了输出的时候更简单 Map posMap = new HashMap(); posMap.put("center", Element.ALIGN_CENTER); posMap.put("left", Element.ALIGN_LEFT); posMap.put("right", Element.ALIGN_RIGHT); posMap.put("top", Element.ALIGN_TOP); posMap.put("middle", Element.ALIGN_MIDDLE); posMap.put("bottom", Element.ALIGN_BOTTOM); int size = tableList.size(); if (tableList == null || size < 1) { return; } for (Table table : tableList) { String rotate = table.getRotate(); Rectangle rect = new Rectangle(PageSize.A4); // 添加横向支持 if (rotate.equals("true")) { document.setPageSize(rect.rotate()); } document.newPage(); PdfPTable table1 = new PdfPTable(12); // table1.addCell("测试一下"); // table1.getDefaultCell().setBorder(PdfPCell.NO_BORDER); // table1.setLockedWidth(true); Title t = table.getTitle(); PdfPTable tableTitle = new PdfPTable(1); if (t != null && t.getText() != null) { setTitle(document, t, tableTitle); } List trList = table.getTrList(); String entity = table.getEntity(); Map obj = map.get(entity); if (null == obj) { System.out.println("警告:出现空值!"); } if (trList == null || trList.size() < 1) { document.add(table1); continue; } for (Tr tr : trList) { List
tdList = tr.getTdList(); if (tdList == null || tdList.size() < 1) { continue; } for (Td td : tdList) { String text = td.getText(); if (text.startsWith("{{") && text.endsWith("}}")) { String key = text.replace("{{", "").replace("}}", ""); text = obj.containsKey(key) && obj.get(key) != null ? obj.get(key).toString() : ""; } PdfPCell cell = new PdfPCell(new Paragraph(text, font)); String borderWidth = td.getBorderWidth(); float[] borderArr = getBorder(borderWidth); if (borderArr != null) { cell.setBorderWidthTop(borderArr[0]); cell.setBorderWidthRight(borderArr[1]); cell.setBorderWidthBottom(borderArr[2]); cell.setBorderWidthLeft(borderArr[3]); } cell.setColspan(Integer.parseInt(td.getColspan())); cell.setRowspan(Integer.parseInt(td.getRowspan())); cell.setHorizontalAlignment(posMap.get(td.getAlign())); cell.setVerticalAlignment(posMap.get(td.getvAlign())); cell.setMinimumHeight(20f); table1.addCell(cell); } } document.add(table1); } document.close(); } /** * TODO:在这里设置边框。暂时没有什么好的方法 */ private static float[] getBorder(String borderWidth) { if (borderWidth == null) { return null; } float[] borderArr = new float[4]; String[] borderWidths = borderWidth.split("\\s+"); // 校验边框 int borderNum = borderWidths.length; switch (borderNum) { case 1: borderArr[0] = Float.parseFloat(borderWidths[0]); borderArr[1] = borderArr[0]; borderArr[2] = borderArr[0]; borderArr[3] = borderArr[0]; break; case 2: borderArr[0] = Float.parseFloat(borderWidths[0]); borderArr[1] = borderArr[0]; borderArr[2] = Float.parseFloat(borderWidths[1]); borderArr[3] = borderArr[2]; break; case 3: borderArr[0] = Float.parseFloat(borderWidths[0]); borderArr[1] = Float.parseFloat(borderWidths[1]); borderArr[2] = Float.parseFloat(borderWidths[2]); borderArr[3] = 0; break; case 4: borderArr[0] = Float.parseFloat(borderWidths[0]); borderArr[1] = Float.parseFloat(borderWidths[1]); borderArr[2] = Float.parseFloat(borderWidths[2]); borderArr[3] = Float.parseFloat(borderWidths[3]); break; default: borderArr[0] = borderArr[1] = borderArr[2] = borderArr[3] = 1; break; } return borderArr; } private static void setTitle(Document document, Title title, PdfPTable tableTitle) throws Exception { PdfPCell cell = new PdfPCell(new Paragraph(title.getText(), new Font( BaseFont.createFont(title.getFontFamily(), "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 17, Font.NORMAL))); // TODO:这个地方要设置标题的位置,暂时先不写 cell.setHorizontalAlignment(Element.ALIGN_CENTER); // 设置单元格中文本位置(居中:ALIGN_CENTER;靠左:ALIGN_LEFT;靠右:ALIGN_RIGHT) cell.setVerticalAlignment(Element.ALIGN_MIDDLE); // 文本垂直方向位置(靠上:ALIGN_TOP;居中:ALIGN_MIDDLE;靠下:ALIGN_BOTTOM;) cell.setBorderWidth(0f); // 设置单元格边框,参数都为float cell.setPaddingBottom(20f); // 设置单元格文本内边距 tableTitle.addCell(cell); document.add(tableTitle); } }

其它测试类

package com.ufgov.pdf.util;

import java.math.BigDecimal;
import java.text.NumberFormat;
import java.util.Locale;

/**
 * 测试用的工具类,在cpams中已经存在,可以删除了
 * @author lihh
 *
 */
public class CanDel {

	/**
	 * 
	 * @param number
	 *            要转换的数字
	 * @param digit
	 *            保留小数点位数
	 * @return
	 * @author zhangdand at 2018年3月1日下午4:10:52
	 */
	public static String numberFormat(BigDecimal number, int digit) {
		String result = "0";
		// 小数点后边的数字(不包括.)
		String digitStr = "";
		NumberFormat usFormat = NumberFormat.getIntegerInstance(Locale.US);
		if (number == null || number.compareTo(new BigDecimal(0)) == 0) {
			if (digit > 0) {
				for (int i = 0; i < digit; i++) {
					digitStr += "0";
				}
				result += "." + digitStr;
			}
		} else {
			// 保留两位小数
			usFormat.setMaximumFractionDigits(digit);
			result = usFormat.format(number);
			if (result.indexOf(".") < 0 && digit > 0) {
				for (int i = 0; i < digit; i++) {
					digitStr += "0";
				}
				result += "." + digitStr;
			} else if (result.indexOf(".") > 0) {
				String[] tmpArry = result.split("\\.");
				digitStr = tmpArry[1];
				// 处理小数点结尾0不显示的情况
				if (digitStr.length() < digit) {
					int tmpN = digit - digitStr.length();
					for (int i = 0; i < tmpN; i++) {
						digitStr += "0";
					}
					result = tmpArry[0] + "." + digitStr;
				}
			}
		}
		return result;
	}
}

4.实体基类

所有需要转pdf的实体继承基类,主要是toMap方法,不过在main方法中并没有用到

package com.ufgov.pdf.entity;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import com.ufgov.pdf.util.CanDel;

/**
 * pdf bean基类. 将需要转换为Map的bean继承自此抽象类
 * 如果所需要的类型在toMap方法中不存在,可以添加;
 * 如果基类的toMap方法实在不能满足您的需求,您可以重写此方法
 * 
 * @author lihh
 *
 */
public abstract class BaseMapBean {

	/**
	 * 转化为Map
	 * @return
	 */
	public Map toMap() {
		Map map = new HashMap();
		try {
			// 内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 PersonBean中有属性 name, 那我们可以通过
			// getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这就是默认的规则。 Java
			// 中提供了一套 API 用来访问某个属性的 getter/setter 方法,通过这些 API 可以使你不需要了解这个规则(但你最好还是要搞清楚),这些
			// API 存放于包 java.beans 中。注意:
			// PersonBean中属性mN的getter/setter方法必须满足javaBean命名规范,即getmN,不能写作getMN,否则转换失败。
			BeanInfo beanInfo = Introspector.getBeanInfo(this.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(this);
					if (value != null) {
						if (value instanceof BigDecimal) {
							value = CanDel.numberFormat((BigDecimal) value, 2);
						} else {
							System.out.println(value.getClass().toString());
						}
					}
					map.put(key, value);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("transBean2Map Error " + e);
		}

		return map;
	}
}

main测试方法

package com.ufgov.pdf.util;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.io.SAXReader;

import com.ufgov.pdf.entity.Tablepage;

/**
 * 导出PDF的Main方法
 * 
 * @author lihh
 *
 */
public class ExportPdfImpl {

	/**
	 * 这个在注会中写成一个方法,该方法接受一个xml文件路径参数,一个map
	 * @param args
	 */
	public static void main(String[] args) {
		SAXReader sax = new SAXReader();// 创建一个SAXReader对象
		File xmlFile = new File("xml-config/NewFile.xml");// 根据指定的路径创建file对象
		try {
			// 获取document对象,如果文档无节点,则会抛出Exception提前结束
			Document document = sax.read(xmlFile);
			Tablepage tablepage = JaxbUtil.converyToJavaBean(document.asXML(), Tablepage.class);
			Map> map = new HashMap>();

			String sql = "select * from cpa_cpaf_bir t where t.report_no ='CG201700042045'";
			map.put("cpafInfo", DBHelper.getData(sql));
			PdfHelper.convert(tablepage, map);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
	// public static void getRoot() {
	// SAXReader sax = new SAXReader();// 创建一个SAXReader对象
	// File xmlFile = new File("xml-config/NewFile.xml");// 根据指定的路径创建file对象
	// try {
	// // 获取document对象,如果文档无节点,则会抛出Exception提前结束
	// Document document = sax.read(xmlFile);
	// Element root = document.getRootElement();// 获取根节点
	// Tablepage tablepage = new Tablepage();
	// getNodes(root, tablepage);// 从根节点开始遍历所有节点
	// } catch (DocumentException e) {
	// e.printStackTrace();
	// }
	//
	// }
	//
	// /**
	// * 从指定节点开始,递归遍历所有子节点
	// *
	// * @author chenleixing
	// */
	// public static void getNodes(Element node, Tablepage tablepage) {
	// System.out.println("--------------------");
	// if (node.getName().equals("title")) {
	// tablepage.setTitle(node.getText());
	// } else if (node.getName().equals("table")) {
	// Table table = new Table();
	// }
	// // 当前节点的名称、文本内容和属性
	// System.out.println("当前节点名称:" + node.getName());// 当前节点名称
	// System.out.println("当前节点的内容:" + node.getTextTrim());// 当前节点名称
	// List listAttr = node.attributes();// 当前节点的所有属性的list
	// for (Attribute attr : listAttr) {// 遍历当前节点的所有属性
	// String name = attr.getName();// 属性名称
	// String value = attr.getValue();// 属性的值
	// System.out.println("属性名称:" + name + "属性值:" + value);
	// }
	//
	// // 递归遍历当前节点所有的子节点
	// List listElement = node.elements();// 所有一级子节点的list
	// for (Element e : listElement) {// 遍历所有一级子节点
	// // getNodes(e);// 递归
	// }
	// }

}

至此,整个项目结束

导出的pdf还有一个问题就是,在设置边框后,放大pdf,会看到设置的边框外侧和其它没有手动设置、正常的cell边框有细微的距离,这个不知道怎么解决

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