1. 程式人生 > >iText把jsp/html轉pdf,並支援新增頁首頁尾

iText把jsp/html轉pdf,並支援新增頁首頁尾

公司的相關業務需要匯出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 %>"/>


<!-- 
1.確保所有標籤全部閉合,如果沒有閉合,呵呵噠
2.確保該頁面不執行js去獲取資料,否則你會失望
 -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<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;">呵呵噠</strong>
</div>
<h4 style="margin:10px 0;font-weight:600">呵呵噠</h4>
<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">呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
</tr>
<tr align="center">
<td style="size:18px">呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
<td>呵呵噠</td>
</tr>
</tbody>
</table>
</div>
<h4 style="margin:20px 0;font-weight:600">呵呵噠</h4>
</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);
    }


    /**
     * <B>NOTE:</B> 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("<?xpacket begin='\uFEFF' id='W5M0MpCehiHzreSzNTczkc9d'?>\n");
        result.append(metadata);
        result.append("\n<?xpacket end='r'?>");


        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;
    }
}

相關推薦

iTextjsp/htmlpdf,支援新增

公司的相關業務需要匯出pdf,找遍了各大網站論壇,然後自己又總結融合了不少其他程式碼,吃過不少虧,特把全部原始碼扔上去供大家做個參考,鄙人研發兩年還屬於小菜階段.程式碼不嚴謹的地方還望指正; 為了給pdf直接加上頁首頁尾,直接重寫了ITextRenderer 下面直接上原始

iText —— JAVA將htmlpdf

1、index.html檔案內容如下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.

【JAVA】使用 iText XMLWorker實現HTMLPDF

使用 iText XML Worker實現HTML轉PDF package com.yfli.iText; import java.io.FileInputStream; import java.i

java實現htmlpdf支援中文,css以及中文換行

專案需使用到html轉pdf功能,在網上搜了很多,綜合了不少大神的方法,現在這裡做一個標記,以免自己以後忘記了。 java程式碼 import java.io.File; import java.io.FileOutputStream; import j

HTMLPDF上傳FTP(1)

準備工作: 1.安裝外掛wkhtmltopdf,URL:https://wkhtmltopdf.org/downloads.html 2.導包 jsch-0.1.54.jar URL:http://www.jcraft.com/jsch/ 程式碼

JS實現HTMLpdf支援高清放大及分)詳解

在這裡我主要講述實現思路及方法,原理大家可以自行百度,寫此文章主要是網上的很多實現方案都不能很好的支援高清放大及分頁。首先:引入三個js外掛,請自行上網百度下載,注意html2canvas.js版本太高會出現Promise未定義,本人猜測ES6高版本中可能用到ES6語法,請注

Django 實現HTMLPDF 用通用檢視編寫PDF 並且讓PDF支援中文

Django 實現HTML轉PDF 用通用檢視編寫PDF 並且讓PDF支援中文 如何使用django-easy-pdf django-easy-pdf的依賴 安裝django-easy-pdf 使用過程中遇到的問題總結

wkhtmltopdf htmlPDF 支援java 直接呼叫命令進行轉換

wkhtmltopdf [OPTIONS]... <input file> [More input files] <output file> 常規選項  --allow <path>  允許載入從指定的資料夾中的檔案或檔案(可重複)--b

Itext 匯出PDF(中文解決,HTMLPDF

iText是著名的開放原始碼的站點sourceforge一個專案,是用於生成PDF文件的一個java類庫。通過iText不僅可以生成PDF或rtf的文件,而且可以將XML、Html檔案轉化為PDF檔案。 iText的安裝非常方便,下載iText.jar檔案後,只需要在系統的

HTMLPDF工具(wkhtmltopdf)介紹,支援widows和linux

最近專案中客戶提了一個奇葩的需求;批量把html轉為pdf檔案用於存檔。聽到這個需求不知所錯,最開始研究iText使用java開發,各種中文亂碼,中文不顯示問題。後來在網上搜索到wkhtmltopdf工具,以下是完整的說明以及程式碼。 首先下載檔案:html轉為pdf檔案(wkhtm

iText htmlpdf

所需jar包 import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import org.xhtmlre

itext轉換HTMLpdf支援中文換行

最近有個需求,OA系統流程走完後,要求將流程匯出為pdf供人下載,在網上各種查資料搗鼓了半天,終於算是搞出來了,基本邏輯就是配置好需要顯示的佈局,然後根據佈局生成HTML頁面,再匯出為pdf。 (20180903增加:此方法生成pdf樣式存在差異,我後續使用了別的方式生成p

史上最強php生成pdf文件,htmlpdf文件方法

是不是 下載地址 註意 pdflib min views 開發者 lan 輸入 之前有個客戶需要把一些html頁面生成pdf文件,然後我就找一些用php把html頁面圍成pdf文件的類。方法是可謂是找了很多很多,什麽html2pdf,pdflib,FPDF這些都試過了,但是

實現wordpdfHTMLpdf(探索篇)

ner ase node eth ack line prope fin -o 筆者找依賴的jar包,找的好辛苦。 ITextRenderer、ITextFontResolver這兩個類依賴的jar包到底是哪個,還有怎麽下載?苦苦糾結了3個小時。終於找到你了!記錄個網址:ht

指定htmlpdf文檔

.com data com change creat one his cat div 1.資源 <script type="text/javascript" src="./js/canvg2.js"></script> <script

freemarker生成htmlhtmlpdfpdf根據關鍵字定位、pdf簽名

freemarker生成html、html轉pdf、pdf根據關鍵字定位、pdf簽名圖片 PdfUtil 類 (全部功能程式碼) Content 類 (自己建立相關檔案) 相關依賴(基於spring-boot測試) PdfUtil 類

PDF技術(四)-Java實現HtmlPDF檔案

html轉換為pdf的關鍵技術是如何處理網頁中複雜的css樣式、以及中文亂碼處理。 各實現對比表 於Windows平臺進行測試:   基於IText 基於FlyingSaucer 基於WKHtmlToPdf

HTML PDF 之 wkhtmltopdf 工具精講

術語定義 文件物件 “文件物件”是指PDF文件中的文件物件,共有三種類型的“文件物件”,他們分別是“頁面物件”,“封面物件”和“目錄物件”。 頁面物件 “頁面物件”是指以頁面的形式在PDF文件中呈現的物件,這個是相對於“封面物件”和“目錄物件”來講的。此類物件會成為P

Java檔案上傳資料庫(儲存本地)、wordpdf進行頁面預覽

對於頁面預覽用到了OpenOffice附件: 官方的下載地址:Apache OpenOffice 選擇windows版本安裝完成後,在cmd中執行下面兩個命令,檢視工作管理員中是否有soffice.bin的程序。(用到OpenOffice,必須保證工作管理員中有

【優化版】Java檔案上傳資料庫(儲存本地)、wordpdf進行頁面預覽

上一篇檔案上傳【點選跳轉】,是將路徑等檔案資訊存進log_file臨時表,內容二進位制存入資料庫Test表,這種邏輯是在呼叫資料庫表Test內容展示時,判斷檔案為word(轉換成pdf)還是pdf(直接展示)。 上一篇連結:連結地址。 下面進一步優化: 具體邏輯