PDF生成工具类:
package com.bjsasc.inv.util.pdf;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.bjsasc.inv.core.entity.ApproveLogger;
import com.bjsasc.inv.core.entity.RewardMember;
import com.bjsasc.inv.util.UserUtil;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
public class PDFUtil {
private static final Logger logger = LoggerFactory.getLogger(PDFUtil.class);
public static void exportPDF(SpecialRewardData rewardData,HttpServletResponse response,String userPassword,String ownerPassword) {
try {
Document doc = getDocument(response,userPassword,ownerPassword);
setLogo(doc);
setTitle(doc,rewardData.getRewardTypeName());
setHeadLine(doc);
setBasic(doc,rewardData);
setPassLogo(doc,420,600);
setRewardMember(doc,rewardData.getRewardMemberList());
setApproveLogger(doc,rewardData.getApproveLoggerList());
dashLine(doc,50);
dashLine(doc,3);
doc.close();
} catch (Exception e) {
logger.error("pdf导出异常",e);
}
}
public static void exportPDF(RewardData rewardData,HttpServletResponse response,String userPassword,String ownerPassword) {
try {
Document doc = getDocument(response,userPassword,ownerPassword);
setLogo(doc);
setTitle(doc,rewardData.getRewardTypeName());
setHeadLine(doc);
setBasic(doc,rewardData);
setPassLogo(doc,420,600);
setRewardMember(doc,rewardData.getRewardMemberList());
setApproveLogger(doc,rewardData.getApproveLoggerList());
dashLine(doc,50);
dashLine(doc,3);
doc.close();
} catch (Exception e) {
logger.error("pdf导出异常",e);
}
}
private static void setApproveLogger(Document doc,java.util.List<ApproveLogger> approveLoggerList) throws DocumentException {
PdfPTable approveTable = createTable(new float[] { 40, 120});
approveTable.addCell(createCell("审批流水", titlefont, Element.ALIGN_LEFT, 2, false));
for (ApproveLogger approveLogger : approveLoggerList) {
if(approveLogger.getName().contains("创建")){
approveTable.addCell(createCell("创建人", textfont, Element.ALIGN_LEFT));
approveTable.addCell(createCell(approveLogger.getAssigneeName(), textfont, Element.ALIGN_LEFT));
}else
if(approveLogger.getName().contains("提交")){
approveTable.addCell(createCell("提交人", textfont, Element.ALIGN_LEFT));
approveTable.addCell(createCell(approveLogger.getAssigneeName(), textfont, Element.ALIGN_LEFT));
}else{
approveTable.addCell(createCell(approveLogger.getName(), textfont, Element.ALIGN_LEFT));
approveTable.addCell(createCell("审批人:"+approveLogger.getAssigneeName()+",审批结果:"+(approveLogger.getOpinion().equals("1")?"同意":"拒绝,审批意见"+approveLogger.getComment()), textfont, Element.ALIGN_LEFT));
}
}
doc.add(approveTable);
}
private static void setRewardMember(Document doc,java.util.List<RewardMember> rewardMemberList) throws DocumentException {
PdfPTable detailTable = createTable(new float[] { 40, 60,80,40,120,120});
detailTable.addCell(createCell("奖励明细", headfont, Element.ALIGN_LEFT, 6, false));
detailTable.addCell(createCell("姓名", textfont, Element.ALIGN_CENTER));
detailTable.addCell(createCell("所在部门", textfont, Element.ALIGN_CENTER));
detailTable.addCell(createCell("金额(元)", textfont, Element.ALIGN_CENTER));
detailTable.addCell(createCell("比例(%)", textfont, Element.ALIGN_CENTER));
detailTable.addCell(createCell("银行卡开户行", textfont, Element.ALIGN_CENTER));
detailTable.addCell(createCell("银行卡号", textfont, Element.ALIGN_CENTER));
for (RewardMember rewardMember : rewardMemberList) {
detailTable.addCell(createCell(rewardMember.getMemberName(), textfont));
detailTable.addCell(createCell(rewardMember.getDeptName(), textfont));
detailTable.addCell(createCell(rewardMember.getAmountStr(), textfont));
detailTable.addCell(createCell(rewardMember.getScale(), textfont));
detailTable.addCell(createCell(rewardMember.getAccountBank(), textfont));
detailTable.addCell(createCell(rewardMember.getBankCardNumber(), textfont));
}
doc.add(detailTable);
}
private static void setPassLogo(Document doc,float abosoluteX,float abosoluteY) throws IOException, DocumentException {
try {
ClassPathResource classPathResource = new ClassPathResource("image/pass.png");
InputStream resourceAsStream =classPathResource.getInputStream();
byte[] bytes = IOUtils.toByteArray(resourceAsStream);
Image passImg = Image.getInstance(bytes);
passImg.setAbsolutePosition(abosoluteX, abosoluteY);
passImg.scaleAbsolute(92, 82);
doc.add(passImg);
} catch (IOException e) {
e.printStackTrace();
}
}
private static void setHeadLine(Document doc) throws DocumentException {
dashLine(doc,3);
Paragraph p4 = new Paragraph();
p4.add(new Chunk("打印时间:"+ LocalDateTimeUtil.formatNormal(LocalDateTime.now()),textfont));
p4.add(new Chunk(" "));
p4.add(new Chunk(" 打印账号:"+ UserUtil.getCurrentUser().getName(),textfont));
doc.add(p4);
dashLine(doc,3);
}
private static Paragraph dashLine(Document doc) throws DocumentException {
return dashLine(doc,5);
}
private static Paragraph dashLine(Document doc,float Leading) throws DocumentException {
// 点线
Paragraph p2 = new Paragraph();
p2.add(new Chunk(new DashLineSeparator()));
p2.setLeading(Leading); //行间距
doc.add(p2);
return p2;
}
private static void setTitle(Document doc,String title) throws DocumentException {
Paragraph paragraph = new Paragraph(title, titlefont);
paragraph.setAlignment(1); //设置文字居中 0靠左 1,居中 2,靠右
paragraph.setIndentationLeft(12); //设置左缩进
paragraph.setIndentationRight(12); //设置右缩进
paragraph.setFirstLineIndent(24); //设置首行缩进
paragraph.setLeading(20f); //行间距
paragraph.setSpacingBefore(5f); //设置段落上空白
paragraph.setSpacingAfter(10f); //设置段落下空白
doc.add(paragraph);
}
private static void setLogo(Document doc) throws DocumentException, IOException {
try {
ClassPathResource classPathResource = new ClassPathResource("image/logo.jpg");
InputStream resourceAsStream =classPathResource.getInputStream();
byte[] bytes = IOUtils.toByteArray(resourceAsStream);
Image image = Image.getInstance(bytes);
image.setAbsolutePosition(20, 802);
image.scaleAbsolute(20, 20);
doc.add(image);
} catch (IOException e) {
e.printStackTrace();
}
Chunk engineeringNameChunkTitle = new Chunk(" xxxxx管理平台", titlefont);
doc.add(engineeringNameChunkTitle);
}
private static Document getDocument(HttpServletResponse response,String userPassword,String ownerPassword) throws DocumentException, IOException {
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("奖励审批记录.pdf", "UTF-8"));
//设置纸张
Rectangle rect = new Rectangle(PageSize.A4);
//创建文档实例
Document doc = new Document(rect);
//添加中文字体
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
//设置字体样式
PdfWriter writer = PdfWriter.getInstance(doc, response.getOutputStream());
writer.setEncryption(userPassword.getBytes(),ownerPassword.getBytes(),PdfWriter.ALLOW_PRINTING,PdfWriter.ENCRYPTION_AES_128);
//打开文档
doc.open();
//创建新的一页
doc.newPage();
return doc;
}
private static void setBasic(Document doc,RewardData rewardData) throws DocumentException {
PdfPTable table = createTable(new float[] { 20, 120});
table.addCell(createCell("基础信息", titlefont, Element.ALIGN_LEFT, 2, false));
table.addCell(createCell("项目名称", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getEngineeringName(), textfont, Element.ALIGN_LEFT));
table.addCell(createCell("项目来源", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getProjectSource(), textfont, Element.ALIGN_LEFT));
table.addCell(createCell("承办单位", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getUnit(), textfont, Element.ALIGN_LEFT));
table.addCell(createCell("承担部门", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getDept(), textfont, Element.ALIGN_LEFT));
table.addCell(createCell("经费总数(元)", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getFund(), textfont, Element.ALIGN_LEFT));
if(StringUtils.isNotEmpty(rewardData.getRewardType())){
table.addCell(createCell("奖励类别", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getRewardType(), textfont, Element.ALIGN_LEFT));
}
table.addCell(createCell("申请金额(元)", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getApplyAmount(), textfont, Element.ALIGN_LEFT));
doc.add(table);
}
private static void setBasic(Document doc,SpecialRewardData rewardData) throws DocumentException {
PdfPTable table = createTable(new float[] { 20, 120});
table.addCell(createCell("基础信息", titlefont, Element.ALIGN_LEFT, 2, false));
table.addCell(createCell("奖励名称", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getRewardName(), textfont, Element.ALIGN_LEFT));
table.addCell(createCell("申请金额(元)", textfont, Element.ALIGN_LEFT));
table.addCell(createCell(rewardData.getApplyAmount(), textfont, Element.ALIGN_LEFT));
doc.add(table);
}
// 定义全局的字体静态变量
private static Font titlefont;
private static Font headfont;
private static Font keyfont;
private static Font textfont;
private static Font midfont;
// 最大宽度
private static int maxWidth = 520;
// 静态代码块
static {
try {
// 不同字体(这里定义为同一种字体:包含不同字号、不同style)
BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
titlefont = new Font(bfChinese, 16, Font.BOLD);
headfont = new Font(bfChinese, 14, Font.BOLD);
keyfont = new Font(bfChinese, 10, Font.BOLD);
textfont = new Font(bfChinese, 10, Font.NORMAL);
midfont = new Font(bfChinese, 12, Font.NORMAL);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建单元格(指定字体)
* @param value
* @param font
* @return
*/
public static PdfPCell createCell(String value, Font font) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
cell.setPaddingTop(10.0f);
cell.setPaddingBottom(10.0f);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 创建单元格(指定字体、水平..)
* @param value
* @param font
* @param align
* @return
*/
public static PdfPCell createCell(String value, Font font, int align) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPaddingTop(10.0f);
cell.setPaddingBottom(10.0f);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并)
* @param value
* @param font
* @param align
* @param colspan
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
return cell;
}
/**
* 创建单元格(指定字体、水平居..、单元格跨x列合并、设置单元格内边距)
* @param value
* @param font
* @param align
* @param colspan
* @param boderFlag
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, int colspan, boolean boderFlag) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setColspan(colspan);
cell.setPhrase(new Phrase(value, font));
cell.setPadding(6.0f);
if (!boderFlag) {
cell.setBorder(0);
cell.setPaddingTop(30.0f);
cell.setPaddingBottom(16.0f);
} else if (boderFlag) {
cell.setBorder(0);
cell.setPaddingTop(0.0f);
cell.setPaddingBottom(30.0f);
}
return cell;
}
/**
* 创建单元格(指定字体、水平..、边框宽度:0表示无边框、内边距)
* @param value
* @param font
* @param align
* @param borderWidth
* @param paddingSize
* @param flag
* @return
*/
public static PdfPCell createCell(String value, Font font, int align, float[] borderWidth, float[] paddingSize, boolean flag) {
PdfPCell cell = new PdfPCell();
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
cell.setHorizontalAlignment(align);
cell.setPhrase(new Phrase(value, font));
cell.setBorderWidthLeft(borderWidth[0]);
cell.setBorderWidthRight(borderWidth[1]);
cell.setBorderWidthTop(borderWidth[2]);
cell.setBorderWidthBottom(borderWidth[3]);
cell.setPaddingTop(paddingSize[0]);
cell.setPaddingBottom(paddingSize[1]);
if (flag) {
cell.setColspan(2);
}
return cell;
}
/**------------------------创建表格单元格的方法end----------------------------*/
/**--------------------------创建表格的方法start------------------- ---------*/
/**
* 创建默认列宽,指定列数、水平(居中、右、左)的表格
* @param colNumber
* @param align
* @return
*/
public static PdfPTable createTable(int colNumber, int align) {
PdfPTable table = new PdfPTable(colNumber);
try {
table.setTotalWidth(maxWidth);
table.setLockedWidth(true);
table.setHorizontalAlignment(align);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
/**
* 创建指定列宽、列数的表格
* @param widths
* @return
*/
public static PdfPTable createTable(float[] widths) {
PdfPTable table = new PdfPTable(widths);
try {
table.setTotalWidth(maxWidth);
table.setLockedWidth(true);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.getDefaultCell().setBorder(1);
} catch (Exception e) {
e.printStackTrace();
}
return table;
}
/**
* 创建空白的表格
* @return
*/
public static PdfPTable createBlankTable() {
PdfPTable table = new PdfPTable(1);
table.getDefaultCell().setBorder(0);
table.addCell(createCell("", keyfont));
table.setSpacingAfter(20.0f);
table.setSpacingBefore(20.0f);
return table;
}
/**--------------------------创建表格的方法end------------------- ---------*/
// public static void main(String[] args) {
// exportPDF();
// }
}
水印生成类:
package com.bjsasc.inv.util.pdf;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
public class Watermark extends PdfPageEventHelper {
Font FONT = new Font(Font.FontFamily.HELVETICA, 30, Font.BOLD, new GrayColor(0.95f));
private String waterCont;//水印内容
public Watermark() {
}
public Watermark(String waterCont) {
this.waterCont = waterCont;
}
@Override
public void onEndPage(PdfWriter writer, Document document) {
for(int i=0 ; i<5; i++) {
for(int j=0; j<5; j++) {
ColumnText.showTextAligned(writer.getDirectContentUnder(),
Element.ALIGN_CENTER,
new Phrase(this.waterCont == null ? "REWARD DETAIL" : this.waterCont, FONT),
(50.5f+i*350),
(40.0f+j*150),
writer.getPageNumber() % 2 == 1 ? 45 : -45);
}
}
}
}
虚线生成类:
package com.bjsasc.inv.util.pdf;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.pdf.PdfChunk;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.draw.VerticalPositionMark;
public class DashLineSeparator extends VerticalPositionMark {
/** 线的粗细. */
protected float lineWidth = 0.1f;
/** 线占页面宽度的百分比 */
protected float percentage = 100;
/** 线色. */
protected BaseColor lineColor;
/** 线的对齐方式. */
protected int alignment = Element.ALIGN_BOTTOM;
public DashLineSeparator(float lineWidth, float percentage, BaseColor lineColor, int align, float offset) {
this.lineWidth = lineWidth;
this.percentage = percentage;
this.lineColor = lineColor;
this.alignment = align;
this.offset = offset;
}
/**
* Creates a new instance of the DashLineSeparator class.
*
* @param font the font
*/
public DashLineSeparator(Font font) {
this.lineWidth = PdfChunk.UNDERLINE_THICKNESS * font.getSize();
this.offset = PdfChunk.UNDERLINE_OFFSET * font.getSize();
this.percentage = 100;
this.lineColor = font.getColor();
}
/**
* Creates a new instance of the LineSeparator class with default values:
* lineWidth 1 user unit, width 100%, centered with offset 0.
*/
public DashLineSeparator() {
}
/**
* @see com.itextpdf.text.pdf.draw.DrawInterface#draw(com.itextpdf.text.pdf.PdfContentByte,
* float, float, float, float, float)
*/
public void draw(PdfContentByte canvas, float llx, float lly, float urx, float ury, float y) {
canvas.saveState();
drawLine(canvas, llx, urx, y);
canvas.restoreState();
}
/**
* Draws a horizontal line.
*
* @param canvas the canvas to draw on
* @param leftX the left x coordinate
* @param rightX the right x coordindate
* @param y the y coordinate
*/
public void drawLine(PdfContentByte canvas, float leftX, float rightX, float y) {
float w;
if (getPercentage() < 0)
w = -getPercentage();
else
w = (rightX - leftX) * getPercentage() / 100.0f;
float s;
switch (getAlignment()) {
case Element.ALIGN_LEFT:
s = 0;
break;
case Element.ALIGN_RIGHT:
s = rightX - leftX - w;
break;
default:
s = (rightX - leftX - w) / 2;
break;
}
canvas.setLineWidth(getLineWidth());
if (getLineColor() != null)
canvas.setColorStroke(getLineColor());
canvas.setLineDash(3, 3, 0);
canvas.moveTo(s + leftX, y + offset);
canvas.lineTo(s + w + leftX, y + offset);
canvas.stroke();
}
/**
* Getter for the line width.
*
* @return the thickness of the line that will be drawn.
*/
public float getLineWidth() {
return lineWidth;
}
/**
* Setter for the line width.
*
* @param lineWidth the thickness of the line that will be drawn.
*/
public void setLineWidth(float lineWidth) {
this.lineWidth = lineWidth;
}
/**
* Setter for the width as a percentage of the available width.
*
* @return a width percentage
*/
public float getPercentage() {
return percentage;
}
/**
* Setter for the width as a percentage of the available width.
*
* @param percentage a width percentage
*/
public void setPercentage(float percentage) {
this.percentage = percentage;
}
/**
* Getter for the color of the line that will be drawn.
*
* @return a color
*/
public BaseColor getLineColor() {
return lineColor;
}
/**
* Setter for the color of the line that will be drawn.
*
* @param color a color
*/
public void setLineColor(BaseColor color) {
this.lineColor = color;
}
/**
* Getter for the alignment of the line.
*
* @return an alignment value
*/
public int getAlignment() {
return alignment;
}
/**
* Setter for the alignment of the line.
*
* @param align an alignment value
*/
public void setAlignment(int align) {
this.alignment = align;
}
}
生成的pdf: