<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
<exclusions>
<exclusion>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
我下面代码中imgurl是base64编码,让后转的图片,你们使用的话,直接替换成图片路径地址就可以了
headList参数表示表格头部需要合并的集合,如果相邻左右或者上下位置的内容相同,就会自动合并单元格
List<List<String>> headList = new ArrayList<>();
headList.add(Arrays.asList(new String[]{"1","2","2","3","3","4","4","5"}));
headList.add(Arrays.asList(new String[]{"1","6","7","8","9","10","11","5"}));
headList.add(Arrays.asList(new String[]{"1","12","13","14","15","16","17","5"}));
dataList参数表示表格下方的数据集合,会根据headList中第一行的长度进行自动换行,传入 dataList参数的长度只要是headList(0)的长度的倍数即可.
其余的一些参数是我项目中使用到的,你们看着删一删就行了.
这里面自带 合并pdf功能,两次调用方法如果传入的文件名相同的话就会合并成一个
package com.runstone.rsflow.pdf;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.runstone.system.util.ConstantParam;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.Logger;
import sun.misc.BASE64Decoder;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
/**
* 导出pdf
*/
public class PdfExport {
/**
*
* @param title pdf的标题
* @param imgUrl 图片路径 例:d:/echarts1.png
* @param filePath 要保存pdf的路径 例:d:/
* @param fileName pdf的文件名 例:1.pdf
* @param headList 表格头部的list数据
* @param dataList 表格下方的内容数据 按顺序填入集合中即可
* @param log
*/
public static void makePdf(List<String> title,List<String> imgUrl,String filePath,String fileName, List<List<String>> headList, List<String> dataList,String note, Logger log){
fileName = fileName.replaceAll("/", "");
fileName = fileName.replaceAll("\\\\","");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String format = simpleDateFormat.format(new Date());
filePath += format+File.separator;
String imgName = filePath+UUID.randomUUID().toString()+".png";
File f = new File(filePath);
OutputStream out = null;
FileOutputStream fileOutputStream = null;
if (!f.exists()){
f.mkdirs();
}
File file = new File(filePath+fileName);
String[] pdfs = new String[2];
if (file.exists()){
pdfs[0] = filePath+fileName;
fileName = UUID.randomUUID().toString()+".pdf";
}
Document document = new Document(PageSize.A2, 50, 50, 50, 50);
try {
fileOutputStream = new FileOutputStream(filePath + fileName);
PdfWriter.getInstance(document,fileOutputStream );
document.open();
BaseFont bf=BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
Font fontTitle = new Font(bf, 20, Font.NORMAL);
for (int i=0;i<title.size();i++){
if (i==0){
if (StringUtils.isNotBlank(title.get(i))){
PdfPTable table1 = new PdfPTable(1);
PdfPCell cell0 = new PdfPCell();
Paragraph p = new Paragraph(title.get(i),fontTitle);
p.setAlignment(1);
p.setSpacingBefore(15f);
cell0.setPaddingTop(-2f);//把字垂直居中
cell0.setPaddingBottom(8f);//把字垂直居中
cell0.addElement(p);
cell0.setBorder(0);
table1.addCell(cell0);
PdfPTable pTable = new PdfPTable(table1);
document.add(pTable);
}
if (StringUtils.isNotBlank(note)){
PdfPTable noteTable = new PdfPTable(1);
PdfPCell cel = new PdfPCell();
Paragraph notePar = new Paragraph(note,fontTitle);
notePar.setSpacingBefore(10f);
cel.setPaddingTop(-2f);//把字垂直居中
cel.setPaddingBottom(8f);//把字垂直居中
cel.addElement(notePar);
cel.setBorder(0);
noteTable.addCell(cel);
PdfPTable pTable3 = new PdfPTable(noteTable);
document.add(pTable3);
}
}else{
PdfPTable table1 = new PdfPTable(1);
PdfPCell cell0 = new PdfPCell();
Paragraph p = new Paragraph(title.get(i),fontTitle);
p.setSpacingBefore(13f);
cell0.setPaddingTop(-2f);//把字垂直居中
cell0.setPaddingBottom(8f);//把字垂直居中
cell0.addElement(p);
cell0.setBorder(0);
table1.addCell(cell0);
PdfPTable pTable = new PdfPTable(table1);
document.add(pTable);
}
}
if (imgUrl!=null && imgUrl.size()>0){
PdfPTable table2 = new PdfPTable(imgUrl.size()==1?1:2); //表格两列
table2.setHorizontalAlignment(Element.ALIGN_CENTER); //垂直居中
float[] wid1 = {1f};
if (imgUrl.size()>1){
wid1 = new float[]{0.5f, 0.5f}; //两列宽度的比例
}
table2.setWidths(wid1);
table2.getDefaultCell().setBorderWidth(0); //不显示边框
for (String str:imgUrl){
if (StringUtils.isNotBlank(str)){
String img = str.replaceAll(" ", "+");
String[] url = img.split("base64,");
String u = url[1];
// Base64解码
byte[] b = new BASE64Decoder().decodeBuffer(u);
// 生成图片
File file1 = new File(imgName);
out = new FileOutputStream(file1);
out.write(b);
out.flush();
out.close();
Image image = Image.getInstance(imgName);
table2.addCell(image);
file1.delete();
}
}
PdfPTable pTable2 = new PdfPTable(table2);
document.add(pTable2);//增加到文档中
}
if (headList!=null){
Font fontChinese = new Font(bf, 12, Font.NORMAL);
PdfPTable pdfPTable = makeData(headList,fontChinese);
if (dataList!=null){
for (String str : dataList){
PdfPCell cell = new PdfPCell();
Paragraph elements = new Paragraph(str,fontChinese);
elements.setAlignment(1);
cell.setVerticalAlignment(cell.ALIGN_MIDDLE);
cell.addElement(elements);
pdfPTable.addCell(cell);
}
}
PdfPTable pTable2 = new PdfPTable(pdfPTable);
document.add(pTable2);
document.close();
}
if (StringUtils.isNotBlank(pdfs[0])){
pdfs[1] = filePath+fileName;
String newPdf = UUID.randomUUID().toString()+".pdf";
mergePdfFiles(pdfs, filePath + newPdf);
new File(pdfs[1]).delete();
new File(pdfs[0]).delete();
new File(filePath + newPdf).renameTo(new File(pdfs[0]));
new File(filePath + newPdf).delete();
}
} catch (Exception e) {
log.error(ConstantParam.ERROR_SYSTEM,e);
}finally {
if (out!=null){
try {
out.close();
} catch (IOException e) {
log.error(ConstantParam.ERROR_SYSTEM,e);
}
}
if (fileOutputStream!=null){
try {
fileOutputStream.close();
} catch (IOException e) {
log.error(ConstantParam.ERROR_SYSTEM,e);
}
}
if (StringUtils.isNotBlank(imgName)){
File file1 = new File(imgName);
if (file1.exists()){
file1.delete();
}
}
}
}
/**
* 合并pdf文件
* @param files 要合并的文件名路径数组
* @param newfile 合并成新的文件路径
* @return 是否执行成功
*/
private static boolean mergePdfFiles(String[] files, String newfile) throws Exception {
boolean retValue = false;
Document document = null;
FileOutputStream fileOutputStream = null;
try {
document = new Document();
fileOutputStream = new FileOutputStream(newfile);
PdfCopy copy = new PdfCopy(document, fileOutputStream);
document.open();
for (int i = 0; i < files.length; i++) {// 几个pdf文件循环
PdfReader reader = null;
try {
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);
}
} finally {
reader.close();
}
}
retValue = true;
} finally {
document.close();
fileOutputStream.close();
}
return retValue;
}
/**
* 合并单元格方法
* @param list 表头数据 list中相连下标位置内容如果相同自动合并 上下位置内容相同自动合并
* @param fontChinese 支持转换中文的Font对象
* @return
*/
private static PdfPTable makeData(List<List<String>> list,Font fontChinese){
int length = list.get(0).size();
PdfPTable table2 = new PdfPTable(list.get(0).size());
List<List<PdfPCell>> aa = new ArrayList<>();
for (int i=0;i<list.size();i++){
List<String> strings = list.get(i);
int colNum = 1;
List<PdfPCell> bb = new ArrayList<>();
for (int j=0;j <strings.size();j++){
if (j+1<strings.size()){
if (strings.get(j).equals(strings.get(j+1))){
colNum++;
}else{
PdfPCell cell = new PdfPCell();
cell.setColspan(colNum);
Paragraph elements = new Paragraph(strings.get(j),fontChinese);
elements.setAlignment(1);
cell.setVerticalAlignment(cell.ALIGN_MIDDLE);
cell.addElement(elements);
bb.add(cell);
for (int a=1;a<colNum;a++){
bb.add(null);
}
colNum=1;
}
}else{
PdfPCell cell = new PdfPCell();
cell.setColspan(colNum);
Paragraph elements = new Paragraph(strings.get(j),fontChinese);
cell.setVerticalAlignment(cell.ALIGN_MIDDLE);
elements.setAlignment(1);
cell.addElement(elements);
bb.add(cell);
for (int a=1;a<colNum;a++){
bb.add(null);
}
colNum=1;
}
}
aa.add(bb);
}
for (int i=0;i<length;i++){
int rowSpan = 1;
for (int j=0;j<aa.size();j++){
if (aa.get(j).get(i)==null){
continue;
}
if (j+1<aa.size()){
if (aa.get(j+1).get(i)!=null && aa.get(j).get(i).getCompositeElements().get(0).toString()
.equals(aa.get(j+1).get(i).getCompositeElements().get(0).toString())
&&aa.get(j).get(i).getCompositeElements().get(0).toString()
.equals(aa.get(j+1).get(i).getCompositeElements().get(0).toString())
){
rowSpan++;
}else{
aa.get(j-rowSpan+1).get(i).setRowspan(rowSpan);
for (int a=1;a<rowSpan;a++){
aa.get(j-rowSpan+1+a).set(i,null);
}
rowSpan=1;
}
}else{
aa.get(j-rowSpan+1).get(i).setRowspan(rowSpan);
for (int a=1;a<rowSpan;a++){
aa.get(j-rowSpan+1+a).set(i,null);
}
rowSpan=1;
}
}
}
for (List<PdfPCell> a:aa){
for (PdfPCell pCell:a){
if (pCell!=null){
table2.addCell(pCell);
}
}
}
return table2;
}
}