pdf.js pdfdom.js使用(轉)


開篇語:

      最近工作需要做一個借款合同,公司以前的合同都是通過app端下載,然后通過本地打開pdf文件,而喜歡創新的我,心想着為什么不能在線H5預覽,正是這個想法,說干就干,實踐過程總是艱難的,折騰了3,4天的時間,熬了兩個凌晨3,4點,其中的艱辛、以及各中的曲折、壓力只有自己能體會,項目上線后心里想着我要寫一篇博文,一是總結一下經驗,其次就是和大家分享自己這一路走來的的心得體會,歡迎吐槽!,廢話不多說,來點干貨!

PDF在線預覽實現:

    8個實現在線瀏覽PDF文件的實用插件,筆者選擇pdf.js,下面簡單介紹8個插件:

PDFObject

 8個實現在線瀏覽PDF文件的實用jQuery插件

PDFobject可以幫助你在頁面直接嵌入pdf文件,有時候有些項目需要動態地嵌入PDF文件。PDFObject為此而設計的,他能夠快速和容易的嵌入PDF文件,PDFObject使用JavaScript來產生相同的符合標准的 標記,然后插入 到您的HTML元素的選擇。您可以填滿整個瀏覽器窗口,或將PDF格式轉換成一個或其他塊級元素。

 

pdf.js

 8個實現在線瀏覽PDF文件的實用jQuery插件

和 Google Chrome 使用的源自 Foxit 的閉源 PDF 瀏覽插件不同,PDF.js 是基於開放的 HTML5 及 JavaScript 技術實現的開源產品

pdf.js 是一個主要用於HTML5 平台上在線閱讀PDF文檔的小插件,基於JavaScript技術編寫而成,無需任何本地技術支持。

pdf.js是由Mozilla Labs發布的。他們的目標是創建一個通用的,基於標准的網絡平台,能夠解析和渲染PDF文件,並最終發布一個PDF閱讀器擴展,毫無疑問 pdf.js 將被整合入 Gecko 成為 Firefox 的內嵌 PDF 閱讀器,但是具體整合時間表尚未確定

jsPDF

 8個實現在線瀏覽PDF文件的實用jQuery插件

jsPDF 是一個使用Javascript語言生成PDF的開源庫。你可以在Firefox插件,服務端腳本或是瀏覽器腳本中使用它。客戶端Safari 和 iPhone Safari 支持得最好,其次是Opera和Windows下的Firefox 3等。IE暫不支持。。

jQuery Media Plugin

 8個實現在線瀏覽PDF文件的實用jQuery插件

jQuery Media Plugin是一款基於jQuery的網頁媒體播放器插件,它支持大部分的網絡多媒體播放器和多媒體格式,比如:Flash, Windows Media Player, Real Player, Quicktime, MP3,Silverlight, PDF。它根據當前的腳本配置,自動將a標簽替換成div,並生成object, embed甚至是iframe代碼,至於生成object還是embed,jQuery Media會根據當前平台自動判別,因此兼容性方面非常出色下面這段代碼是jQuery Media生成后的。

 

Google Docs PDF viewer

 8個實現在線瀏覽PDF文件的實用jQuery插件

ZOHO Viewer

 8個實現在線瀏覽PDF文件的實用jQuery插件

Anychart:使用JavaScript導出PDF

 8個實現在線瀏覽PDF文件的實用jQuery插件

下圖可以導出為PNG或JPG格式的靜態圖像或嵌入式靜態圖像,圖表或一個完全互動的功能圖

 

jQuery Document Viewer

 8個實現在線瀏覽PDF文件的實用jQuery插件

Document Viewer是一個jQuery插件,可以讓你在網頁中直接查看多種文件格式。文檔瀏覽器支持的文件格式:PDF文件,文本文件,代碼,圖像,音頻,視頻等。

PDF.js實踐篇

  第一步 pdf.js源碼下載https://github.com/mozilla/pdf.js

        源碼頁有詳細編譯步奏,最后編譯出來,將generic文件copy至tomcat webapps目錄下,瀏覽器輸入http://localhost:8080/generic/web/viewer.html,H5預覽效果如下,圖片壓縮了,實際預覽效果好很多

   (我這里覆蓋了webapps\generic\web\compressed.tracemonkey-pldi-09.pdf文件,它自帶的是英文文檔): 

        

 

  第二步 我集成到項目以插件的形式目錄結構如下:

       

 

      第三步:編寫H5文件,這里是將pdf.js viever.html 頁面通過Ifram嵌入進來,並通過指定file參數動態傳參,實現動態pdf文件預覽 

  loanPdfContract.jsp:

   <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
<meta name="apple-mobile-web-app-capable" content="yes"/>
<meta name="apple-mobile-web-app-status-bar-style" content="black"/>
<meta name="format-detection" content="telephone=no,email=no,address=no"/>
<title>借款合同</title>
</head>
<body>
<iframe src="<c:url value="/plugin/pdfjs/generic/web/viewer.html"/>?file=<c:url value="/app/credit/loanApplication/contracts/${fileId}"/>"
width="100%" height="800">
</iframe>
</body>
</html>
第四步:編寫Controller方法,
/**
* 16.借款申請[信息確認]《合同及相關協議》-借款合同 H5接口 提供給app端調用
*
* @param userId
* @return
* @since 3.4
*/
@RequestMapping(value ="/app/credit/loanApplication/contracts/loanContract.security")
public Object loanContract(String userId,String borrowCode,String productTypeCode, Model model) {
if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(borrowCode)) {
return "app/credit/canaLoanApplication/404Error";
}
Map<String,String> returnMap = canaApplyLoanService.investmentContractTemplate(userId,borrowCode,productTypeCode);
if( BizCodeType.IS_NO.getCode().equals(returnMap.get("flag"))){
return "app/credit/canaLoanApplication/404Error";
}
model.addAttribute("fileId",returnMap.get("fileId")+".pdf");
return "app/credit/canaLoanApplication/loanPdfContract";
}

  
第五步:編寫Controller方法,注意這個 http head響應頭信息設置是HttpStatus.OK,和文件下載HttpStatus.CREATE頭信息有差異。

 /**

 * 查看PDF文件
* @param fileId
* @return
* @throws IOException
*/
@RequestMapping(value = "/app/credit/loanApplication/contracts/{fileId}.pdf", method = RequestMethod.GET)
public ResponseEntity<byte[]> loadContract(@PathVariable String fileId) throws IOException {
byte[] bytes=canaApplyLoanService.downContract(fileId);
final HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.valueOf("application/pdf"));
headers.setContentLength(bytes.length);
headers.add(HttpHeaders.ACCEPT_RANGES,"bytes");
return new ResponseEntity<byte[]>(bytes, headers, HttpStatus.OK);
}

 

  結束語 看着這里,PDF文件在線動態預覽基本完成,趕快體驗吧!

  

進階篇:Java實現PDF文件轉圖片、多個圖片合成PDF文件.

   前言:

    因為筆者這里的PDF文件帶有交互式表單域,導致PDF文件無法預覽,因為是合同PDF文件,敲章帶有簽名信息導致PDF預覽失敗,當時非常迷茫,沒有方向,后來和同城金服一架構師朋友聊天中,他給了我提示,“說是簽名的問題,需要把PDF轉成圖片”,對於筆者來說,有了思路剩下的就是實踐的事情。

          因為PDF有多頁所以會轉出多張圖片,至於為什么要轉成圖片,僅僅是為了將代簽名的交互式表單域給干掉、因為筆者以前做過多張圖片合成一張大圖,所以當時就想,這個多張圖片合成一張PDF文件應該不是問題,對於以前較少玩PDF文件的我來說,這個想法已經非常大膽了,如果讀者的你也對PDF文件了解不深的話,那么本文將非常適合你,帶你實戰PDF!

         我在啰嗦一句,因為這個PDF文件簽名導致App端無法查看,因為是第三方合同公司,所以我們需要他們的簽名SDK文件才能預覽,

  第一篇:帶你裝B,帶你飛!

      說了這么多,不來點干貨恐怕你們都看不下去了,主流的Pdf與圖片互轉

 

1.PDFRenderer: 確實效率最高,但是缺少字體支持對大多數中文pdf處理不了,這個筆者最開始使用了一下,但是報錯后來放棄了。

2.jpedal:這個是商業版本的,它官網的jar下載較慢,最開始本來打算用,好不容易csdn down下一個jar包,一運行提示jar包過期了。

3.pdfbox:筆者最終采用pdfbox,效果還不錯。之前網上說它對中文支持不好,但是筆者在pdfbox_2.0.2.jar使用過程中都沒遇見亂碼.

   

  第二篇:pdfbox使用

   maven配置:

<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.2</version>
</dependency>


   java代碼:

  

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.graphics.image.JPEGFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class PdfBoxUtil {

public static void main(String[] args) {
//pdfToImg("D:\\test\\22222.pdf","D:\\test\\22222.PNG");
pdfToImgToPdf("D:\\test\\22222.pdf","D:\\test\\3333.pdf");
}

/**
* pdf轉圖片
* @param pdfPath
* @param pngPath
*/
public static void pdfToImg(String pdfPath,String pngPath){
//將pdf裝圖片 並且自定義圖片得格式大小
File file = new File(pdfPath);
try {
PDDocument doc = PDDocument.load(file);
PDFRenderer renderer = new PDFRenderer(doc);
int pageCount = doc.getNumberOfPages();
for (int i = 0; i < pageCount; i++) {
BufferedImage image = renderer.renderImageWithDPI(i, 240);
BufferedImage srcImage = resize(image, image.getWidth(), image.getHeight());
ImageIO.write(srcImage, "PNG", new File(pngPath.replace(".",i+".")));
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* pdf轉圖片然后合成pdf
* @param pdfPath
* @param pdfOutPath
*/
public static void pdfToImgToPdf(String pdfPath,String pdfOutPath){
//將pdf裝圖片 並且自定義圖片得格式大小
File file = new File(pdfPath);
try {
PDDocument doc = PDDocument.load(file);
PDFRenderer renderer = new PDFRenderer(doc);
int pageCount = doc.getNumberOfPages();
List<BufferedImage> images=new ArrayList<BufferedImage>();
for (int i = 0; i < pageCount; i++) {
BufferedImage image = renderer.renderImageWithDPI(i, 240);
BufferedImage srcImage = resize(image, image.getWidth(), image.getHeight());
images.add(srcImage);
}
//合成圖片轉pdf
createPDFFromImage(pdfOutPath,images);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* pdf轉圖片然后合成pdf
* @param input
*/
public static byte[] pdfToImgToPdf(byte[] input){
//將pdf裝圖片 並且自定義圖片得格式大小
byte[] bytes=null;
PDDocument doc=null;
try {
doc = PDDocument.load(input);
List<BufferedImage> images=new ArrayList<BufferedImage>();
PDFRenderer renderer = new PDFRenderer(doc);
int pageCount = doc.getNumberOfPages();
for (int i = 0; i < pageCount; i++) {
BufferedImage image = renderer.renderImageWithDPI(i, 240);
BufferedImage srcImage = resize(image, image.getWidth(), image.getHeight());
images.add(srcImage);
}
bytes=createPDFFromImage(images);
} catch (IOException e) {
e.printStackTrace();
}
if(doc!=null){
try {
doc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return bytes;
}
/**
*圖片合成pdf
* @param images
* @throws Exception
*/
public static void createPDFFromImage(String pdfOutPath,List<BufferedImage> images){
PDDocument doc = new PDDocument();
try {
PDPageContentStream contentStream;
PDPage page;
for (BufferedImage image : images) {
page = new PDPage(new PDRectangle(image.getWidth(),image.getHeight()));
doc.addPage(page);
contentStream = new PDPageContentStream(doc,page,PDPageContentStream.AppendMode.APPEND, true);
PDImageXObject pdImageXObject = JPEGFactory.createFromImage(doc,image);
contentStream.drawXObject(pdImageXObject, 0, 0, image.getWidth(),image.getHeight());
contentStream.close();
}
doc.save(pdfOutPath);
}catch (Exception ex){
ex.printStackTrace();
}finally {
if (doc != null) {
try {
doc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
*圖片合成pdf
* @param images
* @throws Exception
*/
public static byte[] createPDFFromImage(List<BufferedImage> images){
byte[] bytes=null;
ByteArrayOutputStream baos=null;
PDDocument doc = new PDDocument();
try {
PDPageContentStream contentStream;
PDPage page;
for (BufferedImage image : images) {
page = new PDPage(new PDRectangle(image.getWidth(),image.getHeight()));
doc.addPage(page);
contentStream = new PDPageContentStream(doc,page,PDPageContentStream.AppendMode.APPEND, true);
PDImageXObject pdImageXObject = JPEGFactory.createFromImage(doc,image);
contentStream.drawXObject(pdImageXObject, 0, 0, image.getWidth(),image.getHeight());
contentStream.close();
}
baos = new ByteArrayOutputStream();
doc.save(baos);
bytes=baos.toByteArray();
}catch (Exception ex){
ex.printStackTrace();
}finally {
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (doc != null) {
try {
doc.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bytes;
}
/**
* 生成圖片
* @param source
* @param targetW
* @param targetH
* @return
*/
private static BufferedImage resize(BufferedImage source, int targetW, int targetH) {
int type = source.getType();
BufferedImage target = null;
double sx = (double) targetW / source.getWidth();
double sy = (double) targetH / source.getHeight();
if (sx > sy) {
sx = sy;
targetW = (int) (sx * source.getWidth());
} else {
sy = sx;
targetH = (int) (sy * source.getHeight());
}
if (type == BufferedImage.TYPE_CUSTOM) {
ColorModel cm = source.getColorModel();
WritableRaster raster = cm.createCompatibleWritableRaster(targetW, targetH);
boolean alphaPremultiplied = cm.isAlphaPremultiplied();
target = new BufferedImage(cm, raster, alphaPremultiplied, null);
} else {
target = new BufferedImage(targetW, targetH, type);
}
Graphics2D g = target.createGraphics();
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
g.dispose();
return target;
}

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM