java实现在pdf文档上填充内容

时间:2024-02-25 09:20:15

需求:

在合同附件模板上填充内容,生成一个新的合同附件,并可以查看合同附件

思路:

首先在模板文档上设置文本域,根据文本域填充内容,使用itextpdf在pdf上填充内容

1.在pom.xml中加入以下依赖:

<dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.1</version>
        </dependency>
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

2.在application.properties中配置文件模板路径和文件保存路径

conf.uploadContractAttachTemplatePath=D:\\wkgbErp\\upload\\ContractTemplatePath\\\u9644\u4EF6\u4E00 \u623F\u5C4B\u53CA\u79DF\u8D41\u4FE1\u606F\u8868.pdf
conf.saveUploadContractAttachPath=D:\\wkgbErp\\upload\\ContractTemplatePath\\contractAttach\\

3.创建一个service接口:

/**
   * 生成合同附件
   */
  @Override
  public ErrorObject generateContractAttach(String contractId) {
    ErrorObject error = new ErrorObject();
    PdfReader reader;
    FileOutputStream out;
    ByteArrayOutputStream bos;
    PdfStamper stamper;
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
    if (StringUtils.isNotBlank(contractId)) {
      TblContractPre entity = tblContractPreRepository.findByDeedsn(contractId);
      TblIdentify identify = identifyService.findByUid(entity.getUid());
      String fileName = contractId + ".pdf";
      String newPDFPath = saveUploadContractAttachPath + fileName;
      try {
        out = new FileOutputStream(newPDFPath);
        reader = new PdfReader(uploadContractAttachTemplatePath);// 读取pdf模板
        bos = new ByteArrayOutputStream();
        stamper = new PdfStamper(reader, bos);
        AcroFields form = stamper.getAcroFields();
        // java.util.Iterator<String> it = form.getFields().keySet().iterator();
        // while (it.hasNext()) {
        // String name = it.next().toString();
        // // 填写内容部分
        // form.setField(name, identify.getName());
        // }
        // BaseFont.createFont("STSongStd-Light", "UTF-8", false);
        form.setField("liveName", identify.getName());// 租客姓名
        if (entity.getDeedsnStart() != null) {
          form.setField("deedsnStart", dateFormat.format(entity.getDeedsnStart()));// 合同开始时间
        }
        if (entity.getDeedsnEnd() != null) {
          form.setField("deedsnEnd", dateFormat.format(entity.getDeedsnEnd()));// 合同结束时间
        }
        if (entity.getMonthNum() != null) {// 支付方式
          if (entity.getMonthNum() == 1) {
            form.setField("monthNum", "押二     月付");
          }
          if (entity.getMonthNum() == 3) {
            form.setField("monthNum", "押二     季付");
          }
          if (entity.getMonthNum() == 6) {
            form.setField("monthNum", "押二     半年付");
          }
          if (entity.getMonthNum() == 12) {
            form.setField("monthNum", "押二     年付");
          }
        }
        form.setField("roomsn", entity.getRoomsn());// 房源编号
        if (entity.getRental() != null) {
          form.setField("rental", entity.getRental().toString());// 租金
          BigDecimal rental = entity.getRental();
          BigDecimal deposit = rental.multiply(new BigDecimal(2));// 押金=租金*2
          BigDecimal total = rental.multiply(new BigDecimal(12));// 总计
          form.setField("total", total + "元");// 总计
          form.setField("deposit", deposit.toString()); // 押金
        }
        form.setField("houseAddress", entity.getHouseName().replace(";", ""));// 产权地址
        if (entity.getBuildArea() != null) {
          form.setField("buildArea", entity.getBuildArea() + "平米");// 面积
        }

        // 填充租金支付明细
        if (entity.getDeedsnStart() != null) {
          Calendar calendar = Calendar.getInstance();
          calendar.setTime(entity.getDeedsnStart());
          calendar.add(Calendar.DATE, -1);
          Date date = calendar.getTime();
          form.setField("deedsnStart1", dateFormat.format(entity.getDeedsnStart()));
          form.setField("deedsnTime1", dateFormat.format(entity.getDeedsnStart()) + " / " + DateUtil.AddMonth(date, 1));

          form.setField("deedsnStart2", DateUtil.AddMonth(entity.getDeedsnStart(), 1));
          form.setField("deedsnTime2",
              DateUtil.AddMonth(entity.getDeedsnStart(), 1) + " /  " + DateUtil.AddMonth(date, 2));

          form.setField("deedsnStart3", DateUtil.AddMonth(entity.getDeedsnStart(), 2));
          form.setField("deedsnTime3",
              DateUtil.AddMonth(entity.getDeedsnStart(), 2) + " / " + DateUtil.AddMonth(date, 3));

          form.setField("deedsnStart4", DateUtil.AddMonth(entity.getDeedsnStart(), 3));
          form.setField("deedsnTime4",
              DateUtil.AddMonth(entity.getDeedsnStart(), 3) + " / " + DateUtil.AddMonth(date, 4));

          form.setField("deedsnStart5", DateUtil.AddMonth(entity.getDeedsnStart(), 4));
          form.setField("deedsnTime5",
              DateUtil.AddMonth(entity.getDeedsnStart(), 4) + " / " + DateUtil.AddMonth(date, 5));

          form.setField("deedsnStart6", DateUtil.AddMonth(entity.getDeedsnStart(), 5));
          form.setField("deedsnTime6",
              DateUtil.AddMonth(entity.getDeedsnStart(), 5) + " / " + DateUtil.AddMonth(date, 6));

          form.setField("deedsnStart7", DateUtil.AddMonth(entity.getDeedsnStart(), 6));
          form.setField("deedsnTime7",
              DateUtil.AddMonth(entity.getDeedsnStart(), 6) + " / " + DateUtil.AddMonth(date, 7));

          form.setField("deedsnStart8", DateUtil.AddMonth(entity.getDeedsnStart(), 7));
          form.setField("deedsnTime8",
              DateUtil.AddMonth(entity.getDeedsnStart(), 7) + " / " + DateUtil.AddMonth(date, 8));

          form.setField("deedsnStart9", DateUtil.AddMonth(entity.getDeedsnStart(), 8));
          form.setField("deedsnTime9",
              DateUtil.AddMonth(entity.getDeedsnStart(), 8) + " / " + DateUtil.AddMonth(date, 9));

          form.setField("deedsnStart10", DateUtil.AddMonth(entity.getDeedsnStart(), 9));
          form.setField("deedsnTime10",
              DateUtil.AddMonth(entity.getDeedsnStart(), 9) + " / " + DateUtil.AddMonth(date, 10));

          form.setField("deedsnStart11", DateUtil.AddMonth(entity.getDeedsnStart(), 10));
          form.setField("deedsnTime11",
              DateUtil.AddMonth(entity.getDeedsnStart(), 10) + " / " + DateUtil.AddMonth(date, 11));

          form.setField("deedsnStart12", DateUtil.AddMonth(entity.getDeedsnStart(), 11));
          form.setField("deedsnTime12",
              DateUtil.AddMonth(entity.getDeedsnStart(), 11) + " / " + DateUtil.AddMonth(date, 12));
        }

        if (entity.getSignType() != null) {
          if (entity.getSignType() == 0) {
            form.setField("signType1", "true");// 首次签约复选框选中
          }
          if (entity.getSignType() == 1) {
            form.setField("signType2", "true");
          }
        }
        if (entity.getDepositeType() != null) {
          if (entity.getDepositeType() == 0) {
            form.setField("d1", "true");// 首次签约押金复选框选中
          }
          if (entity.getDepositeType() == 1) {
            form.setField("d2", "true");// 首次签约押金复选框选中
          }
        }
        form.setField("c1", "true");// 身份证复选框选中

        if (identify.getSex() != null) {
          if (identify.getSex() == 0) {// 性别
            form.setField("sex", "女");
          }
          if (identify.getSex() == 1) {
            form.setField("sex", "男");
          }
        }
        if (identify.getAge() != null) {
          form.setField("age", identify.getAge().toString());// 年龄
        }
        form.setField("phone", identify.getPhoneNum());// 联系电话
        form.setField("email", entity.getEmail());
        if (StringUtils.isNotBlank(entity.getEmergencyName())) {// 紧急联系人
          form.setField("emergencyName", entity.getEmergencyName());
        }
        if (StringUtils.isNotBlank(entity.getEmergencyPhone())) {// 紧急联系人电话
          form.setField("emergencyPhone", entity.getEmergencyPhone());
        }
        form.setField("certificateNum", identify.getCertificateNum());// 身份证号码
        if (StringUtils.isNotBlank(entity.getCompanyAddr())) {
          form.setField("companyAddr", entity.getCompanyAddr());// 租客通讯地址
        }
        stamper.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true
        stamper.close();
        // Document doc = new Document();
        // PdfCopy copy = new PdfCopy(doc, out);
        // doc.open();
        // PdfImportedPage importPage = copy.getImportedPage(new
        // PdfReader(bos.toByteArray()), 1);
        // copy.addPage(importPage);
        // doc.close();
        out.write(bos.toByteArray());
        out.flush();
        out.close();
        bos.close();
      } catch (FileNotFoundException e1) {
        log.error("{}", e1);
      } catch (IOException e2) {
        log.error("{}", e2);
      } catch (DocumentException e3) {
        log.error("{}", e3);
      }
      // 保存附件文件名
      entity.setFileName(fileName);
      // tblContractPreRepository.save(entity);
      save(entity);
    }
    return error;
  }

4.单元测试

package com.szwoku.gbwk.web.service;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import cn.wkgb.AppConfiguration;
import cn.wkgb.api.service.TblContractPreService;
import cn.wkgb.common.framework.dto.ErrorObject;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AppConfiguration.class)
public class TblContractPreServiceTest {

  @Resource
  private TblContractPreService tblContractPreService;

  @Test
  public void testGenerateContractAttach() {
    ErrorObject error = tblContractPreService.generateContractAttach("PRE-HA180900079");
    log.warn("error= {}", error);
  }
}

5.查看合同接口

/**
   * 查看合同附件
   * 
   * @param fileName
   * @param request
   * @param response
   * @throws Exception
   */
  @RequestMapping(value = { "/viewPdf/{fileName:.+}" })
  public ErrorObject viewPdf(@PathVariable String fileName, final HttpServletResponse request,
      final HttpServletResponse response) throws Exception {
    ErrorObject error = new ErrorObject();
    String ext = StringUtils.substringAfterLast(fileName, ".");
    String path = saveUploadContractAttachPath + fileName;
    logger.debug(path);
    File file = new File(path);
    if (!file.exists()) {
      return error;
    }
    response.reset(); // 非常重要
    if ("pdf".equalsIgnoreCase(ext)) {
      response.setContentType(PDF);
    }
    OutputStream out = response.getOutputStream();
    IOUtils.write(FileUtils.readFileToByteArray(file), out);
    return error;
  }

6.页面

<input type="hidden" value="PRE-HA180900079.pdf" id="contract-btn-attach">
                <a οnclick="sing_view_attach()" class="btn btn-warning radius ml-20 mr-20">查看合同附件</a>

function sing_view_attach(){
    var href=$("#contract-btn-attach").val();
      console.log(href);
      var url= \'/api/upload/viewPdf/\'+href;
      console.log(url);
      if(href ==\'\'|| href == null){
          alert2(\'该在线合同附件链接不存在\');
      }else{
          var index = layer.open({
                type : 2,
                title : \'合同附件查看\',
                content : url,
                area : [\'90%\', \'90%\'],
                shadeClose : false,
                shade : 0.8,
                cancel : function() {

                }
              });
      }
      
}

难点:

在让复选框选中的时候,既要设置文本域的name相同,还要让它的值为true