Ver código fonte

生成预审申请单pdf

master
CMM 1 ano atrás
pai
commit
f7c67bbfea
12 arquivos alterados com 1064 adições e 4 exclusões
  1. +19
    -0
      pmapi/pom.xml
  2. +3
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/Project.java
  3. +140
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/PdfGenerateDTO.java
  4. +140
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfGenerateUtil.java
  5. +153
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfUtils.java
  6. BIN
      pmapi/src/main/resources/template/fileout/c34f631755a04532a0116494fd5f99ac.pdf
  7. BIN
      pmapi/src/main/resources/template/simsun.ttc
  8. +254
    -0
      pmapi/src/main/resources/template/盖章文件.html
  9. +249
    -0
      pmapi/src/main/resources/template/预审申请单.html
  10. BIN
      pmapi/src/main/resources/template/预审申请单.pdf
  11. +82
    -4
      pmapi/src/test/java/com/ningdatech/pmapi/todocenter/TodoCenterTest.java
  12. +24
    -0
      pom.xml

+ 19
- 0
pmapi/pom.xml Ver arquivo

@@ -229,6 +229,25 @@
<groupId>org.springframework.statemachine</groupId>
<artifactId>spring-statemachine-core</artifactId>
</dependency>

<!-- PDF生成 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
</dependency>

</dependencies>
<!-- 打包 -->
<!--配置环境的profile-->


+ 3
- 0
pmapi/src/main/java/com/ningdatech/pmapi/projectlib/model/entity/Project.java Ver arquivo

@@ -309,4 +309,7 @@ public class Project implements Serializable {
@TableField(fill = FieldFill.INSERT_UPDATE)
private Long updateBy;

@ApiModelProperty("项目预审申请单文件ID")
private Long pretrialFileId;

}

+ 140
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/PdfGenerateDTO.java Ver arquivo

@@ -0,0 +1,140 @@
package com.ningdatech.pmapi.todocenter.model.dto;

import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;

/**
* pdf生成实体
*
* @author CMM
* @since 2023/03/13 14:24
*/
@Data
public class PdfGenerateDTO {
@ApiModelProperty("应用ID")
private Long id;

@ApiModelProperty("项目名称")
private String projectName;

@ApiModelProperty("是否临时增补 0:否 1:是")
private String isTemporaryAugment;

@ApiModelProperty("项目负责人")
private String responsibleMan;

@ApiModelProperty("负责人手机号码")
private String responsibleManMobile;

@ApiModelProperty("项目联系人")
private String contactName;

@ApiModelProperty("项目联系人手机号码")
private String contactPhone;

@ApiModelProperty("建设单位名称")
private String buildOrgName;

@ApiModelProperty("建设单位统一社会信用代码")
private String orgCreditCode;

@ApiModelProperty("项目类型 1:建设 2:运维")
private String projectType;

@ApiModelProperty("是否首次新建 0:否 1:是")
private String isFirst;

@ApiModelProperty("项目预算年度")
private Integer projectYear;

@ApiModelProperty("项目建设起止时间")
private String beginAndEndTime;

@ApiModelProperty("四大体系 1:业务应用 2:应用支撑 3:数据资源 4:基础设施")
private String fourSystems;

@ApiModelProperty("是否数字化改革项目 0:否 1:是")
private String isDigitalReform;

@ApiModelProperty("综合业务领域")
private String bizDomain;

@ApiModelProperty("立项依据")
private String buildBasis;


@ApiModelProperty("是否上云 0:否 1:是")
private String isCloud;

private String cloudType;

@ApiModelProperty("等保级别 1:一级 2:二级 3:三级 4:四级 5:五级")
private Integer protectionLevel;

@ApiModelProperty("是否密评 0:否 1:是")
private Integer isSecretComments;

@ApiModelProperty("项目简介")
private String projectIntroduction;

@ApiModelProperty("资金申报情况-申报金额(万元)")
private BigDecimal declareAmount;

@ApiModelProperty("资金申报情况-自有金额(万元)")
private BigDecimal declareHaveAmount;

@ApiModelProperty("资金申报情况-政府投资-本级财政资金(万元)")
private BigDecimal declareGovOwnFinanceAmount;

@ApiModelProperty("资金申报情况-政府投资-上级补助资金(万元)")
private BigDecimal declareGovSuperiorFinanceAmount;

@ApiModelProperty("银行贷款(万元)")
private BigDecimal declareBankLendingAmount;

@ApiModelProperty("其它资金(万元)")
private BigDecimal declareOtherAmount;

@ApiModelProperty("资金分配情况-软件开发(万元)")
private BigDecimal softwareDevelopmentAmount;

@ApiModelProperty("资金分配情况-云资源、硬件购置(万元)")
private BigDecimal cloudHardwarePurchaseAmount;

@ApiModelProperty("资金分配情况-第三方服务(万元)")
private BigDecimal thirdPartyAmount;

@ApiModelProperty("年度支付计划-年度支付计划(万元)")
private BigDecimal annualPlanAmount;

@ApiModelProperty("年度支付计划-自有金额(万元)")
private BigDecimal annualPlanHaveAmount;

@ApiModelProperty("年度支付计划-政府投资-本级财政资金(万元)")
private BigDecimal annualPlanGovOwnFinanceAmount;

@ApiModelProperty("年度支付计划-政府投资-上级补助资金(万元)")
private BigDecimal annualPlanGovSuperiorFinanceAmount;

@ApiModelProperty("年度支付计划-银行贷款(万元)")
private BigDecimal annualPlanBankLendingAmount;

@ApiModelProperty("年度支付计划-其它资金(万元)")
private BigDecimal annualPlanOtherAmount;

@ApiModelProperty("备注")
private String projectRemarks;

@ApiModelProperty("附件-是否开启 false:关闭 true:开启")
private Boolean isAccessories;

@ApiModelProperty("备注-是否开启 false:关闭 true:开启")
private Boolean isRemarks;

@ApiModelProperty("年度支付计划-是否开启 false:关闭 true:开启")
private Boolean isAnnualPlanAmount;

@ApiModelProperty("一地创新全省共享项目-是否开启 false:关闭 true:开启")
private Boolean isInnovateWholeProvinceShare;
}

+ 140
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfGenerateUtil.java Ver arquivo

@@ -0,0 +1,140 @@
package com.ningdatech.pmapi.todocenter.utils;

import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.util.*;

/**
* pdf 生成工具
*
* @author CMM
* @since 2023/03/13 13:41
*/
@Slf4j
public class PdfGenerateUtil {

private PdfGenerateUtil() {
}


/**
* 生成填充了模板参数的pdf
*
* @param templatePdfInputStream 模板pdf流
* @param paramsMap 填充参数
* @return
*/
public static byte[] generatePdf(InputStream templatePdfInputStream,Map<String, Object> paramsMap) throws IOException {
byte[] templatePdfByteArray = readBytes(templatePdfInputStream);
return generatePdf(templatePdfByteArray, paramsMap);
}

/**
* 生成填充了模板参数的pdf
*
* @param templatePdfByteArray 模板pdf字节数组
* @param paramsMap 填充参数
* @return
*/
public static byte[] generatePdf(byte[] templatePdfByteArray, Map<String, Object> paramsMap) {

PdfReader reader = null;
ByteArrayOutputStream bos = null;
try {
//创建书写器,用于往document中书写信息
// 通过本地文件路径获取资源
reader = new PdfReader(templatePdfByteArray);
bos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, bos);

//使用中文字体
BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
ArrayList<BaseFont> fontList = new ArrayList<>();
fontList.add(baseFont);


AcroFields form = stamper.getAcroFields();
form.setSubstitutionFonts(fontList);

for (String fieldName : paramsMap.keySet()) {
if (paramsMap.get(fieldName) == null) {
continue;
}

if (fieldName.indexOf("Image") > 0) {
String imgPath = paramsMap.get(fieldName).toString();
int pageNo = form.getFieldPositions(fieldName).get(0).page;
Rectangle rectangle = form.getFieldPositions(fieldName).get(0).position;
float x = rectangle.getLeft();
float y = rectangle.getTop();
//根据路径读取图片
Image image = Image.getInstance(imgPath);
//获取图片页面
PdfContentByte under = stamper.getOverContent(pageNo);
//图片大小自适应
image.scaleToFit(rectangle.getWidth(), rectangle.getHeight());
//添加图片
image.setAbsolutePosition(x, y - rectangle.getHeight());
under.addImage(image);
} else {
// 设置占位字段
form.setField(fieldName, paramsMap.get(fieldName).toString());
}
}

stamper.setFormFlattening(false);
stamper.close();

} catch (Exception e) {
log.error("通过模板生成PDF失败", e.getMessage());
return null;
} finally {
try {
if (null != reader) {
reader.close();
}
if (null != bos) {
bos.close();
}

} catch (IOException e) {
log.error("close resource error", e.getMessage());
}
}

return bos.toByteArray();
}

/**
* 读取输入流到字节数组
*
* @param in
* @return
* @throws IOException
*/
private static byte[] readBytes(InputStream in) throws IOException {
//读取字节的缓冲
byte[] buffer = new byte[1024];
//最终的数据
byte[] result = new byte[0];
int size = 0;
while ((size = in.read(buffer)) != -1) {
int oldLen = result.length;
byte[] tmp = new byte[oldLen + size];
if (oldLen > 0) {//copy 旧字节
System.arraycopy(result, 0, tmp, 0, oldLen);
}
//copy 新字节
System.arraycopy(buffer, 0, tmp, oldLen, size);

result = tmp;
}
return result;
}
}



+ 153
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/utils/PdfUtils.java Ver arquivo

@@ -0,0 +1,153 @@
package com.ningdatech.pmapi.todocenter.utils;


import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
import com.ningdatech.basic.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;
import java.util.UUID;

/**
* pdf生成工具类
*
* @author CMM
* @since 2023/03/13 17:01
*/
@Slf4j
@Component
public class PdfUtils {
/**
* 生成PDF文件
*
* @return int
* @author CMM
* @since 2023/03/13 17:07
*/
public byte[] generatePdf(InputStream templateHtmlInputStream, Map<String, Object> paramsMap){
FileInputStream inputStream = null;

try {
File directory = new File("");
//pdf输出路径
String absolutePath = directory.getAbsolutePath();
String linkPath = "\\src\\main\\resources";
String filePath = absolutePath + linkPath + "\\template\\fileout";
if(!new File(filePath).exists()){
new File(filePath).mkdir();
}
//字体格式
String FONT = absolutePath + linkPath + "\\template\\simsun.ttc";
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(templateHtmlInputStream, StandardCharsets.UTF_8));
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line);
}
String htmlInfo = stringBuilder.toString();

//替换参数、多个参数多次替换
for (String fieldName : paramsMap.keySet()) {
if (paramsMap.get(fieldName) == null) {
continue;
}
// 设置占位字段
htmlInfo = htmlInfo.replace("#" + fieldName + "#", paramsMap.get(fieldName).toString());
}


//生成临时文件
String htmlFileName = UUID.randomUUID().toString().replace("-","") + ".html";
String htmlFilePath = filePath + File.separator + htmlFileName;
File file = new File(htmlFilePath);
FileOutputStream fop = new FileOutputStream(file);
if (!file.exists()) {
file.createNewFile();
}
byte[] contentInBytes = htmlInfo.getBytes();
fop.write(contentInBytes);
fop.flush();
fop.close();

//生成pdf
String fileName = UUID.randomUUID().toString().replace("-","") + ".pdf";
String pdfFilePath = filePath + File.separator + fileName;
String url = new File(htmlFilePath).toURI().toURL().toString();
OutputStream os = Files.newOutputStream(Paths.get(pdfFilePath));

ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
renderer.layout();
renderer.createPDF(os);
os.flush();
os.close();

inputStream = new FileInputStream(pdfFilePath);

//删除临时文件
File delFile = new File(pdfFilePath);
if(delFile.exists()){
delFile.delete();
}
File delHtmlFile = new File(htmlFilePath);
if(delHtmlFile.exists()){
delHtmlFile.delete();
}
// 返回生成的pdf文件字节数组
return readBytes(inputStream);
} catch (IOException e) {
throw new BizException("生成pdf文件失败!");
} catch (DocumentException e) {
throw new BizException("生成pdf文件失败!");
} finally {
try {
if (null != inputStream) {

inputStream.close();
}
} catch (IOException e) {
log.error("close resource error", e.getMessage());
}
}
}


/**
* 读取输入流到字节数组
*
* @param in
* @return
* @throws IOException
*/
private byte[] readBytes(InputStream in) throws IOException {
//读取字节的缓冲
byte[] buffer = new byte[1024];
//最终的数据
byte[] result = new byte[0];
int size = 0;
while ((size = in.read(buffer)) != -1) {
int oldLen = result.length;
byte[] tmp = new byte[oldLen + size];
if (oldLen > 0) {//copy 旧字节
System.arraycopy(result, 0, tmp, 0, oldLen);
}
//copy 新字节
System.arraycopy(buffer, 0, tmp, oldLen, size);

result = tmp;
}
return result;
}

}

BIN
pmapi/src/main/resources/template/fileout/c34f631755a04532a0116494fd5f99ac.pdf Ver arquivo


BIN
pmapi/src/main/resources/template/simsun.ttc Ver arquivo


+ 254
- 0
pmapi/src/main/resources/template/盖章文件.html Ver arquivo

@@ -0,0 +1,254 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
html,
body {
padding: 0;
margin: 0;
}
.pdf {
margin: 0 auto;
padding: 10px 0 30px;
text-align: center;
}
.title {
padding: 0 0 40px 0;
font-size: 34px;
margin: 40px 0 0 0;
}
.tab {
padding: 0 20px;
}
.projectId {
color: #999999;
text-align: left;
margin-bottom: 8px;
}
.projectId > .time {
float: right;
}

table {
width: 100%;
border-collapse: collapse;
font-size: 16px;
table-layout: fixed;
word-break: break-all;
text-align: left;
}
td {
padding: 15px 8px;
border: 1px solid;
}
.tabTit {
background-color: #eee;
}
.label {
width: 150px;
}
.sealTd {
height: 200px;
position: relative;
}
.seal {
position: absolute;
right: 20px;
bottom: 30px;
width: 150px;
}
.seal > .time {
text-align: right;
}
.content {
height: 150px;
}
.text {
min-height: 150px;
}
</style>
</head>
<body>
<div class="pdf">
<p class="title">
<span></span>
】预审申请单
</p>
<div class="tab">
<p class="projectId">
<span>
项目编号:
<span></span>
</span>
<span class="time"></span>
</p>
<table>
<tbody>
<tr>
<td class="tabTit" colspan="4">项目基本信息</td>
</tr>
<tr>
<td class="label">项目名称</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="label">是否临时增补</td>
<td></td>
<td class="label">是否一地创新全省共享项目</td>
<td></td>
</tr>
<tr>
<td class="label">项目负责人</td>
<td></td>
<td class="label">负责人手机号</td>
<td></td>
</tr>
<tr>
<td class="label">项目联系人</td>
<td></td>
<td class="label">项目联系人手机号</td>
<td></td>
</tr>
<tr>
<td class="label">建设单位</td>
<td></td>
<td class="label">建设单位统一社会信用代码</td>
<td></td>
</tr>
<tr>
<td class="label">项目类型</td>
<td></td>
<td class="label">是否首次新建</td>
<td></td>
</tr>
<tr>
<td class="label">预算年度</td>
<td></td>
<td class="label">建设起止时间</td>
<td></td>
</tr>
<tr>
<td class="label">四大体系</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="label">是否数字化改革项目</td>
<td></td>
<td class="label">综合业务领域</td>
<td></td>
</tr>
<tr>
<td class="label">立项依据</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="label">是否上云</td>
<td></td>
<td class="label">云类型</td>
<td></td>
</tr>
<tr>
<td class="label">项目简介</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="tabTit" colspan="4">资金申报情况</td>
</tr>
<tr>
<td class="label">申报金额</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="label">自有资金</td>
<td></td>
<td class="label">政府投资-本级财政资金</td>
<td></td>
</tr>
<tr>
<td class="label">政府投资-上级补助资金</td>
<td></td>
<td class="label">银行贷款</td>
<td></td>
</tr>
<tr>
<td class="label">自有资金</td>
<td></td>
<td class="label">政府投资-本级财政资金</td>
<td></td>
</tr>
<tr>
<td class="label">其他资金</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="label">2021年计划投资(万元)</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="tabTit" colspan="4">资金分配情况</td>
</tr>
<tr>
<td class="label">软件开发</td>
<td></td>
<td class="label">云资源、硬件购置</td>
<td></td>
</tr>
<tr>
<td class="label">第三方服务</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="tabTit" colspan="4">年度支付计划</td>
</tr>
<tr>
<td class="label">年度支付金额</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="label">自有资金</td>
<td></td>
<td class="label">政府投资-本级财政资金</td>
<td></td>
</tr>
<tr>
<td class="label">政府投资-上级补助资金</td>
<td></td>
<td class="label">银行贷款</td>
<td></td>
</tr>
<tr>
<td class="label">其他资金</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="tabTit" colspan="4">备注</td>
</tr>
<tr>
<td class="label">备注</td>
<td colspan="3"></td>
</tr>
<tr>
<td class="tabTit" colspan="4">单位意见</td>
</tr>
<tr>
<td class="label">本级主管单位意见(盖章)</td>
<td colspan="3" class="text content"></td>
</tr>
<tr>
<td class="label">上级主管单位意见(盖章)</td>
<td colspan="3" class="text content"></td>
</tr>
<tr>
<td class="label">{本地区大数据局的名称}意见(盖章)</td>
<td colspan="3" class="text content"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

+ 249
- 0
pmapi/src/main/resources/template/预审申请单.html Ver arquivo

@@ -0,0 +1,249 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:font-family="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
html,
body {
padding: 0;
margin: 0;
font-family:SimSun;
}
.pdf {
margin: 0 auto;
padding: 10px 0 30px;
text-align: center;
}
.title {
padding: 0 0 40px 0;
font-size: 34px;
margin: 40px 0 0 0;
font-family:SimSun;
}
.tab {
padding: 0 20px;
}
.projectId {
color: #999999;
text-align: left;
margin-bottom: 8px;
}
.projectId > .time {
float: right;
}

table {
width: 100%;
border-collapse: collapse;
font-size: 16px;
table-layout: fixed;
word-break: break-all;
word-wrap: break-word;
text-align: left;
}
td {
padding: 15px 8px;
border: 1px solid;
}
.tabTit {
background-color: #eee;
}
.label {
width: 150px;
}
.sealTd {
height: 200px;
position: relative;
}
.seal {
position: absolute;
right: 20px;
bottom: 30px;
width: 150px;
}
.seal > .time {
text-align: right;
}
.content {
height: 150px;
}
.text {
min-height: 150px;
}
</style>
</head>
<body>
<div class="pdf">
<p class="title">
预审申请单
</p>
<div class="tab">
<p class="projectId">
<span>
项目编号:
<span>#projectNo#</span>
</span>
<span class="time">#time#</span>
</p>
<table>
<tbody>
<tr>
<td class="tabTit" colspan="4">项目基本信息</td>
</tr>
<tr>
<td class="label">项目名称</td>
<td colspan="3" align="center">#projectName#</td>
</tr>
<tr>
<td class="label">是否临时增补</td>
<td align="center">#isTemporaryAugment#</td>
<td class="label">是否一地创新全省共享项目</td>
<td align="center">#isInnovateWholeProvinceShare#</td>
</tr>
<tr>
<td class="label">项目负责人</td>
<td align="center">#responsibleMan#</td>
<td class="label">负责人手机号</td>
<td align="center">#responsibleManMobile#</td>
</tr>
<tr>
<td class="label">项目联系人</td>
<td align="center">#contactName#</td>
<td class="label">项目联系人手机号</td>
<td align="center">#contactPhone#</td>
</tr>
<tr>
<td class="label">建设单位</td>
<td align="center">#buildOrgName#</td>
<td class="label">建设单位统一社会信用代码</td>
<td align="center">#orgCreditCode#</td>
</tr>
<tr>
<td class="label">项目类型</td>
<td align="center">#projectType#</td>
<td class="label">是否首次新建</td>
<td align="center">#isFirst#</td>
</tr>
<tr>
<td class="label">预算年度</td>
<td align="center">#projectYear#</td>
<td class="label">建设起止时间</td>
<td align="center">#beginAndEndTime#</td>
</tr>
<tr>
<td class="label">四大体系</td>
<td colspan="3" align="center">#fourSystems#</td>
</tr>
<tr>
<td class="label">是否数字化改革项目</td>
<td align="center">#isDigitalReform#</td>
<td class="label">综合业务领域</td>
<td align="center">#bizDomain#</td>
</tr>
<tr>
<td class="label">立项依据</td>
<td colspan="3" align="center">#buildBasis#</td>
</tr>
<tr>
<td class="label">是否上云</td>
<td align="center">#isCloud#</td>
<td class="label">云类型</td>
<td align="center">#cloudType#</td>
</tr>
<tr>
<td class="label">项目简介</td>
<td colspan="3" align="center">#projectIntroduction#</td>
</tr>
<tr>
<td class="tabTit" colspan="4">资金申报情况</td>
</tr>
<tr>
<td class="label">申报金额</td>
<td colspan="3" align="center">#declareAmount#</td>
</tr>
<tr>
<td class="label">自有资金</td>
<td align="center">#declareHaveAmount#</td>
<td class="label">政府投资-本级财政资金</td>
<td align="center">#declareGovOwnFinanceAmount#</td>
</tr>
<tr>
<td class="label">政府投资-上级补助资金</td>
<td align="center">#declareGovSuperiorFinanceAmount#</td>
<td class="label">银行贷款</td>
<td align="center">#declareBankLendingAmount#</td>
</tr>
<tr>
<td class="label">其他资金</td>
<td colspan="3" align="center">#declareOtherAmount#</td>
</tr>
<tr>
<td class="label">本年计划投资(万元)</td>
<td colspan="3" align="center">#yearPlanInvest#</td>
</tr>
<tr>
<td class="tabTit" colspan="4">资金分配情况</td>
</tr>
<tr>
<td class="label">软件开发</td>
<td align="center">#softwareDevelopmentAmount#</td>
<td class="label">云资源、硬件购置</td>
<td align="center">#cloudHardwarePurchaseAmount#</td>
</tr>
<tr>
<td class="label">第三方服务</td>
<td colspan="3" align="center">#thirdPartyAmount#</td>
</tr>
<tr>
<td class="tabTit" colspan="4">年度支付计划</td>
</tr>
<tr>
<td class="label">年度支付金额</td>
<td colspan="3" align="center">#annualPlanAmount#</td>
</tr>
<tr>
<td class="label">自有资金</td>
<td align="center">#annualPlanHaveAmount#</td>
<td class="label">政府投资-本级财政资金</td>
<td align="center">#annualPlanGovOwnFinanceAmount#</td>
</tr>
<tr>
<td class="label">政府投资-上级补助资金</td>
<td align="center">#annualPlanGovSuperiorFinanceAmount#</td>
<td class="label">银行贷款</td>
<td align="center">#annualPlanBankLendingAmount#</td>
</tr>
<tr>
<td class="label">其他资金</td>
<td colspan="3" align="center">#annualPlanOtherAmount#</td>
</tr>
<tr>
<td class="tabTit" colspan="4">备注</td>
</tr>
<tr>
<td class="label">备注</td>
<td colspan="3" align="center">#projectRemarks#</td>
</tr>
<tr>
<td class="tabTit" colspan="4">单位意见</td>
</tr>
<tr>
<td class="label">本级主管单位意见(盖章)</td>
<td colspan="3" class="text content"></td>
</tr>
<tr>
<td class="label">上级主管单位意见(盖章)</td>
<td colspan="3" class="text content"></td>
</tr>
<tr>
<td class="label">{本地区大数据局的名称}意见(盖章)</td>
<td colspan="3" class="text content"></td>
</tr>
</tbody>
</table>
</div>
</div>
</body>
</html>

BIN
pmapi/src/main/resources/template/预审申请单.pdf Ver arquivo


+ 82
- 4
pmapi/src/test/java/com/ningdatech/pmapi/todocenter/TodoCenterTest.java Ver arquivo

@@ -1,18 +1,38 @@
package com.ningdatech.pmapi.todocenter;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.ningdatech.basic.model.GenericResult;
import com.ningdatech.basic.util.NdDateUtils;
import com.ningdatech.file.entity.vo.result.FileResultVO;
import com.ningdatech.file.service.FileService;
import com.ningdatech.pmapi.AppTests;
import com.ningdatech.pmapi.projectlib.enumeration.ProjectTypeEnum;
import com.ningdatech.pmapi.projectlib.manage.ProjectLibManage;
import com.ningdatech.pmapi.projectlib.model.entity.Project;
import com.ningdatech.pmapi.projectlib.model.vo.ProjectDetailVO;
import com.ningdatech.pmapi.projectlib.service.IProjectService;
import com.ningdatech.pmapi.staging.enums.MsgTypeEnum;
import com.ningdatech.pmapi.staging.service.INdWorkNoticeStagingService;
import com.ningdatech.pmapi.todocenter.bean.entity.WorkNoticeInfo;
import com.ningdatech.pmapi.todocenter.manage.TodoCenterManage;
import com.ningdatech.pmapi.todocenter.model.dto.PdfGenerateDTO;
import com.ningdatech.pmapi.todocenter.utils.PdfGenerateUtil;
import com.ningdatech.pmapi.todocenter.utils.PdfUtils;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import com.ningdatech.zwdd.client.ZwddClient;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDateTime;
import java.util.concurrent.*;

import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPLATE;
@@ -25,10 +45,6 @@ import static com.ningdatech.pmapi.todocenter.constant.WorkNotice.PASS_MSG_TEMPL
*/
@Slf4j
public class TodoCenterTest extends AppTests {

//@Autowired
//private TaskExecutor executor;

@Autowired
private TodoCenterManage todoCenterManage;
@Autowired
@@ -37,6 +53,14 @@ public class TodoCenterTest extends AppTests {
private ZwddClient zwddClient;
@Autowired
private INdWorkNoticeStagingService workNoticeStagingService;
@Autowired
private ProjectLibManage projectLibManage;
@Autowired
private FileService fileService;
@Autowired
private IProjectService projectService;
@Autowired
private PdfUtils pdfUtils;
@Test
public void sendWorkNoticeTest() throws ExecutionException, InterruptedException {
//String msg = String.format(PASS_MSG_TEMPLATE, "发改委", "0223-00-测试项目");
@@ -98,4 +122,58 @@ public class TodoCenterTest extends AppTests {
// 放入工作通知暂存表中,通过扫表异步发送
workNoticeStagingService.addByWorkNotice(passWorkNoticeInfo, MsgTypeEnum.AUDIT);
}

@Test
public void GeneratePdf(){
// 获取本地目录的pdf模板
String fileName = "预审申请单";
InputStream pdfInputStream =
this.getClass().getClassLoader().getResourceAsStream("template/" + fileName + ".html");
// 获取表单数据
ProjectDetailVO projectDetail = projectLibManage.getProjectDetail(44L);
PdfGenerateDTO pdfGenerateDTO = new PdfGenerateDTO();
BeanUtils.copyProperties(projectDetail, pdfGenerateDTO);
// 设置pdf模板参数
JSONObject paramsMap = JSONObject.parseObject(JSONObject.toJSONString(pdfGenerateDTO));
paramsMap.put("time", NdDateUtils.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm"));
paramsMap.put("isTemporaryAugment", "否");
Integer projectType = projectDetail.getProjectType();
paramsMap.put("projectType", ProjectTypeEnum.getDesc(projectType));
Integer isFirst = projectDetail.getIsFirst();
paramsMap.put("isFirst", "是");
Boolean isInnovateWholeProvinceShare = projectDetail.getIsInnovateWholeProvinceShare();
paramsMap.put("isInnovateWholeProvinceShare", Boolean.TRUE.equals(isInnovateWholeProvinceShare) ? "是" : "否");
String beginTime = projectDetail.getBeginTime();
String endTime = projectDetail.getEndTime();
String beginAndEndTime = beginTime + StrUtil.DASHED + endTime;
paramsMap.put("beginAndEndTime", beginAndEndTime);
Integer fourSystems = projectDetail.getFourSystems();
paramsMap.put("fourSystems", "业务应用");
Integer isDigitalReform = projectDetail.getIsDigitalReform();
paramsMap.put("isDigitalReform", "否");
Integer isCloud = projectDetail.getIsCloud();
paramsMap.put("isCloud", "否");

// 生成pdf字节数组

byte[] pdf = pdfUtils.generatePdf(pdfInputStream, paramsMap);

// 转换成MultipartFile
MultipartFile multipartFile = new MockMultipartFile("file", fileName + ".pdf", "application/pdf", pdf);

// 上传OSS
FileResultVO resultVO = fileService.upload(multipartFile, "default");

// 将返回的文件ID保存到项目库中
Project project = projectService.getById(44L);
project.setPretrialFileId(resultVO.getId());

try {
if (null != pdfInputStream) {
pdfInputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

+ 24
- 0
pom.xml Ver arquivo

@@ -148,6 +148,28 @@
<artifactId>spring-statemachine-core</artifactId>
<version>2.0.1.RELEASE</version>
</dependency>

<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.9</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-itext5</artifactId>
<version>9.0.3</version>
</dependency>

</dependencies>
</dependencyManagement>

@@ -165,6 +187,8 @@
</snapshots>
</repository>
</repositories>


<pluginRepositories>
<!--阿里云代理Spring 插件仓库-->
<pluginRepository>


Carregando…
Cancelar
Salvar