iText是一种生成PDF报表的Java组件
maven项目,添加依赖如下:
<!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.itextpdf/itext-asian -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
Controller 如下:
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/pdf")
public class PdfController {
@PostMapping("/PDFTest")
public void exportPDFTest(HttpServletResponse response) {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
String fileName = URLEncoder.encode(System.currentTimeMillis()+"", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".pdf");
ByteArrayOutputStream baos = new ByteArrayOutputStream();// 构建字节输出流
// 实例化文档对象
Document document = new Document(PageSize.A4, 10, 10, 10, 10);
// 创建 PdfWriter 对象 文件的输出路径+文件的实际名称
PdfWriter writer = PdfWriter.getInstance(document, baos);// 设置分页
// writer.setPageEvent(new PDFMaker());
document.open();// 打开文档
// 创建一个段落
document.add(PDFUtil.getPDFParagraph("测试PDF标题", 0, 20, Element.ALIGN_CENTER, 1));
// 标题
String[] title = {"ID", "姓名", "年龄", "生日", "出生地", "身份证", "住址"};
// 列宽
int tableWidth[] = {10, 15, 15, 15, 15, 15, 15};
Map<String, Object> map = new HashMap<>();
//自定义数据列
List<UserPdfExport> userPdfExports = new ArrayList<>();
UserPdfExport userPdfExport = new UserPdfExport();
userPdfExport.setId(1);
userPdfExport.setName("zhang");
userPdfExport.setAge(12);
userPdfExport.setBirthday("232");
userPdfExport.setCsd("住址住址住址住址住址住址住址住址");
userPdfExport.setIdCard("住址住址住址");
userPdfExport.setAddress("住址住址住址住址阿斯顿发送到发送到发送到发送到发送到发送到阿斯顿发送到阿斯顿发水电费阿斯顿发送到阿斯蒂芬阿萨德");
userPdfExports.add(userPdfExport);
map.put("ksList", userPdfExports);
if (map != null) {
if (map.get("ksList") != null) {
List list = (List<UserPdfExport>) map.get("ksList");
// 获取PDFTable
PdfPTable table = PDFUtil.getPDFTable(tableWidth, title, list, 0);
// 添加进文档
document.add(table);
}
}
// 关闭文档
if (document != null) {
document.close();
}
if (baos != null) {
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
OutputStream os = response.getOutputStream();
// 设置文件大小
// response.setContentLength((int) f.length());
os.write(baos.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
}
}
PDFUtil工具类 如下:
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;
public class PDFUtil {
static BaseFont baseFont = null;
static {
try {
baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
/**
* PDF大标题字体
*/
public static Font PDFTITLEFONT = new Font(baseFont, 16, Font.BOLD);
/**
* PDF小标题字体
*/
public static Font PDFTITLEFONT1 = new Font(baseFont, 13, Font.NORMAL);
/**
* 表格宽度百分比
*/
public static Integer WIDTHPERCENTAGE = 98;
/**
* 表格标题字体
*/
public static Font TITLEFONT = new Font(baseFont, 12, Font.NORMAL);
/**
* 翻页加载表头
*/
public static Integer HEADERROWS = 1;
/**
* 翻页不加载表头
*/
public static Integer NOHEADERROWS = 0;
/**
* 表格内容字体
*/
public static Font CONTENTFONT = new Font(baseFont, 9, Font.NORMAL);
/**
* PDF表格样式
*/
private static PdfPCell cell = new PdfPCell();
/**
* 获取表格
*/
public static PdfPCell getCell() {
// 水平居中
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
// 垂直居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
// 边距
cell.setPadding(1);
// 行高
cell.setMinimumHeight(22);
cell.setBorderColor(BaseColor.BLACK);
// 不换行
// cell.setNoWrap(true);
// 颜色淡化
// cell.setBorderColor(Color.decode("#EBEEF5"));
cell.setBorderColor(new BaseColor(1));
cell.setBackgroundColor(BaseColor.WHITE);
cell.setBorder(0);
cell.setBorderWidthTop(0.1f);
cell.setBorderWidthBottom(0.1f);
cell.setBorderWidthLeft(0.1f);
cell.setBorderWidthRight(0.1f);
cell.setBorderColorBottom(BaseColor.BLACK);
cell.setBorderColorLeft(BaseColor.BLACK);
cell.setBorderColorRight(BaseColor.BLACK);
cell.setBorderColorTop(BaseColor.BLACK);
cell.setPadding(3);
return cell;
}
/**
* 获取表格并赋值
*/
public static PdfPCell getCell(Paragraph content) {
cell = getCell();
// 设置内容
cell.setPhrase(content);
return cell;
}
/**
* @param titleNum 列数
* @param tableWidth 列宽
* @param titles 标题集合
* @param contents 内容集合
* @param headerRows 是否再次加载表头
* @return
* @throws Exception
* @Description 生成PDF表格
*/
public static void setTableStyle(PdfPTable table, PdfPCell cell) {
// 设置表格样式
table.setLockedWidth(true);
table.setTotalWidth(500);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
// 设置单元格样式
cell.setMinimumHeight(35);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setBackgroundColor(BaseColor.WHITE);
cell.setBorder(0);
cell.setBorderWidthTop(0.1f);
cell.setBorderWidthBottom(0.1f);
cell.setBorderWidthLeft(0.1f);
cell.setBorderWidthRight(0.1f);
cell.setBorderColorBottom(BaseColor.BLACK);
cell.setBorderColorLeft(BaseColor.BLACK);
cell.setBorderColorRight(BaseColor.BLACK);
cell.setBorderColorTop(BaseColor.BLACK);
cell.setPadding(3);
}
public static PdfPTable getPDFTable(int[] tableWidth, String[] titles, List<Object> contents, int headerRows) throws Exception {
// 创建表格对象
// 列数
PdfPTable table = new PdfPTable(titles.length);
// 表格宽度百分比
table.setWidthPercentage(WIDTHPERCENTAGE);
table.setSpacingBefore(20);
table.setSpacingAfter(20);
// 列宽百分比
if (tableWidth != null) table.setWidths(tableWidth);
// 翻页加载表头
if (headerRows == HEADERROWS) table.setHeaderRows(HEADERROWS);
// 标题集合
String[] pdfTitles = titles;
if (pdfTitles != null && pdfTitles.length > 0) {
// 标题
for (String pdfTitle : pdfTitles) {
PdfPCell title = getCell(new Paragraph(pdfTitle, TITLEFONT));
table.addCell(title);
}
}
// 内容集合
if (contents != null && contents.size() > 0) {
Field[] fields = contents.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
fieldNames[i] = fields[i].getName();
}
}
// 内容集合
if (contents != null && contents.size() > 0) {
for (Object obj : contents) {
Field[] fields = obj.getClass().getDeclaredFields();
String[] fieldNames = new String[fields.length];
for (int i = 0; i < fields.length; i++) {
fieldNames[i] = fields[i].getName();
String firstLetter = fieldNames[i].substring(0, 1).toUpperCase();
String getter = "get" + firstLetter + fieldNames[i].substring(1);
Method method = obj.getClass().getMethod(getter, new Class[]{});
Object value = method.invoke(obj, new Object[]{});
PdfPCell content = getCell(new Paragraph(String.valueOf(value), CONTENTFONT));
table.addCell(content);
}
// 撑行数,否则最后一行会消失
table.addCell("");
table.completeRow();
}
}
return table;
}
/**
* @param content 段落内容
* @param top 上边距
* @param bottom 下边距
* @param align 居中
* @param type 标题类别
* @return
* @throws Exception
*/
public static Paragraph getPDFParagraph(String content, int top, int bottom, int align, int type) throws Exception {
Paragraph paragraph = null;
if (type == 1) {
paragraph = new Paragraph(content, PDFTITLEFONT);
} else {
paragraph = new Paragraph(content, PDFTITLEFONT1);
}
paragraph.setSpacingAfter(top);
paragraph.setSpacingBefore(bottom);
paragraph.setAlignment(align);
return paragraph;
}
}
UserPdfExport实体类 如下:
import lombok.Data;
@Data
public class UserPdfExport {
private Integer id;
private String name;
private Integer age;
private String birthday;
private String csd;
private String idCard;
private String address;
}
测试结果 如下:
其他部分:
1.PDF添加图片:
Document doc= new Document(PageSize.A1, 10, 10, 10, 10); //创建文档
PdfWriter writer= PdfWriter.getInstance(tDoc, new FileOutputStream(mFileFullPath.toString())); //创建写入流
writer.setEncryption(null,"123".getBytes(), PdfWriter.ALLOW_SCREENREADERS|PdfWriter.ALLOW_PRINTING,PdfWriter.STANDARD_ENCRYPTION_128); //加密
doc.open(); //打开文档
Image image= Image.getInstance(new DefaultResourceLoader().getResource("classpath:static/images/1.jpg").getURL());
/* 设置图片的位置 */
image.setAbsolutePosition(0, 0);
/* 设置图片的大小 */
image.scaleAbsolute(842, 1190);
doc.add(image); //加载图片
2.PDF中的Excel的单元格修改背景颜色:
//添加到工具类的PdfPTable方法中的内容集合中去
Font CONTENTFONT = new Font(baseFont, 9, Font.NORMAL);
PdfPCell content = getCell(new Paragraph(String.valueOf(value), CONTENTFONT));
content.setBackgroundColor(BaseColor.WHITE);
if (fields[i].getName().equals("Color")) {//定制化的红黄绿颜色
if (String.valueOf(value).contains("红")) content.setBackgroundColor(BaseColor.RED);
if (String.valueOf(value).contains("黄")) content.setBackgroundColor(BaseColor.YELLOW);
if (String.valueOf(value).contains("绿")) content.setBackgroundColor(BaseColor.GREEN);
}
3.PDF中的Excel的单元格修改字体颜色:
//添加到工具类的PdfPTable方法中的内容集合中去
Font CONTENTFONT = new Font(baseFont, 9, Font.NORMAL);
if (fields[i].getName().equals("Color")) {//定制化的红黄绿颜色
if (String.valueOf(value).contains("红")) CONTENTFONT=new Font(baseFont, 9, Font.NORMAL, BaseColor.RED);
if (String.valueOf(value).contains("黄")) CONTENTFONT=new Font(baseFont, 9, Font.NORMAL, BaseColor.YELLOW);
if (String.valueOf(value).contains("绿")) CONTENTFONT=new Font(baseFont, 9, Font.NORMAL, BaseColor.GREEN);
}
PdfPCell content = getCell(new Paragraph(String.valueOf(value), CONTENTFONT));
4.PDF中的Excel的单元格修改背景图:
//添加到工具类的PdfPTable方法中的内容集合中去
PdfPCell content = getCell(new Paragraph(String.valueOf(value), CONTENTFONT));
// 构造图片
Image image = Image.getInstance(new DefaultResourceLoader().getResource("classpath:static/images/china@2x.png").getURL());
// 设置CellEvent
content.setCellEvent(new ImageBackgroundEvent(image));
// 按比例设置cell高度
content.setFixedHeight(200 * image.getScaledHeight() / image.getScaledWidth());
table.addCell(content);
/**
* 背景图片
*/
static class ImageBackgroundEvent implements PdfPCellEvent {
protected Image image;
public ImageBackgroundEvent(Image image) {
this.image = image;
}
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
try {
PdfContentByte cb = canvases[PdfPTable.BACKGROUNDCANVAS];
image.scaleAbsolute(position.getWidth(), position.getHeight());
image.setAbsolutePosition(position.getLeft(), position.getBottom());
cb.addImage(image);
} catch (DocumentException e) {
throw new ExceptionConverter(e);
}
}
}