程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 生成PDF全攻略,pdf全攻略

生成PDF全攻略,pdf全攻略

編輯:JAVA綜合教程

生成PDF全攻略,pdf全攻略


     經歷過多少踩坑,翻看過多少類似博客,下載過多少版本的Jar,才能摸索出正確的代碼書寫方式,才能實現項目經理需求分析書中的功能點。

     本文借一次 JavaEE 生成PDF的顛簸的實現過程,描述中小公司程序員的坎坷成長之路。

     俺上面只所以將成熟大公司排除在外的原因是,大公司一般都有成熟的產品線和技術積澱。

     至少會有完善的建構師團隊,有像掃地神僧那樣的牛人隱士......

     公司中初級程序員遇到問題,能找到以前實現過的類似功能的代碼作為參照,也能咨詢技術經理。

     小公司是沒有這種福分的,就像昨天早晨"生成PDF"需求到,工期一天,明日要給客戶看。

     第一反應是找度娘,關鍵字 "Java生成PDF",博客不是一般的多,下面簡述幾種實現方式和實現過程中遇到的問題。

     (目錄已列在上面,通過搜索引擎進來的小伙伴,看看上面列表中是否有能解決你問題的,有點到相應的小節,沒有就關閉看下一條搜索記錄吧....)

1.IText 生成復雜PDF

    度娘中占比例最大的Java 生成PDF實現類庫,也是許多技術博客中涉及到技術。

    開源中國中的介紹:http://www.oschina.net/p/itext,好嘞,既然都推薦那就采用這類庫看看。

    下載 Jar 也是琳琅滿目,讓你挑花眼,從 2.1--5.5 應有盡有,有些論壇下載東西還需要注冊o(︶︿︶)o 唉。

    這裡采用的是最新的版本 5.5,仔細閱讀下別人的技術博客或者是官方文檔,編碼起來確實不是很費勁。筆者將業務抽象實現的類如下:

import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
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 java.io.FileOutputStream;

public class createSimplePDF {
    private static Font FontChinese;
    public static void simplePDF() {
        try {
            BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            FontChinese = new Font(bfChinese, 12, Font.NORMAL);
            Document document = new Document();
            PdfWriter.getInstance(document, new FileOutputStream("F:\\Garbage\\Hello simplePDF.pdf"));
            document.open();

            PdfPTable table = new PdfPTable(4);
            table.addCell(getCell("姓名", 1, 1));
            table.addCell(getCell("", 1, 1));
            table.addCell(getCell("編號", 1, 1));
            table.addCell(getCell("", 1, 1));

            table.addCell(getCell("部門", 1, 1));
            table.addCell(getCell("", 1, 1));
            table.addCell(getCell("崗位名稱", 1, 1));
            table.addCell(getCell("", 1, 1));

            table.addCell(getCell("到職日期", 1, 1));
            table.addCell(getCell("", 1, 1));
            table.addCell(getCell("預定離職日期", 1, 1));
            table.addCell(getCell("", 1, 1));

            table.addCell(getCell("事由", 1, 3));
            table.addCell(getCell("", 3, 3));

            table.addCell(getCell("部門意見", 1, 3));
            table.addCell(getCell("", 3, 3));
            document.add(table);
            document.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static PdfPCell getCell(String cellValue, int colspan, int rowSpan) {
        PdfPCell cell = new PdfPCell();
        try {
            cell = new PdfPCell(new Phrase(cellValue, FontChinese));
            cell.setRowspan(rowSpan);
            cell.setColspan(colspan);
            cell.setHorizontalAlignment(Element.ALIGN_CENTER);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return cell;
    }
}

2.IText添加對中文的支持

   愉快的將代碼編寫完成,生成後中文不見了,注意是不見了,不是亂碼,拋出的錯誤如下:

   Font 'STSong-Light' with 'UniGB-UCS2-H' is not recognized

   再次詢問度娘,發現IText需要添加另外itext-asian.jar去支持中文,那就添加吧。

   因為自己IText使用的是最新的5.5版本,導致其他低版本的 itext-asian.jar 無法支持。

   最終在一篇博客中尋獲解決方法,嘗試後奏效,就是上述代碼中:

 BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
 FontChinese = new Font(bfChinese, 12, Font.NORMAL);

  筆者這裡將最新的IText.jar 和 配套的中文支持  itext-asian.jar 放入: http://pan.baidu.com/s/1bqs4km  提取密碼: 99eg

  為後面同學節省找 jar 的時間。實現的截圖如下:

  其實最終要實現的表格的樣子比這個要復雜的多,80%花費時間主要是在調整樣式,編譯輸出--->看樣式,到這裡其實需求已經能夠實現了。

  筆者也是用這種方式實現的,畢竟是給客戶演示的。

  這裡要感謝的是這位博主的博客,裡面有詳細的IText 設置段落,標題,表格,加密..........只要你能在生成PDF想到的,這裡面基本上都有。

  博客地址:http://rensanning.iteye.com/blog/1538689

3.iTextRenderer(Flying Saucer) HTML轉PDF

  Flying saucer 是開源項目的名稱,老外起名字我也是醉了,想起一出是一出,HTML 渲染 PDF起個"飛行器"。

  其中的核心類 iTextRenderer 支持將HTML生成PDF。

  iTextRenderer 依賴與iText單獨實現的渲染器,基本上能實現 CSS 2.1的整體性,並且完全符合 W3C 規范。

  如果采用這種方式,在後台調整樣式什麼的,就讓它見鬼去把。

  具體的流程如下圖:

  

     這才是高大上的解決方案有木有,模版引擎現在也是玲琅滿目(freemark,velocity.......),具體看你們項目吧。

     這樣就不用為繁瑣的樣式發愁了,定義模版前端查看,注入數據,生成PDF。

                ITextRenderer iTextRenderer = new ITextRenderer();
                iTextRenderer.getFontResolver().addFont("C:/Windows/Fonts/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                iTextRenderer.setDocument(new File(currWebcontentPath + reviewHtmlPath).toURI().toString());
                iTextRenderer.layout();
                String pdfName = getPdfName(testVO);
                OutputStream fileOutputStream = new FileOutputStream(currWebcontentPath + pdfPath + pdfName);
                iTextRenderer.createPDF(fileOutputStream);
                iTextRenderer.finishPDF();

    這裡面需要解決的問題還有生成的HTML存放的位置,然後就是跳轉到下載頁面了,如果你是JavaEE後端開發,這些問題應該都難不到你。

    使用的iTextRenderer的jar同樣也放到: http://pan.baidu.com/s/1kTOpM0R  提取密碼: y9y2

    具體參考的博客有:

    http://www.tuicool.com/articles/qAFNFja

    http://downpour.iteye.com/blog/509417

    http://my.oschina.net/u/603602/blog/268611?fromerr=bxBuHc6W

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved