Java Itext 生成PDF文件

利用Java Itext生成PDF文件并导出,实现效果如下:

PDFUtil.java

package com.jeeplus.modules.order.util;

import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.jeeplus.common.utils.Encodes;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.modules.order.entity.OrderHeader;
import com.jeeplus.modules.order.entity.OrderLine;
import com.jeeplus.modules.order.service.PDFService;
import com.jeeplus.modules.sys.utils.UserUtils;

public class PDFUtil {

  /**
   *
   * @param exhibitionName 展会名称
   * @param orders 订单
   * @param REMITTANCE_UNIT 收款单位
   * @param REMITTANCE_BANK 收款银行
   * @param REMITTANCE_ACCOUNT 收款账号
   * @param SEAL_PICTURE_NAME 印章名称默认为深圳中智兴
   * @param payUrl 系统网址
   * @param response
   * @throws Exception author:xiaofei.xian 日期:2018年5月30日 上午11:29:57
   */
  public static void createPDF(String exhibitionName, List<OrderHeader> orders, String REMITTANCE_UNIT, String REMITTANCE_BANK,
      String REMITTANCE_ACCOUNT, String SEAL_PICTURE_NAME, String payUrl, HttpServletResponse response) throws Exception {
    // 生成PDF
    Document document = new Document(PageSize.A4);
    BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    Font fontChinese = new Font(bfChinese, 12, Font.NORMAL);
    Font fontMoney = new Font(bfChinese, 13, Font.BOLD, BaseColor.RED);
    Font BlodFont = new Font(bfChinese, 12, Font.BOLD, BaseColor.BLACK);

    // 写入器
    PdfWriter writer = PdfWriter.getInstance(document, response.getOutputStream());
    // 只读
    writer.setEncryption(null, null, PdfWriter.ALLOW_PRINTING, PdfWriter.STANDARD_ENCRYPTION_128);
    // 通过PDF页面事件模式添加文字水印功能
    writer.setPageEvent(new TextWaterMarkPdfPageEvent(REMITTANCE_UNIT));

    // 添加页脚功能
    document.open();
    PdfPTable pdfPTable = new PdfPTable(1);
    PdfFooterEvent footerTable = new PdfFooterEvent(pdfPTable, payUrl);
    footerTable.setTableFooter(writer);
    document.add(pdfPTable);


    // 添加PDF属性
    document.open();
    Paragraph pph1 = new Paragraph("预租确认回执", new Font(bfChinese, 20, Font.BOLD, BaseColor.BLACK));
    pph1.setAlignment(Element.ALIGN_CENTER);
    pph1.setSpacingAfter(10);
    pph1.setSpacingBefore(5);
    document.add(pph1);
    // 6列的表.
    PdfPTable table = new PdfPTable(6);
    table.setTotalWidth(500);
    table.setLockedWidth(true);
    table.setHorizontalAlignment(Element.ALIGN_CENTER);

    // 第一行
    PdfPCell cell1 = new PdfPCell(new Phrase("展会名称:" + exhibitionName, fontChinese));
    cell1.setColspan(6);
    table.addCell(cell1);

    StringBuffer boothNums = new StringBuffer();
    for (OrderHeader orderHeader : orders) {
      // 获取订单信息
      boothNums.append(orderHeader.getExName() + ",");
    }

    // 第二行
    PdfPCell cell2 = new PdfPCell(new Phrase("展位编号:" + boothNums.toString().subSequence(0, boothNums.length() - 1), fontChinese));
    cell2.setColspan(6);
    table.addCell(cell2);

    // 第三行
    PdfPCell cell3 = new PdfPCell(new Phrase("下单人:" + UserUtils.get(orders.get(0).getCreateBy()).getName(), fontChinese));
    cell3.setColspan(6);
    cell3.setHorizontalAlignment(Element.ALIGN_RIGHT);
    table.addCell(cell3);

    // 第四行
    PdfPCell cell4_1 = new PdfPCell(new Phrase("名称", fontChinese));
    PdfPCell cell4_2 = new PdfPCell(new Phrase("规格", fontChinese));
    PdfPCell cell4_3 = new PdfPCell(new Phrase("单价", fontChinese));
    PdfPCell cell4_4 = new PdfPCell(new Phrase("押金", fontChinese));
    PdfPCell cell4_5 = new PdfPCell(new Phrase("数量", fontChinese));
    PdfPCell cell4_6 = new PdfPCell(new Phrase("小计", fontChinese));
    table.addCell(cell4_1);
    table.addCell(cell4_2);
    table.addCell(cell4_3);
    table.addCell(cell4_4);
    table.addCell(cell4_5);
    table.addCell(cell4_6);

    BigDecimal total = BigDecimal.ZERO;

    List<OrderLine> orderLines = new ArrayList<OrderLine>();
    for (OrderHeader orderHeader : orders) {
      orderLines = orderHeader.getOrderLines();
      for (OrderLine orderLine : orderLines) {
        cell4_1 = new PdfPCell(new Phrase(orderLine.getGoodsName(), fontChinese));
        cell4_2 = new PdfPCell(new Phrase(orderLine.getSpecifications(), fontChinese));
        cell4_3 = new PdfPCell(new Phrase(String.valueOf(orderLine.getUnitPrice()), fontChinese));

        DecimalFormat df1 = new DecimalFormat("0.00");
        String str = df1.format(orderLine.getForegift().multiply(orderLine.getBuyNum().subtract(orderLine.getEditForegiftPrice())));
        cell4_4 = new PdfPCell(new Phrase(str, fontChinese));
        cell4_5 = new PdfPCell(new Phrase(String.valueOf(orderLine.getBuyNum()), fontChinese));
        cell4_6 =
            new PdfPCell(new Phrase(String.valueOf((orderLine.getUnitPrice().add(orderLine.getForegift())).multiply(orderLine.getBuyNum())
                .subtract(orderLine.getEditFeePrice().subtract(orderLine.getEditForegiftPrice()))), fontChinese));
        total = total.add((orderLine.getUnitPrice().add(orderLine.getForegift())).multiply(orderLine.getBuyNum())
            .subtract(orderLine.getEditFeePrice().subtract(orderLine.getEditForegiftPrice())));
        table.addCell(cell4_1);
        table.addCell(cell4_2);
        table.addCell(cell4_3);
        table.addCell(cell4_4);
        table.addCell(cell4_5);
        table.addCell(cell4_6);
      }
    }

    // 第六行
    PdfPCell cell6 = new PdfPCell(new Phrase("总计:" + total, fontMoney));
    cell6.setColspan(6);
    table.addCell(cell6);

    // 第七行
    PdfPCell cell7_1 = new PdfPCell(new Phrase("收款单位:", fontChinese));
    PdfPCell cell7_2 = new PdfPCell(new Phrase(REMITTANCE_UNIT, fontChinese));
    cell7_1.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell7_2.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell7_1.setColspan(2);
    cell7_2.setColspan(4);

    table.addCell(cell7_1);
    table.addCell(cell7_2);

    cell7_1 = new PdfPCell(new Phrase("开户行:", fontChinese));
    cell7_2 = new PdfPCell(new Phrase(REMITTANCE_BANK, fontChinese));
    cell7_1.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell7_2.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell7_1.setColspan(2);
    cell7_2.setColspan(4);

    table.addCell(cell7_1);
    table.addCell(cell7_2);

    cell7_1 = new PdfPCell(new Phrase("账号:", fontChinese));
    cell7_2 = new PdfPCell(new Phrase(REMITTANCE_ACCOUNT, fontMoney));
    cell7_1.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell7_2.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell7_1.setColspan(2);
    cell7_2.setColspan(4);

    table.addCell(cell7_1);
    table.addCell(cell7_2);

    // 第十行
    PdfPCell cell10 = new PdfPCell(new Phrase(REMITTANCE_UNIT, fontChinese));
    cell10.setHorizontalAlignment(Element.ALIGN_RIGHT);
    cell10.setColspan(6);
    table.addCell(cell10);

    document.add(table);

    // 默认为深圳中智兴
    if (StringUtils.isEmpty(SEAL_PICTURE_NAME)) {
      SEAL_PICTURE_NAME = "zzx_seal.png";
    }
    // 读入并设置印章图片
    URL resource = PDFService.class.getResource("/sealimg/" + SEAL_PICTURE_NAME);
    Image image = Image.getInstance(resource);
    image.setScaleToFitLineWhenOverflow(true);
    image.setAlignment(Element.ALIGN_RIGHT);
    float x = table.getTotalWidth();
    float y = 750 - table.getTotalHeight();
    while (y < 0) {
      y = 750 - (table.getTotalHeight() - 750);
    }
    image.setAbsolutePosition(x - 60, y);
    image.scaleAbsolute(100, 100);
    PdfContentByte pcb = writer.getDirectContentUnder();
    pcb.addImage(image);
    document.add(image);
    document.add(Chunk.NEWLINE);

    // 特别提醒
    Paragraph paragraphRemark = new Paragraph();
    Font remarkFont = new Font(bfChinese, 10, Font.NORMAL);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    paragraphRemark.add(new Chunk("特别提醒:", BlodFont));
    paragraphRemark.add(Chunk.NEWLINE);
    paragraphRemark.add(new Chunk("1.您的汇款识别码为", remarkFont));
    paragraphRemark.add(new Chunk(orders.get(0).getRemitCode(), fontMoney));
    paragraphRemark.add(new Chunk("。请将此识别码填写到汇款单【附言】栏内(仅填写此识别码),如未填写会影响订单确认时间。", remarkFont));
    paragraphRemark.add(Chunk.NEWLINE);
    paragraphRemark.add(Chunk.NEWLINE);
    paragraphRemark.add(new Chunk("2.请将待支付款项在", remarkFont));
    paragraphRemark.add(new Chunk(sdf.format(orders.get(0).getCancelDate()), fontMoney));
    paragraphRemark.add(new Chunk("前通过银行汇到以上指定账号,请您尽快汇清款项,逾期订单将自动取消,汇款后请等待确认收款,到账周期一般为1-3个工作日。", remarkFont));
    paragraphRemark.add(Chunk.NEWLINE);
    paragraphRemark.add(Chunk.NEWLINE);
    paragraphRemark.add(new Chunk("4.汇款金额请与应付金额保持一致,请勿多汇款或者少汇款。", remarkFont));
    paragraphRemark.add(Chunk.NEWLINE);
    document.add(paragraphRemark);


    sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
    pph1 = new Paragraph("打印日期:" + sdf.format(new Date()), fontChinese);
    pph1.setAlignment(Element.ALIGN_RIGHT);
    pph1.setSpacingBefore(20);
    document.add(pph1);
    response.setContentType("application/pdf; charset=utf-8");
    response.setHeader("Content-Disposition", "attachment; filename=" + Encodes.urlEncode("预租确认回执") + ".pdf");
    document.close();
    writer.close();
    OutputStream out = response.getOutputStream();
    out.flush();
    response.flushBuffer();
  }

}

水印事件TextWaterMarkPdfPageEvent.java

package com.jeeplus.modules.order.util;

import java.io.IOException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * PDF 水印事件
 *
 * @author xiaofei.xian 日期:2018年5月30日 上午11:25:18
 */
public class TextWaterMarkPdfPageEvent extends PdfPageEventHelper {

  private String waterMarkText;

  public TextWaterMarkPdfPageEvent(String waterMarkText) {
    this.waterMarkText = waterMarkText;
  }

  @Override
  public void onEndPage(PdfWriter writer, Document document) {
    try {
      float pageWidth = document.right() + document.left();// 获取pdf内容正文页面宽度
      float pageHeight = document.top() + document.bottom();// 获取pdf内容正文页面高度
      // 设置水印字体格式
      BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
      Font waterMarkFont = new Font(base, 15, Font.BOLD, new BaseColor(230, 230, 230));
      PdfContentByte waterMarkPdfContent = writer.getDirectContentUnder();
      Phrase phrase = new Phrase(waterMarkText, waterMarkFont);
      ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.25f, pageHeight * 0.2f, 45);
      ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.25f, pageHeight * 0.5f, 45);
      ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.25f, pageHeight * 0.8f, 45);
      ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.65f, pageHeight * 0.2f, 45);
      ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.65f, pageHeight * 0.5f, 45);
      ColumnText.showTextAligned(waterMarkPdfContent, Element.ALIGN_CENTER, phrase, pageWidth * 0.65f, pageHeight * 0.8f, 45);
    } catch (DocumentException de) {
      de.printStackTrace();
    } catch (IOException de) {
      de.printStackTrace();
    }
  }
}

页脚事件PdfFooterEvent.java

package com.jeeplus.modules.order.util;

import java.io.IOException;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
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 com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * PDF 页眉事件
 *
 * @author xiaofei.xian 日期:2018年5月30日 上午11:25:00
 */
public class PdfFooterEvent extends PdfPageEventHelper {

  public static PdfPTable footer;

  public static String webUrl;

  public PdfFooterEvent(PdfPTable footer, String webUrl) {
    PdfFooterEvent.footer = footer;
    PdfFooterEvent.webUrl = webUrl;
  }

  @Override
  public void onEndPage(PdfWriter writer, Document document) {
    // 把页脚表格定位
    footer.writeSelectedRows(0, -1, 38, 30, writer.getDirectContent());
  }

  /**
   * 页脚是文字
   *
   * @param writer
   * @param songti09
   * @throws IOException
   * @throws DocumentException
   */
  public void setTableFooter(PdfWriter writer) throws DocumentException, IOException {
    PdfPTable table = new PdfPTable(1);
    table.setTotalWidth(520f);
    PdfPCell cell = new PdfPCell();
    cell.setBorder(1);
    String string =
        "本回执仅做财务付款申请凭证,它用无效                                                                                         网址:" + webUrl;
    BaseFont bfChinese = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    Font FontChinese = new Font(bfChinese, 10, Font.NORMAL);
    FontChinese.setColor(new BaseColor(150, 150, 150));
    Paragraph p = new Paragraph(string, FontChinese);
    cell.setPaddingLeft(10f);
    cell.setPaddingTop(-2f);
    cell.addElement(p);
    table.addCell(cell);
    PdfFooterEvent event = new PdfFooterEvent(table, webUrl);
    writer.setPageEvent(event);
  }
}

猜你喜欢

转载自www.cnblogs.com/rememberme/p/pdf_seal.html