/**
* <br>Created on 2013-8-16
* @author Y.Huang - 黄勇
*/
package com.hy.pdf;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.html.simpleparser.HTMLWorker;
import com.itextpdf.text.html.simpleparser.StyleSheet;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.AcroFields.FieldPosition;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
/**
* 组件名称:PDF打印输出组件<br>
* 创建时间:2013-8-16 版本:1.0<br>
* 更新时间:2013-8-23 版本:1.5<br>
* @author Y.Huang - 黄勇
* <h1>功能支持:</h1>
* <ul>
* <li>在PDF模板指定位置插入文本(包含多行文本显示)</li>
* <li>在PDF模板指定位置插入图片,图宽或高超出范围则图片自动按比例缩小到合适大小</li>
* <li>在PDF模板指定位置插入html代码,html代码将解析为显示文本及图片---此功能主要为实现
* 图文混排,暂时不支持复杂样式。
* </li>
* </ul>
* <h1>使用方法</h1>
* <ul>
* 本类方法addText(*)、addImage(*)、addHtml(*)、print(*)对外开放。
* 其中前三个方法用于用户添加打印数据,最后一个方法用于执行PDF文件的打印
* </ul>
* * <h1>本类一依赖包列表:</h1>
* <ul>
* <li>itext-asian-5.4.3.jar</li>
* <li>itextpdf-5.4.3.jar</li>
* <li>xmlworker-5.4.3.jar</li>
* </ul>
*/
public class LcmPdfPrinter {
public final static String PAGECOUNTKEY="总页数";
public final static String PAGEKEY="页数";
public final static String FP_BG_COLOR="bgcolor";
public final static String FP_TEXT_COLOR="textcolor";
public final static String FP_TEXT_FONT="textfont";
public final static String FP_TEXT_SIZE="textsize";
private float offset=10f;
public BaseFont defaultFont;
public float defaultFontSize;
private Map<String,String> template;
private Map<String,List<PDFText>> valuesList;
private Map<String,List<PDFImage>> imageList;
private Map<String,List<PDFHtml>> htmlList;
/**
*黑体字
*/
public static BaseFont SimHei=null;
/**
*宋体字
*/
public static BaseFont SimSuncss=null;
/**
*新宋体字
*/
public static BaseFont NSimSun=null;
static{
try {
SimHei=BaseFont.createFont("ext/glaway/mpmplus/pdfprint/fonts/SIMHEI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
SimSuncss=BaseFont.createFont("ext/glaway/mpmplus/pdfprint/fonts/SIMSUN.TTC,0", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
NSimSun=BaseFont.createFont("ext/glaway/mpmplus/pdfprint/fonts/SIMSUN.TTC,1", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
} catch (Exception e) {
e.printStackTrace();
}
}
public LcmPdfPrinter() {
try {
defaultFont= BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
} catch (Exception e) {
System.out.println("默认字体不存在,你需要提供iText的亚洲语言包iTextAsian或者设置你的本地语言");
e.printStackTrace();
}
template=new LinkedHashMap<String, String>();
valuesList=new HashMap<String, List<PDFText>>();
imageList=new HashMap<String, List<PDFImage>>();
htmlList=new HashMap<String, List<PDFHtml>>();
}
public Rectangle getRectangleInfo(String templName,String key){
Rectangle ret=null;
try{
PdfReader reader=new PdfReader(template.get(templName));
AcroFields af=reader.getAcroFields();
List<FieldPosition> fpList=af.getFieldPositions(key);
if(fpList==null||fpList.size()==0){
throw new Exception("在模板中未找到指定的文本域:"+key);
}
ret=fpList.get(0).position;
}catch(Exception e){
e.printStackTrace();
}
return ret;
}
/**
*为指定模板添加一个文本域数据
*/
public void addText(String templName,PDFText value){
if(!valuesList.containsKey(templName)){
valuesList.put(templName, new ArrayList<PDFText>());
}
List<PDFText> vals=valuesList.get(templName);
vals.add(value);
valuesList.put(templName, vals);
}
public PDFText addText(String templName,String key,String value){
if(!valuesList.containsKey(templName)){
valuesList.put(templName, new ArrayList<PDFText>());
}
List<PDFText> vals=valuesList.get(templName);
PDFText v=new PDFText(key, value);
vals.add(v);
return v;
}
public PDFImage addImage(String templName,Image image){
return addImage(templName,null,image);
}
public PDFImage addImage(String templName,String imageFileName){
return addImage(templName,null,imageFileName);
}
public PDFImage addImage(String templName,String key,Image image){
if (!imageList.containsKey(templName)) {
imageList.put(templName, new ArrayList<PDFImage>());
}
List<PDFImage> vals = imageList.get(templName);
PDFImage img = new PDFImage(key,image);
vals.add(img);
return img;
}
public PDFImage addImage(String templName,String key,String imageFileName){
try {
Image img = Image.getInstance(imageFileName);
return addImage(templName,key, img);
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
public PDFHtml addHtml(String templName,String key,String html){
return addHtml(templName, key, new StringReader(html));
}
public PDFHtml addHtml(String templName,String key,File file) throws Exception{
return addHtml(templName, key, new FileReader(file));
}
public PDFHtml addHtml(String templName,String key,Reader reader){
if (!htmlList.containsKey(templName)) {
htmlList.put(templName, new ArrayList<PDFHtml>());
}
List<PDFHtml> vals = htmlList.get(templName);
PDFHtml html = new PDFHtml(key,reader);
vals.add(html);
return html;
}
/**
*添加一个模板页
*/
public String addTempl(String templName,String templPath){
template.put(templName, templPath);
return templName;
}
public void removeTempl(String templName){
template.remove(templName);
}
/**
*<h1>将输出流写入指定的路径的文件中</h1>
*返回 File 生成的新的PDF文件
*/
public File print(String targetFileName)throws Exception{
File ret=new File(targetFileName);
FileOutputStream fos=new FileOutputStream(ret);
ByteArrayOutputStream bos=print();
bos.writeTo(fos);
bos.close();
fos.close();
return ret;
}
/**
*<h1>合并