公司的相关业务需要导出pdf,找遍了各大网站论坛,然后自己又总结融合了不少其他代码,吃过不少亏,特把全部源码扔上去供大家做个参考,鄙人研发两年还属于小菜阶段.代码不严谨的地方还望指正;
为了给pdf直接加上页眉页脚,直接重写了ITextRenderer
下面直接上源码吧:
相关源码和jar包可去http://download.csdn.net/download/patpeng/10202716下载
<%@ page import="java.util.*" pageEncoding="UTF-8" contentType="text/html; charset=UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
<%@ taglib uri="http://java.sun.com/taglibs/samples-uitls" prefix="utils"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/sql" prefix="sql" %>
<%@ taglib uri="http://www.springframework.org/tags" prefix="spring" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
%>
<c:set var="ctx" value="<%=basePath %>"/>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>pdf导出title>
<style type="text/css">
*{
font-size: 10px;
font-family:SimSun;/* 重要,支持中文 */
}
body{
background-color:#fff;
font-family: SimSun;
}
.tb-group-btn{border-color:#C9C9C9}
div.answerBox{
font-weight:700;
}
style>
<script src="${ctx}/js/jquery.min.js">script>
head>
<body style="width:auto;height:100%;">
<div id="donotExport" style="float:right;border:0;padding:0;width:100%">
div>
<div id="needPrint">
<div class="line" style="width:100%;margin-top:30px" align="center">
<strong style="font-size:20px;">导出pdfstrong>
div>
<h4 style="margin:10px 0;font-weight:600">导出pdfh4>
<div>
<table border="1" style="border:#7D7D7D;width:100%;text-align:center;border-collapse:collapse;color:#676767;font-size:16px;line-height:30px">
<tbody>
<tr style="">
<td style="size:18px">导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
tr>
<tr align="center">
<td style="size:18px">导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
<td>导出pdftd>
tr>
tbody>
table>
div>
<h4 style="margin:20px 0;font-weight:600">导出pdfh4>
div>
body>
html>
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.BaseFont;
public class ItextPdfUtil {
/**
* 通过url获取远程下载pdf
* @param url:jsp页面的url
* @param fileName:导出后PDF文件名
* @param request
* @param response
* @param flag :String[] 0:页眉;1页脚;2页脚;传null默认没有页眉页脚
*
* @version:v4.0
* @author:pengkz
* @date:2018年1月3日 下午4:58:25
*/
public static void html2Pdf(String url,String fileName,HttpServletRequest request,HttpServletResponse response,String[] flag){
OutputStream outputStream = null;
ByteArrayInputStream inputStream = null;
try {
inputStream = getPDFInputStreamByURL(url, request,flag);
outputStream = response.getOutputStream();
response.setHeader("Content-Disposition", "attachment;filename="+new String(fileName.getBytes("gbk"), "iso8859-1"));
int b;
while((b=inputStream.read())!= -1)
{
outputStream.write(b);
}
outputStream.flush();
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (outputStream!=null) {
outputStream.close();
outputStream=null;
}
if (inputStream!=null) {
inputStream.close();
inputStream=null;
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 通过url获取远程jsp页面源码
* @param url
* @return
* @throws Exception
*
* @version:v2.0
* @author:pengkz
* @date:2017年7月21日 下午2:58:31
*/
public static String getHTMLSourceByUrl(String url) throws Exception {
URL urls=new URL(url);
HttpURLConnection conn = (HttpURLConnection) urls.openConnection();
conn.setRequestProperty("Content-type", "text/html");
conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8");
conn.setRequestProperty("Charset", "utf-8");
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream(); // 通过输入流获取html二进制数据
byte[] data = readInputStream(inStream); // 把二进制数据转化为byte字节数据
String htmlSource = new String(data,"utf-8");//解决乱码问题
conn.disconnect();
if (inStream!=null) {
inStream.close();
inStream=null;
}
return htmlSource;
}
/**
* 从输入流中获取字节数组
* @param inputStream
* @return
* @throws IOException
*
* @version:v2.0
* @author:pengkz
* @date:2017年7月21日 下午2:58:19
*/
private static byte[] readInputStream(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024];
int len = 0;
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = inputStream.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.close();
return bos.toByteArray();
}
/**
* 通过URL获取到pdf的inputstream流
* @param url
* @param request
* @param flag String[],最少传三个参数 0:顶部标识/1:左下角标识/2:右下角标识
* @return
* @throws DocumentException
* @throws IOException
* @throws Exception
*
* @version:v2.0
* @author:pengkz
* @date:2017年7月28日 下午3:46:21
*/
public static ByteArrayInputStream getPDFInputStreamByURL(String url, HttpServletRequest request,String[] flag)
throws DocumentException, IOException, Exception {
ByteArrayOutputStream os = null;
ITextRendererO renderer = new ITextRendererO();
String[] array=new String[3];
if (flag.length>=3) {
array=flag;
}else {
for (int i = 0; i < flag.length; i++) {
array[i]=flag[i];
}
}
ITextFontResolver fontResolver = renderer.getFontResolver();
String apath=request.getSession().getServletContext().getRealPath("/");
//读取模板字体
String templateFilePath = apath.replace("\\", "/").replaceAll(request.getContextPath(), "")+"simsun.ttc";//支持中文字体的模板
fontResolver.addFont(templateFilePath, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
String htmlss = getHTMLSourceByUrl(url);
renderer.setDocumentFromString(htmlss);
renderer.layout();
os = new ByteArrayOutputStream();
renderer.createPDF(os,templateFilePath,array);
ByteArrayInputStream inputStream = new ByteArrayInputStream(os.toByteArray());
renderer=null;
os.close();
os=null;
return inputStream;
}
}
/*
* {{{ header & license
* Copyright (c) 2006 Wisconsin Court System
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
* }}}
*/
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Shape;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.List;
import java.util.regex.Pattern;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xhtmlrenderer.context.StyleReference;
import org.xhtmlrenderer.css.style.CalculatedStyle;
import org.xhtmlrenderer.extend.NamespaceHandler;
import org.xhtmlrenderer.extend.UserInterface;
import org.xhtmlrenderer.layout.BoxBuilder;
import org.xhtmlrenderer.layout.Layer;
import org.xhtmlrenderer.layout.LayoutContext;
import org.xhtmlrenderer.layout.SharedContext;
import org.xhtmlrenderer.pdf.ITextFontContext;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextOutputDevice;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xhtmlrenderer.pdf.ITextReplacedElementFactory;
import org.xhtmlrenderer.pdf.ITextTextRenderer;
import org.xhtmlrenderer.pdf.ITextUserAgent;
import org.xhtmlrenderer.pdf.PDFCreationListener;
import org.xhtmlrenderer.pdf.PDFEncryption;
import org.xhtmlrenderer.render.BlockBox;
import org.xhtmlrenderer.render.PageBox;
import org.xhtmlrenderer.render.RenderingContext;
import org.xhtmlrenderer.render.ViewportBox;
import org.xhtmlrenderer.resource.XMLResource;
import org.xhtmlrenderer.simple.extend.XhtmlNamespaceHandler;
import org.xhtmlrenderer.util.Configuration;
import org.xml.sax.InputSource;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Font;
import com.lowagie.text.HeaderFooter;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfWriter;
public class ITextRendererO extends ITextRenderer {
// These two defaults combine to produce an effective resolution of 96 px to
// the inch
private static final float DEFAULT_DOTS_PER_POINT = 20f * 4f / 3f;
private static final int DEFAULT_DOTS_PER_PIXEL = 20;
private final SharedContext _sharedContext;
private final ITextOutputDevice _outputDevice;
private Document _doc;
private BlockBox _root;
private final float _dotsPerPoint;
private com.lowagie.text.Document _pdfDoc;
private PdfWriter _writer;
private PDFEncryption _pdfEncryption;
// note: not hard-coding a default version in the _pdfVersion field as this
// may change between iText releases
// check for null before calling writer.setPdfVersion()
// use one of the values in PDFWriter.VERSION...
private Character _pdfVersion;
private final char[] validPdfVersions = new char[] { PdfWriter.VERSION_1_2, PdfWriter.VERSION_1_3, PdfWriter.VERSION_1_4,
PdfWriter.VERSION_1_5, PdfWriter.VERSION_1_6, PdfWriter.VERSION_1_7 };
private Integer _pdfXConformance;
private PDFCreationListener _listener;
private boolean _timeouted;
public ITextRendererO() {
this(DEFAULT_DOTS_PER_POINT, DEFAULT_DOTS_PER_PIXEL);
}
public ITextRendererO(float dotsPerPoint, int dotsPerPixel) {
this(dotsPerPoint, dotsPerPixel, new ITextOutputDevice(dotsPerPoint));
}
public ITextRendererO(float dotsPerPoint, int dotsPerPixel, ITextOutputDevice outputDevice) {
this(dotsPerPoint, dotsPerPixel, outputDevice, new ITextUserAgent(outputDevice));
}
public ITextRendererO(float dotsPerPoint, int dotsPerPixel, ITextOutputDevice outputDevice, ITextUserAgent userAgent) {
_dotsPerPoint = dotsPerPoint;
_outputDevice = outputDevice;
_sharedContext = new SharedContext();
_sharedContext.setUserAgentCallback(userAgent);
_sharedContext.setCss(new StyleReference(userAgent));
userAgent.setSharedContext(_sharedContext);
_outputDevice.setSharedContext(_sharedContext);
ITextFontResolver fontResolver = new ITextFontResolver(_sharedContext);
_sharedContext.setFontResolver(fontResolver);
ITextReplacedElementFactory replacedElementFactory = new ITextReplacedElementFactory(_outputDevice);
_sharedContext.setReplacedElementFactory(replacedElementFactory);
_sharedContext.setTextRenderer(new ITextTextRenderer());
_sharedContext.setDPI(72 * _dotsPerPoint);
_sharedContext.setDotsPerPixel(dotsPerPixel);
_sharedContext.setPrint(true);
_sharedContext.setInteractive(false);
_timeouted= false;
}
public Document getDocument() {
return _doc;
}
public ITextFontResolver getFontResolver() {
return (ITextFontResolver) _sharedContext.getFontResolver();
}
private Document loadDocument(final String uri) {
return _sharedContext.getUac().getXMLResource(uri).getDocument();
}
public void setDocument(String uri) {
setDocument(loadDocument(uri), uri);
}
public void setDocument(Document doc, String url) {
setDocument(doc, url, new XhtmlNamespaceHandler());
}
public void setDocument(File file) throws IOException {
File parent = file.getAbsoluteFile().getParentFile();
setDocument(loadDocument(file.toURI().toURL().toExternalForm()), (parent == null ? "" : parent.toURI().toURL().toExternalForm()));
}
public void setDocumentFromString(String content) {
setDocumentFromString(content, null);
}
public void setDocumentFromString(String content, String baseUrl) {
InputSource is = new InputSource(new BufferedReader(new StringReader(content)));
Document dom = XMLResource.load(is).getDocument();
setDocument(dom, baseUrl);
}
public void setDocument(Document doc, String url, NamespaceHandler nsh) {
_doc = doc;
getFontResolver().flushFontFaceFonts();
_sharedContext.reset();
if (Configuration.isTrue("xr.cache.stylesheets", true)) {
_sharedContext.getCss().flushStyleSheets();
} else {
_sharedContext.getCss().flushAllStyleSheets();
}
_sharedContext.setBaseURL(url);
_sharedContext.setNamespaceHandler(nsh);
_sharedContext.getCss().setDocumentContext(_sharedContext, _sharedContext.getNamespaceHandler(), doc, new NullUserInterface());
getFontResolver().importFontFaces(_sharedContext.getCss().getFontFaceRules());
}
public PDFEncryption getPDFEncryption() {
return _pdfEncryption;
}
public void setPDFEncryption(PDFEncryption pdfEncryption) {
_pdfEncryption = pdfEncryption;
}
public void setPDFVersion(char _v) {
for (int i = 0; i < validPdfVersions.length; i++) {
if (_v == validPdfVersions[i]) {
_pdfVersion = new Character(_v);
return;
}
}
throw new IllegalArgumentException("Invalid PDF version character; use "
+ "valid constants from PdfWriter (e.g. PdfWriter.VERSION_1_2)");
}
public char getPDFVersion() {
return _pdfVersion == null ? '0' : _pdfVersion.charValue();
}
public void setPDFXConformance(int pdfXConformance){
_pdfXConformance = new Integer(pdfXConformance);
}
public int getPDFXConformance(){
return _pdfXConformance == null ? '0' : _pdfXConformance.intValue();
}
public void layout() {
LayoutContext c = newLayoutContext();
BlockBox root = BoxBuilder.createRootBox(c, _doc);
root.setContainingBlock(new ViewportBox(getInitialExtents(c)));
root.layout(c);
Dimension dim = root.getLayer().getPaintingDimension(c);
root.getLayer().trimEmptyPages(c, dim.height);
root.getLayer().layoutPages(c);
_root = root;
}
private Rectangle getInitialExtents(LayoutContext c) {
PageBox first = Layer.createPageBox(c, "first");
return new Rectangle(0, 0, first.getContentWidth(c), first.getContentHeight(c));
}
private RenderingContext newRenderingContext() {
RenderingContext result = _sharedContext.newRenderingContextInstance();
result.setFontContext(new ITextFontContext());
result.setOutputDevice(_outputDevice);
_sharedContext.getTextRenderer().setup(result.getFontContext());
result.setRootLayer(_root.getLayer());
return result;
}
private LayoutContext newLayoutContext() {
LayoutContext result = _sharedContext.newLayoutContextInstance();
result.setFontContext(new ITextFontContext());
_sharedContext.getTextRenderer().setup(result.getFontContext());
return result;
}
public void createPDF(OutputStream os,String templateFilePath,String ...flag) throws DocumentException {
createPDF(os, true, 0,templateFilePath,flag);
}
public void writeNextDocument() throws DocumentException {
writeNextDocument(0);
}
public void writeNextDocument(int initialPageNo) throws DocumentException {
List pages = _root.getLayer().getPages();
RenderingContext c = newRenderingContext();
c.setInitialPageNo(initialPageNo);
PageBox firstPage = (PageBox) pages.get(0);
com.lowagie.text.Rectangle firstPageSize = new com.lowagie.text.Rectangle(0, 0, firstPage.getWidth(c) / _dotsPerPoint,
firstPage.getHeight(c) / _dotsPerPoint);
_outputDevice.setStartPageNo(_writer.getPageNumber());
_pdfDoc.setPageSize(firstPageSize);
_pdfDoc.newPage();
writePDF(pages, c, firstPageSize, _pdfDoc, _writer);
}
public void finishPDF() {
if (_pdfDoc != null) {
fireOnClose();
_pdfDoc.close();
}
}
public void createPDF(OutputStream os, boolean finish) throws DocumentException {
createPDF(os, finish, 0);
}
/**
* NOTE: Caller is responsible for cleaning up the OutputStream if
* something goes wrong.
* flag Object[],最少传三个参数 0:顶部标识/1:左下角标识/2:右下角标识
*/
public void createPDF(OutputStream os, boolean finish, int initialPageNo,String templateFilePath,String ...flag) throws DocumentException {
List pages = _root.getLayer().getPages();
RenderingContext c = newRenderingContext();
c.setInitialPageNo(initialPageNo);
PageBox firstPage = (PageBox) pages.get(0);
com.lowagie.text.Rectangle firstPageSize = new com.lowagie.text.Rectangle(0, 0, firstPage.getWidth(c) / _dotsPerPoint,
firstPage.getHeight(c) / _dotsPerPoint);
com.lowagie.text.Document doc = new com.lowagie.text.Document(firstPageSize, 0,0, 20, 10);
PdfWriter writer = PdfWriter.getInstance(doc, os);
if (flag!=null&&flag.length>0) {
//页眉页脚设置开始
BaseFont fontChinese=null;
try {
fontChinese = BaseFont.createFont(templateFilePath+",1", BaseFont.IDENTITY_H, BaseFont.EMBEDDED,false);//配置中文
} catch (IOException e) {
e.printStackTrace();
}
Font chinese = new Font(fontChinese, 10, Font.NORMAL);
/**
* HeaderFooter的第2个参数为非 false时代表打印页码
* 页眉页脚中也可以加入图片,并非只能是文字
*/
if (StringUtils.isNotBlank(flag[0])) {
HeaderFooter header=new HeaderFooter(new Phrase(flag[0]+" ",chinese),false);
//设置是否有边框等
// header.setBorder(Rectangle.NO_BORDER);
header.setAlignment(2);
header.setBorder(Font.NORMAL);
doc.setHeader(header);
}
if (StringUtils.isNotBlank(flag[1])&&StringUtils.isNotBlank(flag[2])) {//如果左右页脚都不空
HeaderFooterfooter=new HeaderFooter(new Phrase(flag[1]+" | "+flag[2]+" ",chinese),false);
/**
* 0是靠左
* 1是居中
* 2是居右
*/
footer.setBorder(Font.NORMAL);
footer.setAlignment(1);
// footer.setBorderColor(Color.red);
doc.setFooter(footer);
}
//页眉页脚设置结束
}
if (_pdfVersion != null) {
writer.setPdfVersion(_pdfVersion.charValue());
}
if (_pdfXConformance != null) {
writer.setPDFXConformance(_pdfXConformance.intValue());
}
if (_pdfEncryption != null) {
writer.setEncryption(_pdfEncryption.getUserPassword(), _pdfEncryption.getOwnerPassword(),
_pdfEncryption.getAllowedPrivileges(), _pdfEncryption.getEncryptionType());
}
_pdfDoc = doc;
_writer = writer;
firePreOpen();
doc.open();
writePDF(pages, c, firstPageSize, doc, writer);
if (finish) {
fireOnClose();
doc.close();
}
}
private void firePreOpen() {
if (_listener != null) {
_listener.preOpen(this);
}
}
private void firePreWrite(int pageCount) {
if (_listener != null) {
_listener.preWrite(this, pageCount);
}
}
private void fireOnClose() {
if (_listener != null) {
_listener.onClose(this);
}
}
private void writePDF(List pages, RenderingContext c, com.lowagie.text.Rectangle firstPageSize, com.lowagie.text.Document doc,
PdfWriter writer) throws DocumentException {
_outputDevice.setRoot(_root);
_outputDevice.start(_doc);
_outputDevice.setWriter(writer);
_outputDevice.initializePage(writer.getDirectContent(), firstPageSize.getHeight());
_root.getLayer().assignPagePaintingPositions(c, Layer.PAGED_MODE_PRINT);
int pageCount = _root.getLayer().getPages().size();
c.setPageCount(pageCount);
firePreWrite(pageCount); // opportunity to adjust meta data
setDidValues(doc); // set PDF header fields from meta data
for (int i = 0; i < pageCount; i++) {
if (isTimeouted() || Thread.currentThread().isInterrupted())
throw new RuntimeException("Timeout occured");
PageBox currentPage = (PageBox) pages.get(i);
c.setPage(i, currentPage);
paintPage(c, writer, currentPage);
_outputDevice.finishPage();
if (i != pageCount - 1) {
PageBox nextPage = (PageBox) pages.get(i + 1);
com.lowagie.text.Rectangle nextPageSize = new com.lowagie.text.Rectangle(0, 0, nextPage.getWidth(c) / _dotsPerPoint,
nextPage.getHeight(c) / _dotsPerPoint);
doc.setPageSize(nextPageSize);
doc.newPage();
_outputDevice.initializePage(writer.getDirectContent(), nextPageSize.getHeight());
}
}
_outputDevice.finish(c, _root);
}
// Sets the document information dictionary values from html metadata
private void setDidValues(com.lowagie.text.Document doc) {
String v = _outputDevice.getMetadataByName("title");
if (v != null) {
doc.addTitle(v);
}
v = _outputDevice.getMetadataByName("author");
if (v != null) {
doc.addAuthor(v);
}
v = _outputDevice.getMetadataByName("subject");
if (v != null) {
doc.addSubject(v);
}
v = _outputDevice.getMetadataByName("keywords");
if (v != null) {
doc.addKeywords(v);
}
}
private void paintPage(RenderingContext c, PdfWriter writer, PageBox page) {
provideMetadataToPage(writer, page);
page.paintBackground(c, 0, Layer.PAGED_MODE_PRINT);
page.paintMarginAreas(c, 0, Layer.PAGED_MODE_PRINT);
page.paintBorder(c, 0, Layer.PAGED_MODE_PRINT);
Shape working = _outputDevice.getClip();
Rectangle content = page.getPrintClippingBounds(c);
_outputDevice.clip(content);
int top = -page.getPaintingTop() + page.getMarginBorderPadding(c, CalculatedStyle.TOP);
int left = page.getMarginBorderPadding(c, CalculatedStyle.LEFT);
_outputDevice.translate(left, top);
_root.getLayer().paint(c);
_outputDevice.translate(-left, -top);
_outputDevice.setClip(working);
}
private void provideMetadataToPage(PdfWriter writer, PageBox page) {
byte[] metadata = null;
if (page.getMetadata() != null) {
try {
String metadataBody = stringfyMetadata(page.getMetadata());
if (metadataBody != null) {
metadata = createXPacket(stringfyMetadata(page.getMetadata())).getBytes("UTF-8");
}
} catch (UnsupportedEncodingException e) {
// Can't happen
throw new RuntimeException(e);
}
}
if (metadata != null) {
writer.setPageXmpMetadata(metadata);
}
}
private String stringfyMetadata(Element element) {
Element target = getFirstChildElement(element);
if (target == null) {
return null;
}
try {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter output = new StringWriter();
transformer.transform(new DOMSource(target), new StreamResult(output));
return output.toString();
} catch (TransformerConfigurationException e) {
// Things must be in pretty bad shape to get here so
// rethrow as runtime exception
throw new RuntimeException(e);
} catch (TransformerException e) {
throw new RuntimeException(e);
}
}
private static Element getFirstChildElement(Element element) {
Node n = element.getFirstChild();
while (n != null) {
if (n.getNodeType() == Node.ELEMENT_NODE) {
return (Element) n;
}
n = n.getNextSibling();
}
return null;
}
private String createXPacket(String metadata) {
StringBuffer result = new StringBuffer(metadata.length() + 50);
result.append("\n");
result.append(metadata);
result.append("\n");
return result.toString();
}
public ITextOutputDevice getOutputDevice() {
return _outputDevice;
}
public SharedContext getSharedContext() {
return _sharedContext;
}
public void exportText(Writer writer) throws IOException {
RenderingContext c = newRenderingContext();
c.setPageCount(_root.getLayer().getPages().size());
_root.exportText(c, writer);
}
public BlockBox getRootBox() {
return _root;
}
public float getDotsPerPoint() {
return _dotsPerPoint;
}
public List findPagePositionsByID(Pattern pattern) {
return _outputDevice.findPagePositionsByID(newLayoutContext(), pattern);
}
private static final class NullUserInterface implements UserInterface {
public boolean isHover(Element e) {
return false;
}
public boolean isActive(Element e) {
return false;
}
public boolean isFocus(Element e) {
return false;
}
}
public PDFCreationListener getListener() {
return _listener;
}
public void setListener(PDFCreationListener listener) {
_listener = listener;
}
public PdfWriter getWriter() {
return _writer;
}
public void setTimeouted(boolean timeouted) {
_timeouted= timeouted;
}
public boolean isTimeouted() {
return _timeouted;
}
}