使用itext生成并下载pdf文件

    最近使用itext生成pdf文件并下载,其中涉及到金额的计算,所以代码比较啰嗦点,maven和代码如下:

<!-- iText  -->
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itextpdf</artifactId>
	<version>5.5.11</version>
</dependency>
<dependency>
	<groupId>com.itextpdf</groupId>
	<artifactId>itext-asian</artifactId>
	<version>5.2.0</version>
</dependency>
package com.xxx.controller;

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 lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
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.math.BigDecimal;
import java.nio.charset.StandardCharsets;

@RestController
@AllArgsConstructor
@RequestMapping("/xxxx")
public class ITextController{


  /**
   * 大写数字
   */
  private static final String[] NUMBERS = {"零", "壹", "贰", "叁", "肆", "伍",
    "陆", "柒", "捌", "玖"};

  /**
   * 整数部分的单位
   */
  private static final String[] IUNIT = {"元", "拾", "佰", "仟", "万", "拾", "佰",
    "仟", "亿", "拾", "佰", "仟", "万", "拾", "佰", "仟"};

  /**
   * 小数部分的单位
   */
  private static final String[] DUNIT = {"角", "分", "厘"};

  @RequestMapping(value = "/itext", method = RequestMethod.GET)
  @ResponseBody
  public void importExcel(HttpServletResponse response) throws IOException {
    OutputStream out = null;
    try {
      ByteArrayOutputStream baos = createPdf();
      //设置请求返回类型
      response.setHeader("Content-Disposition", "attachment; filename=" + new String("销售合同.pdf".getBytes(), StandardCharsets.ISO_8859_1));
      response.setContentLength(baos.size());
      out = response.getOutputStream();
      baos.writeTo(out);
      out.flush();
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      out.close();
    }
  }

  public ByteArrayOutputStream createPdf() throws DocumentException, IOException {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    /* 解决中文无法显示:使用iTextAsian.jar包中的字体 */
    BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
    Font font_normal = new Font(baseFont, 10, Font.NORMAL);
    Font font_bold = new Font(baseFont, 10, Font.BOLD);
    /* 第一步 创建文档实例 自定义页面大小使用 */
    Document document = new Document(PageSize.A4);
    /* 第二步 获取PdfWriter实例 */
    PdfWriter.getInstance(document, baos);
    document.setMargins(64, 64, 36, 36);
    /* 第三步 打开文档 */
    document.open();
    /* 第四步 添加段落内容 */
    Paragraph paragraph = new Paragraph("xxx行业应用服务平台\n" + "销售合同", new Font(baseFont, 18, Font.BOLD));
    paragraph.setAlignment(Element.ALIGN_CENTER);
    /* 上一段落与下一段落的间距加大10个单位 */
    paragraph.setSpacingAfter(10);
    document.add(paragraph);
    paragraph = new Paragraph("买方(以下简称“甲方”):", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("卖方(以下简称“乙方”):xxx有限公司", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("根据《中华人民共和国合同法》及相关法律、法规的规定,买卖双方本着友好合作," +
      "达成以下协议:", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("一、产品名称、数量、价格:", font_bold);
    document.add(paragraph);
    /* 生成表格 */
    PdfPTable table = new PdfPTable(8);
    /* 设置表格上面空白宽度 */
    table.setSpacingBefore(10f);
    table.setTotalWidth(new float[]{36, 88, 88, 88, 50, 56, 56, 56});
    /* 锁住宽度 */
    table.setLockedWidth(true);
    /* 添加表头元素 */
    PdfPCell cell = new PdfPCell(new Paragraph("编号", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    cell = new PdfPCell(new Paragraph("名称", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    cell = new PdfPCell(new Paragraph("型号", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    cell = new PdfPCell(new Paragraph("规格", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    cell = new PdfPCell(new Paragraph("单位", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    cell = new PdfPCell(new Paragraph("数量", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    cell = new PdfPCell(new Paragraph("单价(元)", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    cell = new PdfPCell(new Paragraph("总价(元)", font_bold));
    setCellStyle(24, cell);
    table.addCell(cell);
    /* 添加表格的内容 */
    BigDecimal amount = new BigDecimal(0);
    for (int i = 0; i < 5; i++) {
      cell = new PdfPCell(new Paragraph(i + 1 + "", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
      cell = new PdfPCell(new Paragraph("工业互联网标识", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
      cell = new PdfPCell(new Paragraph("304不锈钢、激光雕刻", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
      cell = new PdfPCell(new Paragraph("尺寸:60mm*40mm厚度0.5mm", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
      cell = new PdfPCell(new Paragraph("个", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
      cell = new PdfPCell(new Paragraph(84 + "", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
      cell = new PdfPCell(new Paragraph(12.02 + "", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
      BigDecimal quantity = new BigDecimal(84);
      BigDecimal price = new BigDecimal(12.02 + "");
      BigDecimal total_price = quantity.multiply(price);
      amount = amount.add(total_price);
      cell = new PdfPCell(new Paragraph(total_price + "", font_normal));
      setCellStyle(0, cell);
      table.addCell(cell);
    }
    /* 金额转为大写 */
    String total_RMB = convertAmount(amount.toString());
    /* 表格总价合计 */
    cell = new PdfPCell(new Paragraph("合计人民币(大写):" + total_RMB, font_bold));
    cell.setColspan(8);
    setCellStyle(24, cell);
    table.addCell(cell);
    /* 设置表格下面空白宽度 */
    table.setSpacingAfter(8f);
    document.add(table);
    paragraph = new Paragraph("二、质量要求与技术标准:", font_bold);
    document.add(paragraph);
    paragraph = new Paragraph("执行国家、地方颁发的质量标准和行业标准。供货时附产品说明书、合格证。" +
      "乙方保证提供符合合同所规定的质量、规格、型号等要求的全新设备。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("三、付款及交货:", font_bold);
    document.add(paragraph);
    paragraph = new Paragraph("1、双方签订合同后2个工作日内,乙方开具同等价值发票,甲方付清合同总价款。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("2、乙方收到货款后7个工作日发货。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("3、乙方负责运输并承担运费、甲方负责装卸货费用。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("4、交货地点:双方协议。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("四、设备的包装、发运及运输:", font_bold);
    document.add(paragraph);
    paragraph = new Paragraph("1、乙方应采用满足产品运输要求的包装,以保证货物安全运输。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("2、产品发货24小时内通知甲方。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("五、其他:", font_bold);
    document.add(paragraph);
    paragraph = new Paragraph("1、因乙方原因造成的逾期交货,乙方每天按合同总价的万分之五向对方支付违约金。" +
      "甲方无正当理由拒收的,应向乙方支付合同总价30%的违约金。因不可抗力导致合同无法执行除外。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("2、本协议在履行过程中,如发生争议,双方友好协商解决,如协商不成,双方由先诉方法院管辖。", font_normal);
    document.add(paragraph);
    paragraph = new Paragraph("3、本协议自双方签字/盖章之日起生效。本协议一式四份,甲乙双方各执两份,具有同等法律效力。", font_normal);
    document.add(paragraph);
    /* 生成尾部签字部分的表格 */
    table = new PdfPTable(2);
    /* 设置表格上面空白宽度 */
    table.setSpacingBefore(5f);
    table.setTotalWidth(new float[]{271, 200});
    /* 锁住宽度 */
    table.setLockedWidth(true);
    /* 添加签字部分第一行元素 */
    setSignStyle("甲方:", table, font_normal);
    setSignStyle("乙方:xxx有限公司", table, font_normal);
    /* 添加第二行元素 */
    setSignStyle("地址:", table, font_normal);
    setSignStyle("地址:xxx", table, font_normal);
    /* 添加第三行元素 */
    setSignStyle("法定代表人:", table, font_normal);
    setSignStyle("法定代表人:xxx", table, font_normal);
    /* 添加第四行元素 */
    setSignStyle("授权代表:", table, font_normal);
    setSignStyle("授权代表:", table, font_normal);
    /* 添加第五行元素 */
    setSignStyle("电话:", table, font_normal);
    setSignStyle("电话:xxx", table, font_normal);
    /* 添加第六行元素 */
    setSignStyle("开户行:", table, font_normal);
    setSignStyle("开户行:xxx支行", table, font_normal);
    /* 添加第七行元素 */
    setSignStyle("帐号:", table, font_normal);
    setSignStyle("帐号:xxxx", table, font_normal);
    /* 添加第八行元素 */
    setSignStyle("税号:", table, font_normal);
    setSignStyle("税号:xxxx", table, font_normal);
    /* 添加第九行元素 */
    setSignStyle("          年   月    日", table, font_normal);
    setSignStyle("          年   月    日", table, font_normal);
    document.add(table);
    /* 第五部 操作完成后必须执行文档关闭操作。*/
    document.close();
    return baos;
  }

  private String convertAmount(String str) {
    /* 去掉"," */
    str = str.replaceAll(",", "");
    /* 整数部分数字 */
    String integerStr;
    /* 小数部分数字 */
    String decimalStr;
    /* 初始化:分离整数部分和小数部分 */
    if (str.indexOf(".") > 0) {
      integerStr = str.substring(0, str.indexOf("."));
      decimalStr = str.substring(str.indexOf(".") + 1);
    } else if (str.indexOf(".") == 0) {
      integerStr = "";
      decimalStr = str.substring(1);
    } else {
      integerStr = str;
      decimalStr = "";
    }
    /* integerStr去掉首0,不必去掉decimalStr的尾0(超出部分舍去) */
    if (!integerStr.equals("")) {
      integerStr = Long.toString(Long.parseLong(integerStr));
      if (integerStr.equals("0")) {
        integerStr = "";
      }
    }
    /* overflow超出处理能力,直接返回 */
    if (integerStr.length() > IUNIT.length) {
      System.out.println(str + ":超出处理能力");
      return str;
    }

    /* 整数部分数字 */
    int[] integers = toArray(integerStr);
    /* 设置万单位 */
    boolean isMust5 = isMust5(integerStr);
    /* 小数部分数字 */
    int[] decimals = toArray(decimalStr);
    return getChineseInteger(integers, isMust5)
      + getChineseDecimal(decimals);
  }

  /**
   * 整数部分和小数部分转换为数组,从高位至低位
   */
  private static int[] toArray(String number) {
    int[] array = new int[number.length()];
    for (int i = 0; i < number.length(); i++) {
      array[i] = Integer.parseInt(number.substring(i, i + 1));
    }
    return array;
  }

  /**
   * 得到中文金额的整数部分。
   */
  private static String getChineseInteger(int[] integers, boolean isMust5) {
    StringBuffer chineseInteger = new StringBuffer("");
    int length = integers.length;
    for (int i = 0; i < length; i++) {
      /* 0出现在关键位置:1234(万)5678(亿)9012(万)3456(元) */
      /* 特殊情况:10(拾元、壹拾元、壹拾万元、拾万元) */
      String key = "";
      if (integers[i] == 0) {
        /* 万(亿)(必填) */
        if ((length - i) == 13)
          key = IUNIT[4];
          /* 亿(必填) */
        else if ((length - i) == 9)
          key = IUNIT[8];
          /* 万(不必填) */
        else if ((length - i) == 5 && isMust5)
          key = IUNIT[4];
          /* 元(必填) */
        else if ((length - i) == 1)
          key = IUNIT[0];
        /* 0遇非0时补零,不包含最后一位 */
        if ((length - i) > 1 && integers[i + 1] != 0)
          key += NUMBERS[0];
      }
      chineseInteger.append(integers[i] == 0 ? key
        : (NUMBERS[integers[i]] + IUNIT[length - i - 1]));
    }
    return chineseInteger.toString();
  }

  /**
   * 得到中文金额的小数部分。
   */
  private static String getChineseDecimal(int[] decimals) {
    StringBuffer chineseDecimal = new StringBuffer("");
    for (int i = 0; i < decimals.length; i++) {
      /* 舍去3位小数之后的 */
      if (i == 3)
        break;
      chineseDecimal.append(decimals[i] == 0 ? "" : (NUMBERS[decimals[i]] + DUNIT[i]));
    }
    return chineseDecimal.toString();
  }

  /**
   * 判断第5位数字的单位"万"是否应加。
   */
  private static boolean isMust5(String integerStr) {
    int length = integerStr.length();
    if (length > 4) {
      String subInteger = "";
      if (length > 8) {
        /* 取得从低位数,第5到第8位的字串 */
        subInteger = integerStr.substring(length - 8, length - 4);
      } else {
        subInteger = integerStr.substring(0, length - 4);
      }
      return Integer.parseInt(subInteger) > 0;
    } else {
      return false;
    }
  }

  private void setSignStyle(String str, PdfPTable table, Font font_normal) {
    PdfPCell cell = new PdfPCell(new Paragraph(str, font_normal));
    cell.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell.setBorderColor(BaseColor.WHITE);
    table.addCell(cell);
  }


  private void setCellStyle(int height, PdfPCell cell) {
    /* 单元格高度,0时表示随内容动态显示高度 */
    if (height != 0) {
      cell.setFixedHeight(height);
    }
    cell.setHorizontalAlignment(Element.ALIGN_CENTER);
    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
  }
}

 

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值