java通过xml配置属性用iText包生成pdf文件
2016-05-05 20:47
691 查看
总共步骤为:1、提供一个需要替换参数传入类;2、解析xml文件,替换xml文件中的特定参数(写死格式);3、解析xml文件中的pdf文件布局(包括表、段落、文字、换行等);
4、生成pdf文件。
第一步:参数可以用map存放,根据相应的key可以取到对应的值,如果值为List,则可用来替换表格中的参数,根据List大小扩展表格的行数。
第二步:解析xml文件,可以直接用dom4j进行解析标准格式的xml文件。此次先用文件流进行解析吧,方便将拿到的参数进行字符串替换操作。解析代码如下:
用第一步set进的对象中的map内容,替换返回的Str中的内容。
示例一种根据特定的xml格式设定的表达式替换方法,代码如下:
2016/05/06 开写:
熟练运用正则表达式能节省很多代码。正则表达式一般包括两种引擎,一种传统NFA,一种DFA。java语言使用的是NFA引擎,使用表达式去匹配内容,当遇到第一个符合条件的值时,接收第一个匹配项。而DFA引擎则是用内容去匹配表达式。若需要匹配所有内容则需要用到Pattern与Matcher,用Matcher.find()读取匹配的下一个字符序列。
第三步:使用jdom解析xml文件,用模型对象存储各个pdf对象的值。
此步骤需要有面向对象编程思想,首先需要一个DocModel存放包含全局参数的全局对象GlobalModel,以及包含内容参数的内容体对象BodyModel。
其次BodyModel向下可以包含pdf的各个组建对象,包括单行(p)、换页(np)、图片(img)、表格(table)、直线(line)、换行(br)。各个元组的内容append到BodyModel对象中。
第四步:创建各个对象元组的具体内容,加入到Document,生成pdf文件。
主要调用iText包里的方法set配置参数,生成pdf内容。代码如下:
/**
* 根据model对象的内容,开始写入pdf文件
* @param model 存放文件内容文件对象
* @param os 文件输出流
* @throws Exception
*/
public void create(DocModel model, OutputStream os) throws Exception {
this.docModel = model;
PageModel pageModel = this.docModel.getGlobalModel().getPage();
Document document = null;
try {
if ((pageModel.getMarginLeft() < 0) && (pageModel.getMarginRight() < 0) && (pageModel.getMarginTop() < 0) && (pageModel.getMarginBottom() < 0))
document = new Document(PageSize.A4); //如果page参数设置不完整,则默认使用A4大小
else {
document = new Document(PageSize.A4, pageModel.getMarginLeft(),
pageModel.getMarginRight(), pageModel.getMarginTop(),
pageModel.getMarginBottom());
}
this.pdfWriter = PdfWriter.getInstance(document, os);
document.setFooter(createHeaderFooter());
document.open();
createContent(document, this.docModel.getBodyModel().getCells());
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (document != null)
document.close();
if (this.pdfWriter != null)
this.pdfWriter.close();
}
}
/**
* 添加各元组实例对象到Document中
* @param document
* @param cells
* @throws Exception
*/
private void createContent(Document document, List<CellModel> cells) throws Exception {
for (CellModel cell : cells)
if ((cell instanceof PModel)) //CellModel为所有模型均须实现的公共接口,可以用 instanceof 判断具体内容具体是被哪个接口实现类实例化的
document.add((Element) new PCreator(this.docModel.getGlobalModel(), this.pdfWriter).create(cell));
else if ((cell instanceof LineModel))
{
new LineCreator(this.docModel.getGlobalModel(), this.pdfWriter,document, 10.0F).create(cell);
}
else if ((cell instanceof ImgModel))
document.add((Element) new ImgCreator(this.docModel.getGlobalModel(), this.pdfWriter).create(cell));
else if ((cell instanceof TableModel))
document.add((Element) new TableCreator(this.docModel.getGlobalModel(), this.pdfWriter, document).create(cell));
else if ((cell instanceof BrModel))
document.add((Element) new BrCreator(this.docModel.getGlobalModel(), this.pdfWriter).create(cell));
else if ((cell instanceof NpModel))
document.newPage();
}
到此处为止,pdf文件已经生成完成。
后续需要好好研究一下正则表达式的使用,已经拓展面向对象编程思想。
4、生成pdf文件。
第一步:参数可以用map存放,根据相应的key可以取到对应的值,如果值为List,则可用来替换表格中的参数,根据List大小扩展表格的行数。
第二步:解析xml文件,可以直接用dom4j进行解析标准格式的xml文件。此次先用文件流进行解析吧,方便将拿到的参数进行字符串替换操作。解析代码如下:
/** * 逐行读取传入的文件内容 * @param filepath 文件绝对路径和文件名 * @return 存放文件全部内容的String * @throws Exception */ public static String readFile(String filepath) throws Exception { InputStreamReader read = null; BufferedReader bufferedReader = null; FileInputStream fileInput = null; try { fileInput = new FileInputStream(filepath); read = new InputStreamReader(fileInput, "GBK");//读取文件流内容 bufferedReader = new BufferedReader(read); String lineTxt = null; StringBuffer buffer = new StringBuffer(); while ((lineTxt = bufferedReader.readLine()) != null) { buffer.append(lineTxt + "\r\n"); } String str1 = buffer.toString(); return str1; }
<span style="white-space:pre"> </span>finally { if (bufferedReader != null) bufferedReader.close(); if (read != null) read.close(); if(fileInput != null) fileInput.close(); } }将文件内容按节点进行拆分为文件头与文件体,文件头存放字体配置文件头、文件页的信息,文件体存放具体需要展示的pdf内容。
用第一步set进的对象中的map内容,替换返回的Str中的内容。
示例一种根据特定的xml格式设定的表达式替换方法,代码如下:
/** * 找到始终的表达式,并进行替换。 表达式的格式为: ${status.index -----} * @param str * @param statusName * @param index * @return * @throws Exception */ private String findExpressAndReplace(String str, String statusName, int index) throws Exception { if ((statusName == null) || (statusName.trim().equals(""))) return str; StringBuffer sb = new StringBuffer(); // Pattern pattern = Pattern.compile("\\$\\{[\\w\\W]*?" + statusName + "\\.index[\\w\\W]*?\\}"); Pattern pattern = Pattern.compile("\\$\\{" + statusName + "\\.index[\\w\\W]*?\\}"); Matcher m = pattern.matcher(str); while (m.find()) { String sValue = m.group(0); sValue = sValue.substring(2, sValue.length() - 1); sValue = sValue.replace(statusName + ".index", index+""); sValue = runJsExpression(sValue); m.appendReplacement(sb, sValue); } m.appendTail(sb); return sb.toString(); } private String runJsExpression(String expression) throws Exception { ScriptEngineManager manager = new ScriptEngineManager(); ScriptEngine engine = manager.getEngineByName("JavaScript"); System.out.println("表达式计算结果为:"+engine.eval(expression).toString()); return engine.eval(expression).toString(); }2016/05/05 就写到这了。
2016/05/06 开写:
熟练运用正则表达式能节省很多代码。正则表达式一般包括两种引擎,一种传统NFA,一种DFA。java语言使用的是NFA引擎,使用表达式去匹配内容,当遇到第一个符合条件的值时,接收第一个匹配项。而DFA引擎则是用内容去匹配表达式。若需要匹配所有内容则需要用到Pattern与Matcher,用Matcher.find()读取匹配的下一个字符序列。
第三步:使用jdom解析xml文件,用模型对象存储各个pdf对象的值。
此步骤需要有面向对象编程思想,首先需要一个DocModel存放包含全局参数的全局对象GlobalModel,以及包含内容参数的内容体对象BodyModel。
其次BodyModel向下可以包含pdf的各个组建对象,包括单行(p)、换页(np)、图片(img)、表格(table)、直线(line)、换行(br)。各个元组的内容append到BodyModel对象中。
第四步:创建各个对象元组的具体内容,加入到Document,生成pdf文件。
主要调用iText包里的方法set配置参数,生成pdf内容。代码如下:
/**
* 根据model对象的内容,开始写入pdf文件
* @param model 存放文件内容文件对象
* @param os 文件输出流
* @throws Exception
*/
public void create(DocModel model, OutputStream os) throws Exception {
this.docModel = model;
PageModel pageModel = this.docModel.getGlobalModel().getPage();
Document document = null;
try {
if ((pageModel.getMarginLeft() < 0) && (pageModel.getMarginRight() < 0) && (pageModel.getMarginTop() < 0) && (pageModel.getMarginBottom() < 0))
document = new Document(PageSize.A4); //如果page参数设置不完整,则默认使用A4大小
else {
document = new Document(PageSize.A4, pageModel.getMarginLeft(),
pageModel.getMarginRight(), pageModel.getMarginTop(),
pageModel.getMarginBottom());
}
this.pdfWriter = PdfWriter.getInstance(document, os);
document.setFooter(createHeaderFooter());
document.open();
createContent(document, this.docModel.getBodyModel().getCells());
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (document != null)
document.close();
if (this.pdfWriter != null)
this.pdfWriter.close();
}
}
/**
* 添加各元组实例对象到Document中
* @param document
* @param cells
* @throws Exception
*/
private void createContent(Document document, List<CellModel> cells) throws Exception {
for (CellModel cell : cells)
if ((cell instanceof PModel)) //CellModel为所有模型均须实现的公共接口,可以用 instanceof 判断具体内容具体是被哪个接口实现类实例化的
document.add((Element) new PCreator(this.docModel.getGlobalModel(), this.pdfWriter).create(cell));
else if ((cell instanceof LineModel))
{
new LineCreator(this.docModel.getGlobalModel(), this.pdfWriter,document, 10.0F).create(cell);
}
else if ((cell instanceof ImgModel))
document.add((Element) new ImgCreator(this.docModel.getGlobalModel(), this.pdfWriter).create(cell));
else if ((cell instanceof TableModel))
document.add((Element) new TableCreator(this.docModel.getGlobalModel(), this.pdfWriter, document).create(cell));
else if ((cell instanceof BrModel))
document.add((Element) new BrCreator(this.docModel.getGlobalModel(), this.pdfWriter).create(cell));
else if ((cell instanceof NpModel))
document.newPage();
}
到此处为止,pdf文件已经生成完成。
后续需要好好研究一下正则表达式的使用,已经拓展面向对象编程思想。
相关文章推荐
- Spring Security 4 整合Hibernate Bcrypt密码加密(带源码)
- 【第二章】 IoC 之 2.3 IoC的配置使用——跟我学Spring3
- 手动制作hadoop-eclipse-plugin插件
- Java线程中 start与run的区别以及源码分析
- Spring IOC 深入分析
- Java线程之CompletionService批处理任务
- Myeclipse的使用
- struts.properties配置详解
- 使用纯java基本语言实现泰勒展开的sin和cos计算
- 排序算法java 一 --快速排序、直接插入、希尔排序
- Eclipse常用快捷键
- JAVA 内存泄露详解(原因、例子及解决)
- Java并发编程的艺术(上)
- JAVA修饰符
- Java垃圾回收
- 非spring组件servlet、filter、interceptor中注入spring bean
- java软件设计的三层结构
- java序列化ClassNotFoundException
- java文件输入输出流
- Java实现十进制数转化为二进制数的算法