相关jar包
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<!--<exclusions>-->
<!--<exclusion>-->
<!--<groupId>*</groupId>-->
<!--<artifactId>*</artifactId>-->
<!--</exclusion>-->
<!--</exclusions>-->
<version>2.1.7</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.*;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
/**
-
Created by Gaci on 2020/7/28.
/
public class PDFUtils {
/ BASE64Encoder和BASE64Decoder这两个方法是sun公司的内部方法,并没有在java api中公开过,所以使用这些方法是不安全的,- 将来随时可能会从中去除,所以相应的应该使用替代的对象及方法,建议使用apache公司的API—可引用 import org.apache.commons.codec.binary.Base64;进行替换
*/
static BASE64Encoder encoder = new BASE64Encoder();
static BASE64Decoder decoder = new BASE64Decoder();
public static void main(String[] args) throws Exception{
//将PDF格式文件转成base64编码
// String base64String = getPDFBinary(“E:\123.pdf”);
// System.out.println(base64String);
// base64String = base64String.replaceAll("\r","");
// base64String = base64String.replaceAll("\t","");
// base64String = base64String.replaceAll("\n","");
// System.out.println(base64String); - 将来随时可能会从中去除,所以相应的应该使用替代的对象及方法,建议使用apache公司的API—可引用 import org.apache.commons.codec.binary.Base64;进行替换
// Integer a = new Integer(3);
// Integer b = 3;
// int c=3;
// System.out.println(a ==b);
// System.out.println(a ==c);
// Integer f1 =100,f2=100,f3=150,f4=150;
// System.out.println(f1 ==f2);
// System.out.println(f3 ==f4);
// int c=200;
// Integer d=200;
// System.out.println(c ==d);
// System.out.println(d.equals©);
// 方式1:--start
// 路径
String path = "";
// PDFbase64
String URLBase = "";
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
String fileName = "label_"+sf.format(new Date());
String labelPathPdf = path + "/"+fileName +".pdf";
File file = base64StringToPDF(URLBase,labelPathPdf);
// controller,action 获取HttpServletResponse
HttpServletResponse response = ServletActionContext.getResponse();
// controller,action 调用
OutputStream os = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
setResponsePdfHeader(response, fileName);
pdfFilesAndResponse(file,os);
// 方式1:--end
// 方式2:--start
List<String> fileNames1 = new ArrayList<String>();//存放pdf的url
SimpleDateFormat sf1 = new SimpleDateFormat("yyyyMMddHHmmss");
String fileName1 = "label2_" + sf1.format(new Date());
String pdfFilePath1 = fileName +".pdf";//PDF文件名
File pdfFile1 = new File(pdfFilePath1);// PDF文件
//定义输出流
HttpServletResponse response1= ServletActionContext.getResponse();
OutputStream os1 = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
setResponseHeader(response1, fileName1);
mergePdfFiles(fileNames1, pdfFile1);
pdfFilesAndResponse(pdfFile1, os1);
// 方式2:--end
}
/**
* 将PDF转换成base64编码
* 1.使用BufferedInputStream和FileInputStream从File指定的文件中读取内容;
* 2.然后建立写入到ByteArrayOutputStream底层输出流对象的缓冲输出流BufferedOutputStream
* 3.底层输出流转换成字节数组,然后由BASE64Encoder的对象对流进行编码
* @param filePath
* @return
*/
public static String getPDFBinary(String filePath) {
FileInputStream fin =null;
BufferedInputStream bin =null;
ByteArrayOutputStream baos = null;
BufferedOutputStream bout =null;
try {
//建立读取文件的文件输出流
fin = new FileInputStream(new File(filePath));
//在文件输出流上安装节点流(更大效率读取)
bin = new BufferedInputStream(fin);
// 创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量
baos = new ByteArrayOutputStream();
//创建一个新的缓冲输出流,以将数据写入指定的底层输出流
bout = new BufferedOutputStream(baos);
byte[] buffer = new byte[1024];
int len = bin.read(buffer);
while(len != -1){
bout.write(buffer, 0, len);
len = bin.read(buffer);
}
//刷新此输出流并强制写出所有缓冲的输出字节,必须这行代码,否则有可能有问题
bout.flush();
byte[] bytes = baos.toByteArray();
//sun公司的API
return encoder.encodeBuffer(bytes).trim();
//apache公司的API
//return Base64.encodeBase64String(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
fin.close();
bin.close();
//关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException
//baos.close();
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/**
* 将base64编码转换成PDF,保存到
* @param base64sString
* 1.使用BASE64Decoder对编码的字符串解码成字节数组
* 2.使用底层输入流ByteArrayInputStream对象从字节数组中获取数据;
* 3.建立从底层输入流中读取数据的BufferedInputStream缓冲输出流对象;
* 4.使用BufferedOutputStream和FileOutputSteam输出数据到指定的文件中
*/
public static void base64StringToPDF1(String base64sString,String filePath){
BufferedInputStream bin = null;
FileOutputStream fout = null;
BufferedOutputStream bout = null;
try {
//将base64编码的字符串解码成字节数组
byte[] bytes = decoder.decodeBuffer(base64sString);
//apache公司的API
//byte[] bytes = Base64.decodeBase64(base64sString);
//创建一个将bytes作为其缓冲区的ByteArrayInputStream对象
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
//创建从底层输入流中读取数据的缓冲输入流对象
bin = new BufferedInputStream(bais);
//指定输出的文件
File file = new File(filePath);
//创建到指定文件的输出流
fout = new FileOutputStream(file);
//为文件输出流对接缓冲输出流对象
bout = new BufferedOutputStream(fout);
byte[] buffers = new byte[1024];
int len = bin.read(buffers);
while(len != -1){
bout.write(buffers, 0, len);
len = bin.read(buffers);
}
//刷新此输出流并强制写出所有缓冲的输出字节,必须这行代码,否则有可能有问题
bout.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
bin.close();
fout.close();
bout.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 解码 PDF流
* @param base64String PDF流字符串
* @param newFile 文件保存地址
*/
public static File base64StringToPDF(String base64String, String newFile) {
File file = null;
try {
BASE64Decoder decoder = new BASE64Decoder();
byte[] bytes = decoder.decodeBuffer(base64String);
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
BufferedInputStream bin = new BufferedInputStream(bais);
file = new File(newFile);
FileOutputStream fout = new FileOutputStream(file);
BufferedOutputStream bout = new BufferedOutputStream(fout);
byte[] buffers = new byte[1024];
int len = bin.read(buffers);
while (len != -1) {
bout.write(buffers, 0, len);
len = bin.read(buffers);
}
bout.flush();
bout.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
public static void createZip(List<String> fileNames, String fileName) throws Exception {
File zipFile = new File(fileName + ".zip");
//定义输出流
HttpServletResponse response= ServletActionContext.getResponse();
OutputStream os = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
setResponseZipHeader(response,fileName);
zipFilesAndResponse(fileNames,zipFile,os);
}
public static void createPdf(List<String> fileNames,String fileName) throws Exception {
if(!fileNames.isEmpty() && !StringUtils.isEmpty(fileName)) {
File pdfFile = new File(fileName + ".pdf" );
//定义输出流
HttpServletResponse response = ServletActionContext.getResponse();
OutputStream os = response.getOutputStream();// 取得输出流
response.reset();// 清空输出流
setResponsePdfHeader(response, fileName);
mergePdfFiles(fileNames, pdfFile);
pdfFilesAndResponse(pdfFile, os);
}
}
/** 设置响应头 */
public static void setResponseZipHeader(HttpServletResponse response,String fileName) {
try {
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="
+ java.net.URLEncoder.encode(fileName, "UTF-8")+".zip");
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
/** 设置响应头 */
public static void setResponseXlsHeader(HttpServletResponse response,String fileName) {
try {
response.setContentType("application/msexcel;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="
+ java.net.URLEncoder.encode(fileName, "UTF-8")+".xls");
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
/** 设置响应头 */
public static void setResponsePdfHeader(HttpServletResponse response,String fileName) {
try {
// response.setContentType(“application/octet-stream;charset=UTF-8”);
response.setContentType(“application/pdf;charset=UTF-8”);
response.setHeader(“Content-Disposition”, “filename=”
+ java.net.URLEncoder.encode(fileName, “UTF-8”)+".pdf");
response.addHeader(“Pargam”, “no-cache”);
response.addHeader(“Cache-Control”, “no-cache”);
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 输出excel文件
* @param fileNames 临时文件名
* @param out 输出流
* @throws Exception
*/
public static void responseXlsFile(List<String> fileNames,OutputStream out) throws Exception
{
File srcFile = new File(fileNames.get(0));
FileInputStream inStream = null;
try
{
inStream = new FileInputStream(srcFile);
byte[] buf = new byte[4096];
int readLength;
while (((readLength = inStream.read(buf)) != -1)) {
out.write(buf, 0, readLength);
}
inStream.close();
out.flush();
out.close();
}catch (Exception ex)
{
ex.printStackTrace();
throw new Exception(ex.getMessage());
}finally {
if(inStream != null)
inStream.close();
if(out != null)
{
out.flush();
out.close();
}
if(srcFile != null) //删除临时文件
if(srcFile.exists()) srcFile.delete();
}
}
/**
*压缩文件并输出到客户端
* @param fileNames 需要压缩的文件名
* @param zipFile 压缩文件
* @param out 输出流
* @throws Exception
*/
public static void zipFilesAndResponse(List<String> fileNames,File zipFile,OutputStream out) throws Exception
{
File srcFiles[] = new File[fileNames.size()];
for (int i = 0, n = fileNames.size(); i < n; i++) {
srcFiles[i] = new File(fileNames.get(i));
}
FileInputStream inStream = null;
try
{
ZipFiles(srcFiles, zipFile);
inStream = new FileInputStream(zipFile);
byte[] buf = new byte[4096];
int readLength;
while (((readLength = inStream.read(buf)) != -1)) {
out.write(buf, 0, readLength);
}
inStream.close();
out.flush();
out.close();
}catch (Exception ex)
{
ex.printStackTrace();
throw new Exception(ex.getMessage());
}finally {
if(inStream != null)
inStream.close();
if(out != null)
{
out.flush();
out.close();
}
if(zipFile.exists()) zipFile.delete();//删除压缩文件
for(File srcFile:srcFiles) //删除临时文件
if(srcFile.exists()) srcFile.delete();
}
}
/**
*
* @param srcFile 文件名数组
* @param zipFile 压缩后文件
*/
public static void ZipFiles(java.io.File[] srcFile, java.io.File zipFile) throws Exception{
byte[] buf = new byte[1024];
try {
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
zipFile));
for (int i = 0; i < srcFile.length; i++) {
FileInputStream in = new FileInputStream(srcFile[i]);
out.putNextEntry(new ZipEntry(srcFile[i].getName()));
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
out.closeEntry();
in.close();
}
out.close();
} catch (IOException e) {
e.printStackTrace();
throw new Exception(e.getMessage());
}
}
/**
*PDF文件并输出到客户端
* @param pdfFile pdf文件
* @param out 输出流
* @throws Exception
*/
public static void pdfFilesAndResponse(File pdfFile, OutputStream out) throws Exception
{
FileInputStream inStream = null;
try
{
inStream = new FileInputStream(pdfFile);
byte[] buf = new byte[4096];
int readLength;
while (((readLength = inStream.read(buf)) != -1)) {
out.write(buf, 0, readLength);
}
inStream.close();
out.flush();
out.close();
}catch (Exception ex)
{
ex.printStackTrace();
throw new Exception(ex.getMessage());
}finally {
if(inStream != null)
inStream.close();
if(out != null)
{
out.flush();
out.close();
}
if(pdfFile.exists()) pdfFile.delete();//删除压缩文件
}
}
public static boolean mergePdfFiles(List<String> fileNames, File outfile) throws Exception {
boolean retValue = false;
com.lowagie.text.Document document = null;
try {
String[] files = new String[fileNames.size()];
for(int i=0;i<fileNames.size();i++){
files[i]= fileNames.get(i);
}
document = new com.lowagie.text.Document(new PdfReader(files[0]).getPageSize(1));
PdfCopy copy = new PdfCopy(document, new FileOutputStream(outfile));
document.open();
for (int i = 0; i < files.length; i++) {
PdfReader reader = new PdfReader(files[i]);
int n = reader.getNumberOfPages();
for (int j = 1; j <= n; j++) {
document.newPage();
PdfImportedPage page = copy.getImportedPage(reader, j);
copy.addPage(page);
}
}
retValue = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
document.close();
}
return retValue;
}
/** 设置响应头 */
public static void setResponseHeader(HttpServletResponse response,String fileName) {
try {
response.setContentType("application/octet-stream;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;filename="
+ java.net.URLEncoder.encode(fileName, "UTF-8") + ".pdf");
response.addHeader("Pargam", "no-cache");
response.addHeader("Cache-Control", "no-cache");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public static void AddContentToPDF(String pdfFile,String newPdfFile) throws Exception{
//创建一个pdf读入流
com.itextpdf.text.pdf.PdfReader reader = new com.itextpdf.text.pdf.PdfReader(pdfFile);
//根据一个pdfreader创建一个pdfStamper.用来生成新的pdf.
PdfStamper stamper = new PdfStamper(reader,
new FileOutputStream(newPdfFile));
//这个字体是itext-asian.jar中自带的 所以不用考虑操作系统环境问题.
String realPath = AddContentToPDF.class.getResource("").toString();
// msyh.ttf 是字体文件bai,就是微软雅黑,它是美du国微软公司委托中国北大zhi方正电子有限公司设计的一款全面支持daoClearType技术的字体。
realPath = realPath.substring(5, realPath.indexOf("WEB-INF")) + "template/common/fonts/msyh.ttf";// 存放路径
BaseFont bf = BaseFont.createFont(realPath, BaseFont.IDENTITY_H,BaseFont.NOT_EMBEDDED);
//baseFont不支持字体样式设定.但是font字体要求操作系统支持此字体会带来移植问题.
Font font = new Font(bf,10);
font.setStyle(Font.BOLD);
font.getBaseFont();
//页数是从1开始的
for (int i=1; i<=reader.getNumberOfPages(); i++){
//获得pdfstamper在当前页的上层打印内容.也就是说 这些内容会覆盖在原先的pdf内容之上.
PdfContentByte over = stamper.getOverContent(i);
//用pdfreader获得当前页字典对象.包含了该页的一些数据.比如该页的坐标轴信息.
PdfDictionary p = reader.getPageN(i);
//拿到mediaBox 里面放着该页pdf的大小信息.
PdfObject po = p.get(new PdfName("MediaBox"));
System.out.println(po.isArray());
//po是一个数组对象.里面包含了该页pdf的坐标轴范围.
PdfArray pa = (PdfArray) po;
System.out.println(pa.size());
//看看y轴的最大值.
System.out.println(pa.getAsNumber(pa.size()-1));
//开始写入文本
over.beginText();
//设置字体和大小
over.setFontAndSize(font.getBaseFont(), 6);
//设置字体颜色
over.setColorFill(BaseColor.BLACK);
String productName = "一二三四五六七八九十一二三四五六七八九十";
String[] lines = new String[2];
if (productName.length() > 10) {
lines[0] = productName.substring(0, 10);
lines[1] = productName.substring(10, productName.length());
} else {
lines[0] = productName;
lines[1] = "";
}
if (i == 1) {
//设置字体的输出位置
over.setTextMatrix(200, 250);
//要输出的text
over.showText(lines[0]);
//设置字体的输出位置
over.setTextMatrix(200, 242);
//要输出的text
over.showText(lines[1]);
} else if (i == 2){
//设置字体的输出位置
over.setTextMatrix(210, 180);
//要输出的text
over.showText(lines[0]);
//设置字体的输出位置
over.setTextMatrix(210, 172);
//要输出的text
over.showText(lines[1]);
}
over.endText();
}
stamper.close();
}
}