Browse Source

2024-07-31 模版管理的页面优化,修复参数或者formfield为空时的bug;增加参数的描述,二维码 的宽高度配置能力

master
zhousq 2 months ago
parent
commit
c45904c4cc
  1. BIN
      models/wuliaotest01.pdf
  2. 6
      pom.xml
  3. 4124
      sql/winps_20240731.sql
  4. 81
      win-admin/pom.xml
  5. 38
      win-admin/src/main/java/com/win/web/controller/print/WinPrintServerControler.java
  6. 10
      win-print/pom.xml
  7. 12
      win-print/src/main/java/com/win/print/domain/WinPrintModelParams.java
  8. 4
      win-print/src/main/java/com/win/print/util/HTMLConvertUitl.java
  9. 31
      win-print/src/main/java/com/win/print/util/PdfModelUitl.java
  10. 9
      win-print/src/main/resources/mapper/print/WinPrintModelMapper.xml
  11. 34
      win-print/src/main/resources/templates/print/modelmanager/add.html
  12. 46
      win-print/src/main/resources/templates/print/modelmanager/edit.html

BIN
models/wuliaotest01.pdf

Binary file not shown.

6
pom.xml

@ -254,7 +254,11 @@
<version>3.5.3</version>
</dependency>
<!--ureport -->
<dependency>
<groupId>ognl</groupId>
<artifactId>ognl</artifactId>
<version>3.2.21</version>
</dependency>
</dependencies>

4124
sql/winps_20240731.sql

File diff suppressed because one or more lines are too long

81
win-admin/pom.xml

@ -128,5 +128,84 @@
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
<!-- <build>-->
<!-- &lt;!&ndash; jar包名 &ndash;&gt;-->
<!-- <finalName>${project.artifactId}</finalName>-->
<!-- <plugins>-->
<!-- &lt;!&ndash; 分离lib &ndash;&gt;-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-dependency-plugin</artifactId>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>copy-dependencies</id>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>copy-dependencies</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- &lt;!&ndash; 依赖包输出目录,将来不打进jar包里 &ndash;&gt;-->
<!-- <outputDirectory>${project.build.directory}/lib</outputDirectory>-->
<!-- <excludeTransitive>false</excludeTransitive>-->
<!-- <stripVersion>false</stripVersion>-->
<!-- <includeScope>runtime</includeScope>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- &lt;!&ndash; copy资源文件 &ndash;&gt;-->
<!-- <plugin>-->
<!-- <artifactId>maven-resources-plugin</artifactId>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <id>copy-resources</id>-->
<!-- <phase>package</phase>-->
<!-- <goals>-->
<!-- <goal>copy-resources</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <resources>-->
<!-- <resource>-->
<!-- <directory>src/main/resources</directory>-->
<!-- </resource>-->
<!-- </resources>-->
<!-- <outputDirectory>${project.build.directory}/resources</outputDirectory>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- &lt;!&ndash; 打jar包时忽略配置文件 &ndash;&gt;-->
<!-- <plugin>-->
<!-- <groupId>org.apache.maven.plugins</groupId>-->
<!-- <artifactId>maven-jar-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <excludes>-->
<!-- <exclude>**/*.yml</exclude>-->
<!-- <exclude>**/*.xml</exclude>-->
<!-- </excludes>-->
<!-- </configuration>-->
<!-- </plugin>-->
<!-- &lt;!&ndash; spring boot repackage &ndash;&gt;-->
<!-- <plugin>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
<!-- <configuration>-->
<!-- <layout>ZIP</layout>-->
<!-- <includes>-->
<!-- <include>-->
<!-- <groupId>non-exists</groupId>-->
<!-- <artifactId>non-exists</artifactId>-->
<!-- </include>-->
<!-- </includes>-->
<!-- </configuration>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <goals>-->
<!-- <goal>repackage</goal>-->
<!-- </goals>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
<!-- </plugins>-->
<!-- </build>-->
</project>

38
win-admin/src/main/java/com/win/web/controller/print/WinPrintServerControler.java

@ -252,11 +252,15 @@ public class WinPrintServerControler extends BaseController {
log.info("thymeleaf");
Map<String, String> modelData = new HashMap<>();
paramList.forEach(item -> {
String value = Optional.ofNullable(data.getString(item.getParamCode())).orElse("");
if ("QRIMG".equalsIgnoreCase(item.getParamType())) {
String mg = qrCodeService.getBase64QRCodeSrc(data.getString(item.getParamCode()), 172, 172, "png");
if(!value.isEmpty() && !value.isBlank()){
Map<String, String> imageDesc = getImageDesc(item.getParamDesc());
String mg = qrCodeService.getBase64QRCodeSrc(value, Integer.valueOf(imageDesc.get("width")), Integer.valueOf(imageDesc.get("height")), imageDesc.get("type"));
modelData.put(item.getParamCode(), Optional.ofNullable(mg).orElse(""));
}
} else {
modelData.put(item.getParamCode(), Optional.ofNullable(data.getString(item.getParamCode())).orElse(""));
modelData.put(item.getParamCode(), value);
}
});
@ -270,6 +274,27 @@ public class WinPrintServerControler extends BaseController {
}
}
private Map<String,String> getImageDesc(String desc){
JSONObject jsonObject=JSONObject.parseObject(Optional.ofNullable(desc).orElse("{\"width\":\"172\",\"height\":\"172\",\"type\":\"png\"}")) ;
Map<String,String> map=new HashMap<>();
String width="172";
String height = "172";
String type = "png";
try{
if(null!=jsonObject){
width=Optional.ofNullable(jsonObject.getString("width")).orElse("172");
height=Optional.ofNullable(jsonObject.getString("height")).orElse("172");
type=Optional.ofNullable(jsonObject.getString("type")).orElse("png");
}
}catch (NumberFormatException ne){
width="172";
height = "172";
}
map.put("width",width);
map.put("height",height);
map.put("type",type);
return map;
}
/**
* 多以合并
*/
@ -286,11 +311,14 @@ public class WinPrintServerControler extends BaseController {
}else{
Map<String, String> modelData = new HashMap<>();
paramList.forEach(item -> {
String value = Optional.ofNullable(pdata.getString(item.getParamCode())).orElse("");
if ("QRIMG".equalsIgnoreCase(item.getParamType())) {
String mg = qrCodeService.getBase64QRCodeSrc(pdata.getString(item.getParamCode()), 172, 172, "png");
modelData.put(item.getParamCode(), Optional.ofNullable(mg).orElse(""));
if(!value.isEmpty() && !value.isBlank()){
Map<String, String> imageDesc = getImageDesc(item.getParamDesc());
String mg = qrCodeService.getBase64QRCodeSrc(value, Integer.valueOf(imageDesc.get("width")), Integer.valueOf(imageDesc.get("height")), imageDesc.get("type"));
modelData.put(item.getParamCode(), Optional.ofNullable(mg).orElse(""));}
} else {
modelData.put(item.getParamCode(), Optional.ofNullable(pdata.getString(item.getParamCode())).orElse(""));
modelData.put(item.getParamCode(), value);
}
});
HTMLConvertUitl.html2Pdf_thymeleaf(tempFile, modelData, pageSize, modelName, modeTypeSrc, templatePath);

10
win-print/pom.xml

@ -77,6 +77,16 @@
<version>2.2.21</version>
<scope>compile</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>ognl</groupId>-->
<!-- <artifactId>ognl</artifactId>-->
<!-- </dependency>-->
<!-- &lt;!&ndash; https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf &ndash;&gt;-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-thymeleaf</artifactId>-->
<!-- <version>3.3.0</version>-->
<!-- </dependency>-->
</dependencies>

12
win-print/src/main/java/com/win/print/domain/WinPrintModelParams.java

@ -44,7 +44,7 @@ public class WinPrintModelParams extends BaseEntity
private String modelCode;
/** 参数名 */
@Excel(name = "参数")
@Excel(name = "参数编码")
private String paramCode;
/** 参数描述 */
@ -54,6 +54,16 @@ public class WinPrintModelParams extends BaseEntity
/** 参数类型 */
@Excel(name = "参数类型")
private String paramType;
@Excel(name = "参数名称")
private String paramName;
public String getParamName() {
return paramName;
}
public void setParamName(String paramName) {
this.paramName = paramName;
}
public void setTenantId(String tenantId)
{

4
win-print/src/main/java/com/win/print/util/HTMLConvertUitl.java

@ -5,6 +5,7 @@ import cn.hutool.extra.template.Template;
import cn.hutool.extra.template.TemplateConfig;
import cn.hutool.extra.template.TemplateEngine;
import cn.hutool.extra.template.TemplateUtil;
import cn.hutool.extra.template.engine.thymeleaf.ThymeleafEngine;
import com.itextpdf.html2pdf.ConverterProperties;
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.css.apply.ICssApplierFactory;
@ -92,13 +93,14 @@ public class HTMLConvertUitl {
TemplateEngine engine=null;
String templateName=modelName;
if("STRING".equalsIgnoreCase(modelTypeSrc)){
//templateName=modelName;
//templateName="temlateString";
engine = TemplateUtil.createEngine(new TemplateConfig(templateName, TemplateConfig.ResourceMode.STRING));
}else if("CLASS".equalsIgnoreCase(modelTypeSrc)){
engine = TemplateUtil.createEngine(new TemplateConfig("templates/models", TemplateConfig.ResourceMode.CLASSPATH));
}else{
engine = TemplateUtil.createEngine(new TemplateConfig(path, TemplateConfig.ResourceMode.FILE));
}
Template template = engine.getTemplate(templateName);
return template.render(data);
}

31
win-print/src/main/java/com/win/print/util/PdfModelUitl.java

@ -72,16 +72,26 @@ public class PdfModelUitl {
if (ObjectUtil.isNotEmpty(data)) {
paramsList.forEach(item -> {
PdfFormField field = form.getField(item.getParamCode());
if(null!=field) {
field.setFont(defaultFont());
field.setFontSize(12);
if(ObjectUtil.isNotEmpty(field)) {
if ("QRIMG".equals(item.getParamType())) {
//渲染Qr图片
try {
BufferedImage bufferedImage = qrCodeService.generateQRCode(Optional.ofNullable(data.getString(item.getParamCode())).orElse(""), 172, 172);
byte[] pngs = qrCodeService.getImgBuffer("jpeg", bufferedImage);
com.itextpdf.layout.element.Image image=new com.itextpdf.layout.element.Image(ImageDataFactory.create(pngs));
JSONObject jsonObject=JSONObject.parseObject(Optional.ofNullable(item.getParamDesc()).orElse("{\"width\":\"172\",\"height\":\"172\",\"type\":\"png\"}")) ;
int width=172;
int height = 172;
String type = "png";
if(null!=jsonObject){
width=Integer.valueOf(Optional.ofNullable(jsonObject.getString("width")).orElse("172"));
height=Integer.valueOf(Optional.ofNullable(jsonObject.getString("height")).orElse("172"));
type=Optional.ofNullable(jsonObject.getString("type")).orElse("png");
}
BufferedImage bufferedImage = qrCodeService.generateQRCode(Optional.ofNullable(data.getString(item.getParamCode())).orElse(""), width, height);
//byte[] pngs = qrCodeService.getImgBuffer("jpeg", bufferedImage);
//com.itextpdf.layout.element.Image image=new com.itextpdf.layout.element.Image(ImageDataFactory.create(pngs));
Rectangle rtl = field.getWidgets().get(0).getRectangle().toRectangle(); // 获取表单域的xy坐标
com.itextpdf.layout.element.Image image=getImage(field,bufferedImage,rtl);
image.setFixedPosition(rtl.getX(), rtl.getY(),rtl.getWidth()); // 设置图片固定位置
//image.setRelativePosition(rtl.getLeft(),rtl.getTop(), rtl.getRight(),rtl.getBottom());
document.add(image);
@ -182,7 +192,20 @@ public class PdfModelUitl {
canvas.addImage(img, rtl.getX(), rtl.getY(), true);
}
}
///*pdf 模版图片压缩处理*/
private com.itextpdf.layout.element.Image getImage(PdfFormField formField, BufferedImage bufferedImage,Rectangle rtl) throws IOException {
byte[] imgBytes = qrCodeService.getImgBuffer("jpeg", bufferedImage);
if (Float.compare(bufferedImage.getWidth(), rtl.getWidth()) <= 0 && Float.compare(bufferedImage.getHeight(), rtl.getHeight()) <= 0) {// 不处理
return new com.itextpdf.layout.element.Image(ImageDataFactory.create(imgBytes));
} else {
// 压缩图片。计算得到图片放缩的最大比例
float scale = Math.max(bufferedImage.getWidth() / rtl.getWidth(), bufferedImage.getHeight() / rtl.getHeight());
// 压缩图片
Image scale1 = ImgUtil.scale(ImgUtil.toImage(imgBytes), scale);
return new com.itextpdf.layout.element.Image(ImageDataFactory.create(ImgUtil.toBytes(scale1, ImgUtil.IMAGE_TYPE_PNG)));
}
}
/**
* 根据表单域关键字查找当前关键字所在页对象PdfPage
*

9
win-print/src/main/resources/mapper/print/WinPrintModelMapper.xml

@ -44,6 +44,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="paramCode" column="param_code" />
<result property="paramDesc" column="param_desc" />
<result property="paramType" column="param_type" />
<result property="paramName" column="param_name" />
</resultMap>
<sql id="selectWinPrintModelVo">
@ -58,6 +60,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="mType != null and mType != ''"> and m_type = #{mType}</if>
<if test="isDyparam != null and isDyparam != ''"> and is_dyparam = #{isDyparam}</if>
<if test="mTypeSrc != null and mTypeSrc != ''"> and m_type_src = #{mTypeSrc}</if>
</where>
order by created_time desc
</select>
@ -75,7 +78,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where m_code = #{code}
</select>
<select id="selectWinPrintModelParamsList" resultMap="WinPrintModelParamsResult">
select tenant_id, revision, created_by, created_time, updated_by, updated_time, id, model_code, param_code, param_desc, param_type
select tenant_id, revision, created_by, created_time, updated_by, updated_time, id, model_code, param_code, param_desc, param_type,param_name
from win_print_model_params
where model_code = #{m_code}
</select>
@ -167,9 +170,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete>
<insert id="batchWinPrintModelParams">
insert into win_print_model_params( tenant_id, revision, created_by, created_time, updated_by, updated_time, id, model_code, param_code, param_desc, param_type) values
insert into win_print_model_params( tenant_id, revision, created_by, created_time, updated_by, updated_time, id, model_code, param_code, param_desc, param_type,param_name) values
<foreach item="item" index="index" collection="list" separator=",">
( #{item.tenantId}, #{item.revision}, #{item.createdBy}, #{item.createdTime}, #{item.updatedBy}, #{item.updatedTime}, #{item.id}, #{item.modelCode}, #{item.paramCode}, #{item.paramDesc}, #{item.paramType})
( #{item.tenantId}, #{item.revision}, #{item.createdBy}, #{item.createdTime}, #{item.updatedBy}, #{item.updatedTime}, #{item.id}, #{item.modelCode}, #{item.paramCode}, #{item.paramDesc}, #{item.paramType}, #{item.paramName})
</foreach>
</insert>

34
win-print/src/main/resources/templates/print/modelmanager/add.html

@ -46,7 +46,7 @@
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">文件名称:</label>
<label class="col-sm-3 control-label is-required">文件名称:</label>
<div class="col-sm-8">
<input name="mFilename" id="mFilename" iclass="form-control" type="text" required>
</div>
@ -64,8 +64,8 @@
<div class="form-group" id="editordiv" style="display: none">
<label class="col-sm-3 control-label">模版内容:</label>
<div class="col-sm-8">
<script id="editor" name="mData" type="text/plain" style="height: 300px;" ></script>
<textarea id="mData" style="display: none;">[[*{mData}]]</textarea>
<!-- <script id="editor" name="mData" type="text/plain" style="height: 300px;" ></script>-->
<textarea id="mData" style="min-height: 320px;min-width: 480px;" ></textarea>
</div>
</div>
</div>
@ -121,7 +121,7 @@
</form>
</div>
<th:block th:include="~{include :: footer}" />
<th:block th:include="~{include :: ueditor-js}" />
<!-- <th:block th:include="~{include :: ueditor-js}" />-->
<th:block th:include="~{include :: bootstrap-fileinput-js}" />
<script th:inline="javascript">
var prefix = ctx + "print/modelmanager"
@ -129,13 +129,13 @@
$("#form-modelmanager-add").validate({
focusCleanup: true
});
$(function () {
var text = $("#mData").text();
var ue = UE.getEditor('editor');
ue.ready(function () {
ue.setContent(text);
});
})
// $(function () {
// var text = $("#mData").text();
// var ue = UE.getEditor('editor');
// ue.ready(function () {
// ue.setContent(text);
// });
// })
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/add", $('#form-modelmanager-add').serialize());
@ -180,12 +180,22 @@
{
field: 'paramCode',
align: 'center',
title: '参数',
title: '参数编码',
formatter: function(value, row, index) {
var html = $.common.sprintf("<input class='form-control' type='text' name='winPrintModelParamsList[%s].paramCode' value='%s'>", index, value);
return html;
}
},
{
field: 'paramName',
align: 'center',
title: '参数名',
formatter: function(value, row, index) {
var html = $.common.sprintf("<input class='form-control' type='text' name='winPrintModelParamsList[%s].paramName' value='%s'>", index, value);
return html;
}
},
{
field: 'paramDesc',
align: 'center',

46
win-print/src/main/resources/templates/print/modelmanager/edit.html

@ -38,7 +38,7 @@
<div class="form-group">
<label class="col-sm-3 control-label is-required">模版来源:</label>
<div class="col-sm-8">
<select name="mTypeSrc" class="form-control" th:with="type=${@dict.getType('model_type_src')}" required>
<select name="mTypeSrc" class="form-control" th:with="type=${@dict.getType('model_type_src')}" required th:disabled="true">
<option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{mTypeSrc}"></option>
</select>
</div>
@ -46,21 +46,21 @@
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label">文件名称:</label>
<label class="col-sm-3 control-label is-required">文件名称:</label>
<div class="col-sm-8">
<input name="mFilename" th:field="*{mFilename}" class="form-control" type="text" required>
</div>
</div>
</div>
<!-- <div class="col-xs-12">-->
<!-- <div class="form-group">-->
<!-- <label class="col-sm-3 control-label">模版内容:</label>-->
<!-- <div class="col-sm-8">-->
<div class="col-xs-12">
<div class="form-group" th:if="${winPrintModel.mTypeSrc == 'STRING'}">
<label class="col-sm-3 control-label">模版内容:</label>
<div class="col-sm-8" >
<!-- <script id="editor" name="mData" type="text/plain" style="height: 300px;" ></script>-->
<!-- <textarea id="mData" style="display: none;">[[*{mData}]]</textarea>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
<textarea id="mData" style="min-height: 320px;min-width: 480px;" th:field="*{mData}" ></textarea>
</div>
</div>
</div>
<div class="col-xs-12">
<div class="form-group">
<label class="col-sm-3 control-label is-required">纸张类型:</label>
@ -113,20 +113,20 @@
</form>
</div>
<th:block th:include="include :: footer" />
<th:block th:include="~{include :: ueditor-js}" />
<!-- <th:block th:include="~{include :: ueditor-js}" />-->
<script th:inline="javascript">
var prefix = ctx + "print/modelmanager";
var paramTypeDatas = [[${@dict.getType('param_type')}]];
$("#form-modelmanager-edit").validate({
focusCleanup: true
});
$(function () {
var text = $("#mData").text();
var ue = UE.getEditor('editor');
ue.ready(function () {
ue.setContent(text);
});
})
// $(function () {
// var text = $("#mData").text();
// var ue = UE.getEditor('editor');
// ue.ready(function () {
// ue.setContent(text);
// });
// })
function submitHandler() {
if ($.validate.form()) {
$.operate.save(prefix + "/edit", $('#form-modelmanager-edit').serialize());
@ -163,7 +163,15 @@
return html;
}
},
{
field: 'paramName',
align: 'center',
title: '参数名',
formatter: function(value, row, index) {
var html = $.common.sprintf("<input class='form-control' type='text' name='winPrintModelParamsList[%s].paramName' value='%s'>", index, value);
return html;
}
},
{
field: 'paramDesc',
align: 'center',

Loading…
Cancel
Save