package com.harper.util;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.BadElementException;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfReader;
import java.awt.Color;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.jboss.netty.util.internal.ReusableIterator;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Image;
import com.lowagie.text.PageSize;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfWriter;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.PdfPageNumber;
import com.spire.pdf.PdfPageRotateAngle;
import com.spire.pdf.widget.PdfPageCollection;
import play.Logger;
import play.Play;
import sun.misc.BASE64Decoder;
/**
*
*
* 判断PDF文件是否损坏
*
* @author Administrator
*
*/
public class PdfUtil {
/**
*
* 判断pdf 是否损坏
*
*/
public static boolean check(String file) {
boolean flag1 = false;
int n = 0;
try {
Document document = new Document(new PdfReader(file).getPageSize(1));
document.open();
PdfReader reader = new PdfReader(file);
n = reader.getNumberOfPages();
if (n != 0)
flag1 = true;
document.close();
} catch (Exception e) {
}
return flag1;
}
/**
*
*
*
* 如果原PDF不存在或者损坏 那么就不能返回文件路径
*
* @param outputFile (添加了sku后输出的文件路径)
* @param input 原始PDF文件
* @param waterMarkName 添加的文字信息
*
*/
public static String setWatermark(String filename, String inputFilePath, String waterMarkName) {
String outputfilepath = Play.configuration.getProperty("applicationPath") + "/file/orderprint/skupdf/" + filename + ".pdf";
File fileout = new File(outputfilepath);
try {
if(fileout.exists()){
fileout.delete();
}
Boolean status = PdfUtil.check(inputFilePath);
File file = new File(inputFilePath);
if(!file.exists() || !status){
return "";
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputfilepath)));
PdfReader reader = new PdfReader(inputFilePath);
PdfStamper stamper = new PdfStamper(reader, bos);
int total = reader.getNumberOfPages() + 1;
PdfContentByte content;
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
for (int i = 1; i < total; i++) {
content = stamper.getOverContent(i);
content.beginText();
content.setColorFill(Color.black);
content.setFontAndSize(base, 7);
content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, 4, 2, 0);
content.endText();
}
stamper.close();
} catch (Exception e) {
}
return outputfilepath;
}
/**
*
* 传入一个从代理那里下载的文件流, 然后先将此文件流保存成一个文件 名字选择为传入的 "tracking_D" 保证以后如果形成错误后,可以找回原面单进行后台修改
*
*
* @param trackingNo
* @param labelPdfBytes
* @param x x轴 14
* @param y y轴(相对于坐标原点(0,0)) 253
* @param height 长度 80
* @param width 高度120
* @return
*/
public static byte[] setWatermarkImage(String trackingNo, byte[] labelPdfBytes, int x, int y, int height, int width) {
try {
//先把文件流形成文件
String fromOtherPdfFile = Play.configuration.getProperty("applicationPath")+"/file/orderprint/pdf/" + trackingNo+"_D" + ".pdf";
FileUtils.writeByteArrayToFile(new File(fromOtherPdfFile), labelPdfBytes);
String outputfilepath = Play.configuration.getProperty("applicationPath")+"/file/orderprint/pdf/"+trackingNo+".pdf";
Boolean status = PdfUtil.check(fromOtherPdfFile);
if(!status){
return labelPdfBytes;
}
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputfilepath)));
PdfReader reader = new PdfReader(fromOtherPdfFile);
PdfStamper stamper = new PdfStamper(reader, bos);
int total = reader.getNumberOfPages() + 1;
PdfContentByte content;
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
for (int i = 1; i < total; i++) {
content = stamper.getOverContent(i);
Image image = Image.getInstance(Play.configuration.getProperty("applicationPath")+"/file/imgs/white.png");
image.setAbsolutePosition(x, y);
image.scaleToFit(height, width);
content.addImage(image);
content.setColorFill(Color.BLACK);
content.setFontAndSize(base, 8);
content.endText();
}
stamper.close();
return FileUtil.fileTobyte(outputfilepath);
} catch (Exception e) {
return labelPdfBytes;
}
}
/***
*
* 合并PDF
*
*
* @param files 传入文件路径数组
* @param savepath 形成新的文件路径
*/
public static void mergePdfFiles(String[] files, String savepath) {
try {
String firstPdf = null;
int index = 0;
// 第一个不为空的PDF将成为第一页
while (firstPdf == null) {
firstPdf = files[index];
}
Document document = new Document(
new PdfReader(files[0]).getPageSize(1));
PdfCopy copy = new PdfCopy(document, new FileOutputStream(savepath));
document.open();
for (int i = 0; i < files.length; i++) {
if (files[i] != null) {
File f = new File(files[i]);
if (f.exists()) {
PdfReader reader = null;
try{
reader = new PdfReader(files[i]);
}catch (Exception e) {
Logger.info(files[i]);
e.printStackTrace();
}
if(reader != null) {
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
}
}
}
}
document.close();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 图片转换成PDF
*
* @param inputFile
* @param outFile
* @param x 长 812
* @param y 宽 1218
*/
public static void pngToPdf(String inputFile, String outFile, int x, int y){
try {
Rectangle rect = new Rectangle(x,y);
Document document = new Document(rect, 0, 0, 0, 0);
PdfWriter.getInstance(document, new FileOutputStream(outFile));
document.open();
Image image = Image.getInstance(inputFile);
document.add(image);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
*
* byte[] zeroLabelPdfBytes = setwaterImageAndSetMark(
"C:\\Users\\Administrator\\Desktop\\tdw\\",
FileUtil.fileTobyte("C:\\Users\\Administrator\\Desktop\\tmp\\D.pdf"),
"C:\\Users\\Administrator\\Desktop\\tmp\\white.png",
"深圳夏浦物流有限公司",
101,
165,
82,
80);
*
*
*
*
* 先将不需要的部分用白色的图片给盖住,然后在盖住的地方打上水印也就是文字(这个方法集成了 PDF图片水印,和PDF文字水印的方式,是上面单纯盖图片和在单纯打水印的升级版)
*
* 每次只能做一个操作 (不可以同时盖住多个地方) 每次调用这个方法,都会形成将近4个中间文件出来 ,如果不是特别的需求,建议不要使用(单纯使用盖住,或者单纯使用加水印的方式)
*
* 如果只需要盖住某个地方 ,那么就可以不用传入水印文字(或者可以使用上面单纯的盖住某一块的方式,效率比较高)
*
* 这个方式比上面单纯加水印的方式优点在于,会直接覆盖之前的文字(用了图片进行覆盖,之前的东西看不到了),单纯的加水印的方式, 之前的那些都还会存在,会重叠
*
*
*
* @param filePath 需要保存中间文件的文件夹, 这个文件夹到时候可以找到中间环节的文件, 具体转换过程
* @param labelPdfBytes 传入的文件流(实体文件形成的文件流,用FileUtils封装的一个方法进行使用转换) 或者直接从代理那里下载的文件流
* @param pngFilepath 盖住图片的文件路径(有时候可以是自己设置的一个logo,或者是一个纯色的png图片)
* @param mark 在盖上图片的位置加上水印文字
* @param x 相对于原点的坐标 x
* @param y 相对于原点的坐标y
* @param width 图片的宽度
* @param height 图片的高度
*
* @return 返回一个做了修改后的文件流 这个文件流可以直接形成文件
*/
public static byte[] setwaterImageAndSetMark(String filePath, byte[] labelPdfBytes, String pngFilepath, String mark, int x,int y, int width, int height ){
byte[] endLabelPdfBytes = null;
try {
//首先将传入的文件流形成一个文件
String saveFirstPathAndFileName =filePath + "first_in_" + UUID.randomUUID() + ".pdf";
FileUtils.writeByteArrayToFile(new File(saveFirstPathAndFileName), labelPdfBytes);
//进行加工处理
String outputFirstfilepathAndFileName = filePath + "first_out_" + UUID.randomUUID() + ".pdf";
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(outputFirstfilepathAndFileName)));
PdfReader reader = new PdfReader(saveFirstPathAndFileName);
PdfStamper stamper = new PdfStamper(reader, bos);
int total = reader.getNumberOfPages() + 1;
PdfContentByte content;
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
for (int i = 1; i < total; i++) {
content = stamper.getOverContent(i);
Image image = Image.getInstance(pngFilepath);
image.setAbsolutePosition(x, y);
image.scaleToFit(height, width);
content.addImage(image);
content.setColorFill(Color.BLACK);
content.setFontAndSize(base, 8);
content.endText();
}
stamper.close();
//已经覆盖上图片的文件流
endLabelPdfBytes = FileUtil.fileTobyte(outputFirstfilepathAndFileName);
//然后再将第一次形成的文件流 设置一个水印字体
String saveTwoFilePathAndFileName = filePath + "two_in_" + UUID.randomUUID() +".pdf";
FileUtils.writeByteArrayToFile(new File(saveTwoFilePathAndFileName), endLabelPdfBytes);
String outputTwoFilePathAndFileName = filePath + "two_out_" + UUID.randomUUID() +".pdf";
BufferedOutputStream bosTwo = new BufferedOutputStream(new FileOutputStream(new File(outputTwoFilePathAndFileName)));
PdfReader readerTwo = new PdfReader(saveTwoFilePathAndFileName);
PdfStamper stamperTWo = new PdfStamper(readerTwo, bosTwo);
int totalTwo = readerTwo.getNumberOfPages() + 1;
PdfContentByte contentSecond;
BaseFont baseTwo = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
for (int i = 1; i < totalTwo; i++) {
contentSecond = stamperTWo.getOverContent(i);
contentSecond.beginText();
contentSecond.setColorFill(Color.BLACK);
contentSecond.setFontAndSize(baseTwo, 7);
contentSecond.showTextAligned(Element.ALIGN_LEFT, mark, x, y, 0);
contentSecond.endText();
}
stamperTWo.close();
endLabelPdfBytes = FileUtil.fileTobyte(outputTwoFilePathAndFileName);
} catch (Exception e) {
e.printStackTrace();
}
return endLabelPdfBytes;
}
/**
* PDF 旋转 (只能旋转一个PDF)
* @param fromFileName
* @param toFileName
*/
public static String anglePDF(String oldFileName,String angleFileName){
if(StringUtils.isBlank(oldFileName)){
return "";
}
try {
// 加载PDF文档
PdfDocument pdf = new PdfDocument();
pdf.loadFromFile(oldFileName);
// 获取第一页
PdfPageBase page = pdf.getPages().get(0);
// 获取第一页当前的旋转角度
int rotateAngle = page.getRotation().getValue();
// 在当前旋转角度的基础上,将第一页顺时针旋转90度(可选0/90/180/270度)
rotateAngle+=PdfPageRotateAngle.Rotate_Angle_90.getValue();
page.setRotation((PdfPageRotateAngle.fromValue(rotateAngle)));
// 保存文档
pdf.saveToFile(angleFileName);
return angleFileName;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}