@@ -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--> | |||
@@ -309,4 +309,7 @@ public class Project implements Serializable { | |||
@TableField(fill = FieldFill.INSERT_UPDATE) | |||
private Long updateBy; | |||
@ApiModelProperty("项目预审申请单文件ID") | |||
private Long pretrialFileId; | |||
} |
@@ -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; | |||
} |
@@ -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; | |||
} | |||
} | |||
@@ -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; | |||
} | |||
} |
@@ -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> |
@@ -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> |
@@ -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(); | |||
} | |||
} | |||
} |
@@ -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> | |||