diff --git a/pom.xml b/pom.xml index 0ecaea17..4b97c410 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,11 @@ 4.0.6.B 2.14.2 5.8.20 + 1.9.1 + 2.1.7 + 1.6.0-beta1 + 1.0 + 5.5.13 @@ -225,6 +230,48 @@ ${yanzhu.version} + + + com.lowagie + itext + ${lowagie.version} + + + + com.lowagie + itext-rtf + ${lowagie.version} + + + + com.deepoove + poi-tl + ${poi-tl.version} + + + + + + org.aspectj + aspectjweaver + ${aspectjweaver.version} + + + + com.aspose + aspose-words + 15.8.0 + + + + + + com.itextpdf + itextpdf + ${itextpdf.version} + + + net.sf.mpxj mpxj diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/BasSignet.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/BasSignet.java new file mode 100644 index 00000000..5ca234c0 --- /dev/null +++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/BasSignet.java @@ -0,0 +1,126 @@ +package com.yanzhu.manage.domain; + +import com.yanzhu.common.core.annotation.Excel; +import com.yanzhu.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 业务签名管理对象 bas_signet + * + * @author JiangYuQi + * @date 2024-12-17 + */ +public class BasSignet extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 公司主键 */ + @Excel(name = "公司主键") + private Long comId; + + /** 项目主键 */ + @Excel(name = "项目主键") + private Long projectId; + + /** 用户主键 */ + @Excel(name = "用户主键") + private Long userId; + + /** 签名地址 */ + @Excel(name = "签名地址") + private String signetPath; + + /** 签名使用次数 */ + @Excel(name = "签名使用次数") + private Long signetNumber; + + /** 删除标识 */ + @Excel(name = "删除标识") + private Long isDel; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setComId(Long comId) + { + this.comId = comId; + } + + public Long getComId() + { + return comId; + } + public void setProjectId(Long projectId) + { + this.projectId = projectId; + } + + public Long getProjectId() + { + return projectId; + } + public void setUserId(Long userId) + { + this.userId = userId; + } + + public Long getUserId() + { + return userId; + } + public void setSignetPath(String signetPath) + { + this.signetPath = signetPath; + } + + public String getSignetPath() + { + return signetPath; + } + public void setSignetNumber(Long signetNumber) + { + this.signetNumber = signetNumber; + } + + public Long getSignetNumber() + { + return signetNumber; + } + public void setIsDel(Long isDel) + { + this.isDel = isDel; + } + + public Long getIsDel() + { + return isDel; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("comId", getComId()) + .append("projectId", getProjectId()) + .append("userId", getUserId()) + .append("signetPath", getSignetPath()) + .append("signetNumber", getSignetNumber()) + .append("isDel", getIsDel()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/BasTemplate.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/BasTemplate.java new file mode 100644 index 00000000..e9439b72 --- /dev/null +++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/domain/BasTemplate.java @@ -0,0 +1,126 @@ +package com.yanzhu.manage.domain; + +import com.yanzhu.common.core.annotation.Excel; +import com.yanzhu.common.core.web.domain.BaseEntity; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 业务模板管理对象 bas_template + * + * @author JiangYuQi + * @date 2024-12-17 + */ +public class BasTemplate extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 主键 */ + private Long id; + + /** 公司主键 */ + @Excel(name = "公司主键") + private Long comId; + + /** 项目主键 */ + @Excel(name = "项目主键") + private Long projectId; + + /** 模板名称 */ + @Excel(name = "模板名称") + private String temName; + + /** 模板类型 */ + @Excel(name = "模板类型") + private String temType; + + /** 模板地址 */ + @Excel(name = "模板地址") + private String temPath; + + /** 删除标识 */ + @Excel(name = "删除标识") + private Long isDel; + + public void setId(Long id) + { + this.id = id; + } + + public Long getId() + { + return id; + } + public void setComId(Long comId) + { + this.comId = comId; + } + + public Long getComId() + { + return comId; + } + public void setProjectId(Long projectId) + { + this.projectId = projectId; + } + + public Long getProjectId() + { + return projectId; + } + public void setTemName(String temName) + { + this.temName = temName; + } + + public String getTemName() + { + return temName; + } + public void setTemType(String temType) + { + this.temType = temType; + } + + public String getTemType() + { + return temType; + } + public void setTemPath(String temPath) + { + this.temPath = temPath; + } + + public String getTemPath() + { + return temPath; + } + public void setIsDel(Long isDel) + { + this.isDel = isDel; + } + + public Long getIsDel() + { + return isDel; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("comId", getComId()) + .append("projectId", getProjectId()) + .append("temName", getTemName()) + .append("temType", getTemType()) + .append("temPath", getTemPath()) + .append("isDel", getIsDel()) + .append("createBy", getCreateBy()) + .append("createTime", getCreateTime()) + .append("updateBy", getUpdateBy()) + .append("updateTime", getUpdateTime()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/BasSignetMapper.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/BasSignetMapper.java new file mode 100644 index 00000000..2e5ce8f4 --- /dev/null +++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/BasSignetMapper.java @@ -0,0 +1,61 @@ +package com.yanzhu.manage.mapper; + +import java.util.List; +import com.yanzhu.manage.domain.BasSignet; + +/** + * 业务签名管理Mapper接口 + * + * @author JiangYuQi + * @date 2024-12-17 + */ +public interface BasSignetMapper +{ + /** + * 查询业务签名管理 + * + * @param id 业务签名管理主键 + * @return 业务签名管理 + */ + public BasSignet selectBasSignetById(Long id); + + /** + * 查询业务签名管理列表 + * + * @param basSignet 业务签名管理 + * @return 业务签名管理集合 + */ + public List selectBasSignetList(BasSignet basSignet); + + /** + * 新增业务签名管理 + * + * @param basSignet 业务签名管理 + * @return 结果 + */ + public int insertBasSignet(BasSignet basSignet); + + /** + * 修改业务签名管理 + * + * @param basSignet 业务签名管理 + * @return 结果 + */ + public int updateBasSignet(BasSignet basSignet); + + /** + * 删除业务签名管理 + * + * @param id 业务签名管理主键 + * @return 结果 + */ + public int deleteBasSignetById(Long id); + + /** + * 批量删除业务签名管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteBasSignetByIds(Long[] ids); +} diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/BasTemplateMapper.java b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/BasTemplateMapper.java new file mode 100644 index 00000000..5ee2eb1e --- /dev/null +++ b/yanzhu-common/yanzhu-common-mapper/src/main/java/com/yanzhu/manage/mapper/BasTemplateMapper.java @@ -0,0 +1,61 @@ +package com.yanzhu.manage.mapper; + +import java.util.List; +import com.yanzhu.manage.domain.BasTemplate; + +/** + * 业务模板管理Mapper接口 + * + * @author JiangYuQi + * @date 2024-12-17 + */ +public interface BasTemplateMapper +{ + /** + * 查询业务模板管理 + * + * @param id 业务模板管理主键 + * @return 业务模板管理 + */ + public BasTemplate selectBasTemplateById(Long id); + + /** + * 查询业务模板管理列表 + * + * @param basTemplate 业务模板管理 + * @return 业务模板管理集合 + */ + public List selectBasTemplateList(BasTemplate basTemplate); + + /** + * 新增业务模板管理 + * + * @param basTemplate 业务模板管理 + * @return 结果 + */ + public int insertBasTemplate(BasTemplate basTemplate); + + /** + * 修改业务模板管理 + * + * @param basTemplate 业务模板管理 + * @return 结果 + */ + public int updateBasTemplate(BasTemplate basTemplate); + + /** + * 删除业务模板管理 + * + * @param id 业务模板管理主键 + * @return 结果 + */ + public int deleteBasTemplateById(Long id); + + /** + * 批量删除业务模板管理 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteBasTemplateByIds(Long[] ids); +} diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/BasSignetMapper.xml b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/BasSignetMapper.xml new file mode 100644 index 00000000..b63eaab7 --- /dev/null +++ b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/BasSignetMapper.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + select id, com_id, project_id, user_id, signet_path, signet_number, is_del, create_by, create_time, update_by, update_time, remark from bas_signet + + + + + + + + insert into bas_signet + + com_id, + project_id, + user_id, + signet_path, + signet_number, + is_del, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{comId}, + #{projectId}, + #{userId}, + #{signetPath}, + #{signetNumber}, + #{isDel}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update bas_signet + + com_id = #{comId}, + project_id = #{projectId}, + user_id = #{userId}, + signet_path = #{signetPath}, + signet_number = #{signetNumber}, + is_del = #{isDel}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from bas_signet where id = #{id} + + + + delete from bas_signet where id in + + #{id} + + + \ No newline at end of file diff --git a/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/BasTemplateMapper.xml b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/BasTemplateMapper.xml new file mode 100644 index 00000000..0e01f3b2 --- /dev/null +++ b/yanzhu-common/yanzhu-common-mapper/src/main/resources/mapper/manage/BasTemplateMapper.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + select id, com_id, project_id, tem_name, tem_type, tem_path, is_del, create_by, create_time, update_by, update_time, remark from bas_template + + + + + + + + insert into bas_template + + com_id, + project_id, + tem_name, + tem_type, + tem_path, + is_del, + create_by, + create_time, + update_by, + update_time, + remark, + + + #{comId}, + #{projectId}, + #{temName}, + #{temType}, + #{temPath}, + #{isDel}, + #{createBy}, + #{createTime}, + #{updateBy}, + #{updateTime}, + #{remark}, + + + + + update bas_template + + com_id = #{comId}, + project_id = #{projectId}, + tem_name = #{temName}, + tem_type = #{temType}, + tem_path = #{temPath}, + is_del = #{isDel}, + create_by = #{createBy}, + create_time = #{createTime}, + update_by = #{updateBy}, + update_time = #{updateTime}, + remark = #{remark}, + + where id = #{id} + + + + delete from bas_template where id = #{id} + + + + delete from bas_template where id in + + #{id} + + + \ No newline at end of file diff --git a/yanzhu-modules/yanzhu-manage/pom.xml b/yanzhu-modules/yanzhu-manage/pom.xml index 54df4d83..90d705ca 100644 --- a/yanzhu-modules/yanzhu-manage/pom.xml +++ b/yanzhu-modules/yanzhu-manage/pom.xml @@ -91,6 +91,54 @@ compile + + + com.lowagie + itext + + + + com.lowagie + itext-rtf + + + + com.lowagie + iTextAsian + 1.0 + + + + com.deepoove + poi-tl + + + + + + org.aspectj + aspectjweaver + + + + com.aspose + aspose-words + + + + + + com.itextpdf + itextpdf + + + + + org.jsoup + jsoup + 1.17.2 + + com.aspose aspose-tasks @@ -98,11 +146,7 @@ system ${pom.basedir}\libs\aspose-tasks-24.10-jdk17.jar - - org.jsoup - jsoup - 1.17.2 - + diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/config/ProfileConfig.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/config/ProfileConfig.java index da802378..f79213f5 100644 --- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/config/ProfileConfig.java +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/config/ProfileConfig.java @@ -2,6 +2,7 @@ package com.yanzhu.manage.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; /** @@ -14,4 +15,16 @@ public class ProfileConfig { private String path; + public static String profile = "/statics"; + + public static String profilePath; + + /** + * 初始化... + * @author JiangYuQi + */ + @Bean + public void initProfileConfig() { + profilePath = path; + } } diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/config/SystemUtils.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/config/SystemUtils.java new file mode 100644 index 00000000..30aca37e --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/config/SystemUtils.java @@ -0,0 +1,33 @@ +package com.yanzhu.manage.config; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.stereotype.Component; + +import java.util.Objects; + +@Data +@Component +@ConfigurationProperties(prefix = "spring.profiles") +public class SystemUtils { + + private String active; + + /** + * 当前环境参数 + * @author JiangYuQi + */ + public static boolean isLinux = Boolean.FALSE; + + /** + * 初始化... + * @author JiangYuQi + */ + @Bean + public void initSettings() { + if(!Objects.equals("dev",active)){ + isLinux = true; + } + } +} diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProPlanController.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProPlanController.java index 45184e46..4a25cbba 100644 --- a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProPlanController.java +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/controller/ProPlanController.java @@ -1,20 +1,8 @@ package com.yanzhu.manage.controller; -import java.io.File; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.io.IOException; -import java.util.UUID; -import javax.servlet.http.HttpServletResponse; - -import com.alibaba.fastjson2.util.DateUtils; import com.aspose.tasks.Project; -import com.aspose.tasks.TableCollection; import com.aspose.tasks.Task; import com.aspose.tasks.TaskCollection; -import com.yanzhu.common.core.utils.poi.ExcelUtil; import com.yanzhu.common.core.web.controller.BaseController; import com.yanzhu.common.core.web.domain.AjaxResult; import com.yanzhu.common.core.web.page.TableDataInfo; @@ -23,18 +11,15 @@ import com.yanzhu.common.log.enums.BusinessType; import com.yanzhu.common.security.annotation.RequiresPermissions; import com.yanzhu.manage.domain.ProPlan; import com.yanzhu.manage.service.IProPlanService; -import lombok.SneakyThrows; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + /** * 计划管理Controller diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/FileUtil.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/FileUtil.java new file mode 100644 index 00000000..c776c463 --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/FileUtil.java @@ -0,0 +1,321 @@ +package com.yanzhu.manage.utils.pdf; + +import java.io.*; +import java.text.DecimalFormat; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +/** + * //////////////////////////////////////////////////////////////////// + * // _ooOoo_ + * // o8888888o + * // 88" . "88 + * // (| ^_^ |) + * // O\ = /O + * // ____/`---'\____ + * // .' \\| |// `. + * // / \\||| : |||// \ + * // / _||||| -:- |||||- \ + * // | | \\\ - /// | | + * // | \_| ''\---/'' | | + * // \ .-\__ `-` ___/-. / + * // ___`. .' /--.--\ `. . ___ + * // ."" '< `.___\_<|>_/___.' >'"". + * // | | : `- \`.;`\ _ /`;.`/ - ` : | | + * // \ \ `-. \_ __\ /__ _/ .-` / / + * // ========`-.____`-.___\_____/___.-`____.-'======== + * // `=---=' + * // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * // 佛祖保佑 永无BUG 永不修改 + * //////////////////////////////////////////////////////////////////// + * + * @ClassName FileUtil + * @Description 文件工具 + * @Author JiangYuQi + * @DateTime 2021/6/8 16:50 + * @Version 1.0 + */ +public class FileUtil +{ + // 默认设置文件缓存大小 5M + private static final int BUFFER_SIZE = 5 * 1024; + + /** + * @功能简介:获取文件大小 + * @应用页面: + * @作者姓名:JiangYuQi + * @创建时间:2014年10月16日 下午6:56:12 + * @param f 文件对象File对象 + * @return:long型的字节数 + * @throws Exception + * : + */ + public static long getFileSizes(File f) throws Exception + { + long s = 0; + if (f.exists()) + { + FileInputStream fis = null; + fis = org.apache.commons.io.FileUtils.openInputStream(f); + s = fis.available(); + fis.close(); + } + else + { + f.createNewFile(); + //System.out.println("文件不存在"); + } + return s; + } + + /** + * @功能简介:判断是否存在该目录,不存在则创建 + * @应用页面: + * @作者姓名:JiangYuQi + * @创建时间:2014年10月16日 下午6:57:56 + * @param path + * : + */ + public static void createDirectiory(String path) + { + File dir = org.apache.commons.io.FileUtils.getFile(path); + if (!dir.exists() && !dir.isDirectory()) + { + dir.mkdirs(); + } + } + + /** + * @功能简介:获取文件夹里面所有文件的大小 + * @应用页面: + * @作者姓名:JiangYuQi + * @创建时间:2014年10月16日 下午6:58:33 + * @param f + * @return + * @throws Exception + * : + */ + public static long getFileSize(File f) throws Exception + { + long size = 0; + File flist[] = f.listFiles(); + for (int i = 0; i < flist.length; i++) + { + if (flist[i].isDirectory()) + { + size = size + getFileSize(flist[i]); + } + else + { + size = size + flist[i].length(); + } + } + return size; + } + + /** + * @功能简介:根据字节数转换文件大小 + * @应用页面: + * @作者姓名:JiangYuQi + * @创建时间:2014年10月16日 下午6:59:20 + * @param fileS + * @return: + */ + public static String formatFileSize(long fileS) + {// 转换文件大小 + DecimalFormat df = new DecimalFormat("#.00"); + String fileSizeString = ""; + if (fileS < 1024) + { + fileSizeString = df.format((double) fileS) + "B"; + } + else if (fileS < 1048576) + { + fileSizeString = df.format((double) fileS / 1024) + "KB"; + } + else if (fileS < 1073741824) + { + fileSizeString = df.format((double) fileS / 1048576) + "MB"; + } + else + { + fileSizeString = df.format((double) fileS / 1073741824) + "GB"; + } + return fileSizeString; + } + + /** + * @功能简介:递归求取目录文件个数 + * @应用页面: + * @作者姓名:JiangYuQi + * @创建时间:2014年10月16日 下午7:00:05 + * @param f + * @return: + */ + public static long getFileListCount(File f) + { + long size = 0; + File flist[] = f.listFiles(); + size = flist.length; + for (int i = 0; i < flist.length; i++) + { + if (flist[i].isDirectory()) + { + size = size + getFileListCount(flist[i]); + size--; + } + } + return size; + } + + /** + * + * @创建人:JiangYuQi + * @创建时间:2012-7-13 + * @功能说明:文件复制 + * @param sourceFile 源文件 + * @param targetFile 目标文件 + * @throws IOException + */ + public static void copyFile(File sourceFile, File targetFile) throws IOException + { + BufferedInputStream inBuff = null; + BufferedOutputStream outBuff = null; + try + { + String tagetFilePath = targetFile.getPath(); + String tagetFileName = targetFile.getName(); + File targetFileMl = org.apache.commons.io.FileUtils.getFile(tagetFilePath.replaceAll(tagetFileName, "")); + if (!targetFileMl.exists()) + { + targetFileMl.mkdirs(); + } + // 新建文件输入流并对它进行缓冲 + inBuff = new BufferedInputStream(org.apache.commons.io.FileUtils.openInputStream(sourceFile)); + + // 新建文件输出流并对它进行缓冲 + outBuff = new BufferedOutputStream(org.apache.commons.io.FileUtils.openOutputStream(targetFile)); + + // 缓冲数组 + byte[] b = new byte[BUFFER_SIZE]; + int len; + while ((len = inBuff.read(b)) != -1) + { + outBuff.write(b, 0, len); + } + // 刷新此缓冲的输出流 + outBuff.flush(); + } + finally + { + // 关闭流 + if (inBuff != null) + inBuff.close(); + if (outBuff != null) + outBuff.close(); + } + } + + /** + * + * @创建人:JiangYuQi + * @创建时间:2012-7-13 + * @功能说明:根据文件路径进行文件复制 + * @param sourceFilePath 源文件路径 + * @param targetFilePath 目标文件路径 + * @throws IOException + */ + public static void copyFile(String sourceFilePath, String targetFilePath) throws IOException + { + File sourceFile = org.apache.commons.io.FileUtils.getFile(sourceFilePath); + File targetFile = org.apache.commons.io.FileUtils.getFile(targetFilePath); + copyFile(sourceFile, targetFile); + } + + /** + * 文件夹压缩成ZIP + * + * @param zipFileName 生成压缩文件夹路径 + * @param sourceFileName 要压缩的文件路径 + * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构; + * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) + * @throws RuntimeException 压缩失败会抛出运行时异常 + */ + public static Boolean folderToZip(String zipFileName, String sourceFileName, boolean KeepDirStructure) { + Boolean result = true; + long start = System.currentTimeMillis();//开始 + ZipOutputStream zos = null; + try { + FileOutputStream fileOutputStream = org.apache.commons.io.FileUtils.openOutputStream(org.apache.commons.io.FileUtils.getFile(zipFileName)); + zos = new ZipOutputStream(fileOutputStream); + File sourceFile = org.apache.commons.io.FileUtils.getFile(sourceFileName); + compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure); + long end = System.currentTimeMillis();//结束 + //System.out.println("压缩完成,耗时:" + (end - start) + " 毫秒"); + } catch (Exception e) { + result = false; + e.printStackTrace(); + } finally { + if (zos != null) { + try { + zos.close(); + } catch (IOException e) { + e.getStackTrace(); + } + } + } + return result; + } + + /** + * 递归压缩方法 + * + * @param sourceFile 源文件 + * @param zos zip输出流 + * @param name 压缩后的名称 + * @param KeepDirStructure 是否保留原来的目录结构,true:保留目录结构; + * false:所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败) + * @throws Exception + */ + public static void compress(File sourceFile, ZipOutputStream zos, String name, + boolean KeepDirStructure) throws Exception { + + if (sourceFile.isFile()) { + // 向zip输出流中添加一个zip实体,构造器中name为zip实体的文件的名字 + zos.putNextEntry(new ZipEntry(name)); + // copy文件到zip输出流中 + int len; + byte[] buf = new byte[1024]; + FileInputStream in = org.apache.commons.io.FileUtils.openInputStream(sourceFile); + while ((len = in.read(buf)) != -1) { + zos.write(buf, 0, len); + } + // Complete the entry + zos.closeEntry(); + in.close(); + } else { + File[] listFiles = sourceFile.listFiles(); + if (listFiles == null || listFiles.length == 0) { + // 需要保留原来的文件结构时,需要对空文件夹进行处理 + if (KeepDirStructure) { + // 空文件夹的处理 + zos.putNextEntry(new ZipEntry(name + "/")); + // 没有文件,不需要文件的copy + zos.closeEntry(); + } + } else { + for (File file : listFiles) { + // 判断是否需要保留原来的文件结构 + if (KeepDirStructure) { + // 注意:file.getName()前面需要带上父文件夹的名字加一斜杠, + // 不然最后压缩包中就不能保留原来的文件结构,即:所有文件都跑到压缩包根目录下了 + compress(file, zos, name + "/" + file.getName(), KeepDirStructure); + } else { + compress(file, zos, file.getName(), KeepDirStructure); + } + } + } + } + } + +} diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/MyTableRenderPolicy.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/MyTableRenderPolicy.java new file mode 100644 index 00000000..df8c12ec --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/MyTableRenderPolicy.java @@ -0,0 +1,305 @@ +package com.yanzhu.manage.utils.pdf; + +import com.deepoove.poi.NiceXWPFDocument; +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.policy.AbstractRenderPolicy; +import com.deepoove.poi.template.ElementTemplate; +import com.deepoove.poi.template.run.RunTemplate; +import com.yanzhu.common.core.text.Convert; +import com.yanzhu.common.core.utils.StringUtils; +import org.apache.poi.xwpf.usermodel.*; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge; + +import java.util.ArrayList; +import java.util.List; + +/** + * //////////////////////////////////////////////////////////////////// + * // _ooOoo_ + * // o8888888o + * // 88" . "88 + * // (| ^_^ |) + * // O\ = /O + * // ____/`---'\____ + * // .' \\| |// `. + * // / \\||| : |||// \ + * // / _||||| -:- |||||- \ + * // | | \\\ - /// | | + * // | \_| ''\---/'' | | + * // \ .-\__ `-` ___/-. / + * // ___`. .' /--.--\ `. . ___ + * // ."" '< `.___\_<|>_/___.' >'"". + * // | | : `- \`.;`\ _ /`;.`/ - ` : | | + * // \ \ `-. \_ __\ /__ _/ .-` / / + * // ========`-.____`-.___\_____/___.-`____.-'======== + * // `=---=' + * // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * // 佛祖保佑 永无BUG 永不修改 + * //////////////////////////////////////////////////////////////////// + * + * @ClassName MyTableRenderPolicy + * @Description 自动以table渲染类 + * @Author JiangYuQi + * @DateTime 2021/6/8 16:50 + * @Version 1.0 + */ +public class MyTableRenderPolicy extends AbstractRenderPolicy { + + + @Override + public void doRender(RunTemplate runTemplate, Object data, XWPFTemplate template) throws Exception { + NiceXWPFDocument doc = template.getXWPFDocument(); + List dataList = (List) data; + // 表格 + List tables = this.getTable(doc, runTemplate); //当前表格 + if (tables != null && tables.size() > 0) { + for (XWPFTable table : tables) { + Integer templateRowIndex = null; + List rows = table.getRows(); + int index = 0, lastTemplateCellIndex = 0; + //计算模板所在行索引 + for (XWPFTableRow row : rows) { + boolean isTemplateRow = false; + for (XWPFTableCell tableCell : row.getTableCells()) { + if (tableCell.getText().indexOf("%") > -1) { + isTemplateRow = true; + break; + } + } + if (isTemplateRow) { + templateRowIndex = index; + break; + } + index++; + } + if (StringUtils.isNull(templateRowIndex)) { + continue; + } + XWPFTableRow templateRow = table.getRow(templateRowIndex); //模板行 + index = 0; + //计算模板行最后模板参数列索引 + for (XWPFTableCell tableCell : templateRow.getTableCells()) { + index++; + if (tableCell.getText().indexOf("%") > -1) { + lastTemplateCellIndex = index; + } + } + lastTemplateCellIndex = lastTemplateCellIndex - 1; + Integer nowCellIndex = this.getNowCellIndex(templateRow.getTableCells(), runTemplate); + if (nowCellIndex != null) { + List verticallyList = new ArrayList<>(); + List horizontalList = new ArrayList<>(); + for (int i = 0; i < dataList.size(); i++) { + int nowRowsSize = table.getNumberOfRows(); //当前表格的行数 + int nowRowIndex = i + templateRowIndex + 1; + if (nowRowsSize - 1 < nowRowIndex) { + XWPFTableRow newCreateRow = table.createRow(); + CopyTableRow(newCreateRow, templateRow);// 复制模板行文本和样式到新行 + } + XWPFTableCell cell = table.getRow(nowRowIndex).getCell(nowCellIndex); + //赋值时候判断是否有合并,找出横纵项的合并参数 + String text = Convert.toStr(dataList.get(i)); + if (StringUtils.isNotEmpty(text) && (text.startsWith("Vertically:") || text.startsWith("Horizontal:"))) { + if (text.startsWith("Vertically:")) { + verticallyList.add(nowCellIndex + "-" + text.split(":")[1]); + } + if (text.startsWith("Horizontal:")) { + horizontalList.add(nowRowIndex + "-" + text.split(":")[1]); + } + } else { + setCellText(cell,text); + } + } + //纵向合并 + if (StringUtils.isNotNull(verticallyList) && verticallyList.size() > 0) { + verticallyList.forEach(vertically -> { + String[] params = vertically.split("-"); + mergeCellsVertically(table, Convert.toInt(params[0]), Convert.toInt(params[1]) + 1, Convert.toInt(params[2]) + 1); + }); + } + //横向合并 + if (StringUtils.isNotNull(horizontalList) && horizontalList.size() > 0) { + horizontalList.forEach(horizontal -> { + String[] params = horizontal.split("-"); + mergeCellsHorizontal(table, Convert.toInt(params[0]) , Convert.toInt(params[1]), Convert.toInt(params[2])); + }); + } + //当模板参数渲染完后删除模板行 + if (StringUtils.isNotNull(templateRowIndex) && lastTemplateCellIndex == nowCellIndex) { + table.removeRow(templateRowIndex); + } + } + } + } + } + /** + * @description:填充单元格内容 + * @author: wangjunsheng + * @date: 2022/9/9 17:21 + * @param: cell + * @param: text + **/ + private void setCellText(XWPFTableCell cell, String text) { + if (text.indexOf("\n") != -1) { + XWPFRun run = cell.getParagraphs().get(0).createRun(); + String[] textArr = text.split("\n"); + for (int k = 0; k < textArr.length; k++) { + if (k == 0) { + run.setText(textArr[k].trim()); + } else { + run.addBreak(); + run.setText(textArr[k].trim()); + } + } + } else { + cell.setText(text); + } + } + + /** + * @Description: 跨行合并 + */ + public void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) { + for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) { + XWPFTableCell cell = table.getRow(rowIndex).getCell(col); + if (rowIndex == fromRow) { + // 设置起始合并位置 + cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART); + } else { + // 设置继续合并位置 + cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE); + } + } + } + + /** + * @Description: 跨列合并 + */ + public void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) { + for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) { + XWPFTableCell cell = table.getRow(row).getCell(cellIndex); + if (cellIndex == fromCell) { + // 设置起始合并位置 + cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART); + } else { + // 设置继续合并位置 + cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE); + } + } + } + + /** + * @Description: 获取当前标签所在列的索引 + * @Param: [eleTemplate] + * @return: int + * @Author: JiangYuQi + * @Date: 2019/8/8 17:42 + */ + private Integer getNowCellIndex(List templateCells, ElementTemplate eleTemplate) { + Integer nowCellIndex = null; + int index = 0; + for (XWPFTableCell cell : templateCells) { + if (cell.getText().contains(eleTemplate.getTagName())) { + nowCellIndex = index; + break; + } + index++; + } + return nowCellIndex; + } + + /** + * @Description: 获取当前标签所在的table + * @Param: [doc, eleTemplate] + * @return: org.apache.poi.xwpf.usermodel.XWPFTable + * @Author: JiangYuQi + * @Date: 2019/8/8 17:42 + */ + private List getTable(NiceXWPFDocument doc, ElementTemplate eleTemplate) { + List resultTables = new ArrayList(); + List tables = doc.getTables(); + for (XWPFTable t : tables) { + if (t.getText().contains(eleTemplate.getTagName())) { + resultTables.add(t); + } + } + return resultTables; + } + + /** + * 复制表格行XWPFTableRow格式 + * + * @param target 待修改格式的XWPFTableRow + * @param source 模板XWPFTableRow + */ + private void CopyTableRow(XWPFTableRow target, XWPFTableRow source) { + + // 复制样式 + target.getCtRow().setTrPr(source.getCtRow().getTrPr()); + // 复制单元格 + for (int i = 0; i < source.getTableCells().size(); i++) { + copyTableCell(target.getCell(i), source.getCell(i)); + } + } + + + /** + * 复制单元格XWPFTableCell格式 + * + * @param newTableCell 新创建的的单元格 + * @param templateTableCell 模板单元格 + * @author Juveniless + * @date 2017年11月27日 下午3:41:02 + */ + private void copyTableCell(XWPFTableCell newTableCell, XWPFTableCell templateTableCell) { + // 列属性 + newTableCell.getCTTc().setTcPr(templateTableCell.getCTTc().getTcPr()); + // 删除目标 targetCell 所有文本段落 + for (int pos = 0; pos < newTableCell.getParagraphs().size(); pos++) { + newTableCell.removeParagraph(pos); + } + // 添加新文本段落 + for (XWPFParagraph sp : templateTableCell.getParagraphs()) { + XWPFParagraph targetP = newTableCell.addParagraph(); + copyParagraph(targetP, sp); + if (templateTableCell.getText().indexOf("%") < 0) { + newTableCell.setText(templateTableCell.getText()); + } + } + } + + /** + * 复制文本段落XWPFParagraph格式 + * + * @param newParagraph 新创建的的段落 + * @param templateParagraph 模板段落 + * @author Juveniless + * @date 2017年11月27日 下午3:43:08 + */ + private void copyParagraph(XWPFParagraph newParagraph, XWPFParagraph templateParagraph) { + // 设置段落样式 + newParagraph.getCTP().setPPr(templateParagraph.getCTP().getPPr()); + // 添加Run标签 + for (int pos = 0; pos < newParagraph.getRuns().size(); pos++) { + newParagraph.removeRun(pos); + + } + for (XWPFRun s : templateParagraph.getRuns()) { + XWPFRun targetrun = newParagraph.createRun(); + CopyRun(targetrun, s); + } + + } + + /** + * 复制文本节点run + * + * @param newRun 新创建的的文本节点 + * @param templateRun 模板文本节点 + * @author Juveniless + * @date 2017年11月27日 下午3:47:17 + */ + private void CopyRun(XWPFRun newRun, XWPFRun templateRun) { + newRun.getCTR().setRPr(templateRun.getCTR().getRPr()); + } +} diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/PdfImageSignetUtil.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/PdfImageSignetUtil.java new file mode 100644 index 00000000..a57b58d3 --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/PdfImageSignetUtil.java @@ -0,0 +1,452 @@ +package com.yanzhu.manage.utils.pdf; + +import cn.hutool.core.img.ImgUtil; +import cn.hutool.core.io.FileUtil; +import com.itextpdf.awt.geom.Rectangle2D; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.Font; +import com.itextpdf.text.Image; +import com.itextpdf.text.pdf.*; +import com.itextpdf.text.pdf.parser.*; +import com.yanzhu.common.core.text.Convert; +import com.yanzhu.manage.config.SystemUtils; +import lombok.extern.slf4j.Slf4j; + +import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.*; +import java.util.ArrayList; +import java.util.List; + +@Slf4j +public class PdfImageSignetUtil { + + private static String typefacePath = "C:/Windows/Fonts/"; + + /** + * pdf插入电子印章水印 + * @param templatePath 原pdf文件路径 + * @param targetPath 生成文件输出路径 + * @param imagePath 图片文件路径 + * @param keyWord 签名关键字 + */ + public static void imageWaterMark(String templatePath,String targetPath,String imagePath,String keyWord){ + log.error("imageWaterMark...PDF...PATH{}:" + templatePath); + try { + File pdfFile = org.apache.commons.io.FileUtils.getFile(templatePath); + byte[] pdfData = new byte[(int) pdfFile.length()]; + FileInputStream inputStream = null; + try { + inputStream = org.apache.commons.io.FileUtils.openInputStream(pdfFile); + inputStream.read(pdfData); + } catch (IOException e) { + log.error("PDF读流异常:" + e); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + log.error("IO流关闭发生异常:" + e); + } + } + } + List positions = findKeywordPostions(pdfData, keyWord); + InputStream input = org.apache.commons.io.FileUtils.openInputStream(org.apache.commons.io.FileUtils.getFile(templatePath)); + if (positions != null && positions.size() > 0) { + log.info("发现关键字总条数:" + positions.size()); + log.info("最后一次出现关键字的位置信息:页码=" + (int)positions.get(positions.size()-1)[0] + + ",X轴=" + positions.get(positions.size()-1)[1] + ",Y轴=" + positions.get(positions.size()-1)[2]); + PdfImage(targetPath,input,imagePath,positions); + }else { + log.info("未发现关键字信息"); + } + + } catch (Exception e) { + log.error("PDF插入图片发生意外异常:" + e); + throw new RuntimeException(); + } + } + + /** + * pdf插入电子签章时间 + * @param templatePath 原pdf文件路径 + * @param targetPath 生成文件输出路径 + * @param KeyWord 签名关键字 + * @param signetDate 签名时间 + */ + public static void SignetDateWaterMark(String templatePath,String targetPath,String KeyWord, String signetDate) { + log.error("SignetDateWaterMark...PDF...PATH{}:" + templatePath); + try { + File pdfFile = org.apache.commons.io.FileUtils.getFile(templatePath); + byte[] pdfData = new byte[(int) pdfFile.length()]; + FileInputStream inputStream = null; + try { + + inputStream = org.apache.commons.io.FileUtils.openInputStream(pdfFile); + inputStream.read(pdfData); + } catch (IOException e) { + log.error("PDF读流异常:" + e); + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + log.error("IO流关闭发生异常:" + e); + } + } + } + List positions = findKeywordPostions(pdfData, KeyWord); + InputStream input = org.apache.commons.io.FileUtils.openInputStream(org.apache.commons.io.FileUtils.getFile(templatePath)); + if (positions != null && positions.size() > 0) { + log.info("发现关键字总条数:" + positions.size()); + log.info("最后一次出现关键字的位置信息:页码=" + (int)positions.get(positions.size()-1)[0] + + ",X轴=" + positions.get(positions.size()-1)[1] + ",Y轴=" + positions.get(positions.size()-1)[2]); + PdfSignetDate(targetPath,input,positions,signetDate); + }else { + log.info("未发现关键字信息"); + } + + } catch (Exception e) { + log.error("PDF插入电子签章时间发生意外异常:" + e); + throw new RuntimeException(); + } + } + + /** + * 添加电子签章水印 + * @param newPdfPath + * @param srcPdfPath + * @param imagePath + * @param list + */ + private static void PdfImage(String newPdfPath,InputStream srcPdfPath,String imagePath, List list) { + PdfReader pdfReader = null; + PdfStamper pdfStamper = null; + try { + pdfReader = new PdfReader(srcPdfPath); + FileOutputStream out = org.apache.commons.io.FileUtils.openOutputStream(org.apache.commons.io.FileUtils.getFile(newPdfPath)); + pdfStamper = new PdfStamper(pdfReader, out); + BufferedImage bufferedImage = ImageIO.read(org.apache.commons.io.FileUtils.getFile(imagePath)); + // 这里裁剪图片可能报错,报错用原图 + int[] array = bufferedImageToIntArray(bufferedImage,bufferedImage.getWidth(),bufferedImage.getHeight()); + // blank是作为四周边距留白 + int blank = 20; + boolean cutResult = false; + try { + // 图片裁剪 + ImgUtil.cut(FileUtil.file(imagePath), + FileUtil.file(imagePath + ".v1.png"), new Rectangle(array[0]-blank,array[1]-blank,array[2]+blank*2, array[3]+blank*2)); + cutResult = true; + }catch (Exception ex){ + log.error("图片裁剪发生未知异常:" + ex); + } + // 图片压缩 + // ImgUtil.scale(FileUtil.file(cutResult?(imagePath + ".v0.png"):imagePath), + // FileUtil.file(imagePath + ".v1.png"), (float) (60.0/bufferedImage.getWidth())); + // 图片旋转 + ImgUtil.rotate(FileUtil.file(cutResult?(imagePath + ".v1.png"):imagePath),270,FileUtil.file(imagePath + ".v2.png")); + Image qrcodeImage = Image.getInstance(imagePath+".v2.png"); + //设置图片宽高 + qrcodeImage.scaleToFit(qrcodeImage.getWidth()/20, qrcodeImage.getHeight()/20); + for(int i=0;i list, String signet) { + + PdfReader pdfReader = null; + PdfStamper pdfStamper = null; + + try { + pdfReader = new PdfReader(srcPdfPath); + FileOutputStream out = org.apache.commons.io.FileUtils.openOutputStream(org.apache.commons.io.FileUtils.getFile(newPdfPath)); + pdfStamper = new PdfStamper(pdfReader, out); + for(int i=0;i findKeywordPostions(byte[] pdfData, String keyword) { + List result = new ArrayList<>(); + List pdfPageContentPositions = getPdfContentPostionsList(pdfData); + for (PdfPageContentPositions pdfPageContentPosition : pdfPageContentPositions) { + List charPositions = findPositions(keyword, pdfPageContentPosition); + if (charPositions == null || charPositions.size() < 1) { + continue; + } + result.addAll(charPositions); + } + return result; + } + + /** + * 读取文件内容 + * @param pdfData + * @return + */ + private static List getPdfContentPostionsList(byte[] pdfData) { + try { + PdfReader reader = new PdfReader(pdfData); + List result = new ArrayList<>(); + int pages = reader.getNumberOfPages(); + for (int pageNum = 1; pageNum < pages+1; pageNum++) { + PdfRenderListener pdfRenderListener = new PdfRenderListener(pageNum); + //解析pdf,定位位置 + PdfContentStreamProcessor processor = new PdfContentStreamProcessor(pdfRenderListener); + PdfDictionary pageDic = reader.getPageN(pageNum); + PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES); + try { + processor.processContent(ContentByteUtils.getContentBytesForPage(reader, pageNum), resourcesDic); + } catch (Exception e) { + reader.close(); + log.error("读取文件内容发生未知异常:" + e); + throw new RuntimeException(); + } + String content = pdfRenderListener.getContent(); + List charPositions = pdfRenderListener.getcharPositions(); + List positionsList = new ArrayList<>(); + for (CharPosition charPosition : charPositions) { + float[] positions = new float[]{charPosition.getPageNum(), charPosition.getX(), charPosition.getY()}; + positionsList.add(positions); + } + PdfPageContentPositions pdfPageContentPositions = new PdfPageContentPositions(); + pdfPageContentPositions.setContent(content); + pdfPageContentPositions.setPostions(positionsList); + result.add(pdfPageContentPositions); + } + reader.close(); + return result; + } catch (Exception e) { + log.error("查找关键字发生未知异常:" + e); + throw new RuntimeException(); + } + } + + /** + * 定位关键字位置 + * @param keyword + * @param pdfPageContentPositions + * @return + */ + private static List findPositions(String keyword, PdfPageContentPositions pdfPageContentPositions) { + List result = new ArrayList<>(); + String content = pdfPageContentPositions.getContent(); + List charPositions = pdfPageContentPositions.getPositions(); + for (int pos = 0; pos < content.length(); ) { + int positionIndex = content.indexOf(keyword, pos); + if (positionIndex == -1) { + break; + } + float[] postions = charPositions.get(positionIndex); + result.add(postions); + pos = positionIndex + 1; + } + return result; + } + + /** + * 图片裁剪 + * @param image + * @return + */ + public static int[] bufferedImageToIntArray(BufferedImage image, int width, int height) { + try { + int rgb = 0; + int x1 = width; + int y1 = height; + int x2 = 0; + int y2 = 0; + int temp1 = 0; + int temp2 = 0; + // 方式一:通过getRGB()方式获得像素数组 + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + rgb = image.getRGB(i, j); + if (rgb == -16777216) { + temp1 = i; + temp2 = j; + // 计算最左侧 + if (x1 >= temp1) { + x1 = temp1; + } + // 计算最右侧 + if (x2 <= temp1) { + x2 = temp1; + } + // 计算最下方 + if (y2 <= temp2) { + y2 = temp2; + } + // 计算最上方 + if (y1 >= temp2) { + y1 = temp2; + } + } + } + } + return new int[] {x1, y1, x2 - x1, y2 - y1}; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + static class CharPosition{ + + private int pageNum = 0; + private float x = 0; + private float y = 0; + + public CharPosition(int pageNum, float x, float y) { + + this.pageNum = pageNum; + this.x = x; + this.y = y; + } + public int getPageNum() { + + return pageNum; + } + public float getX() { + return x; + } + public float getY() { + return y; + } + @Override + public String toString() { + + return "[pageNum=" + this.pageNum + ",x=" + this.x + ",y=" + this.y + "]"; + } + } + private static class PdfPageContentPositions { + + private String content; + private List positions; + public String getContent() { + return content; + } + public void setContent(String content) { + this.content = content; + } + public List getPositions() { + return positions; + } + public void setPostions(List positions) { + this.positions = positions; + } + } + private static class PdfRenderListener implements RenderListener { + + private int pageNum; + private StringBuilder contentBuilder = new StringBuilder(); + private List charPositions = new ArrayList<>(); + public PdfRenderListener(int pageNum) { + this.pageNum = pageNum; + } + public void beginTextBlock() { + } + public void renderText(TextRenderInfo renderInfo) { + + List characterRenderInfos = renderInfo.getCharacterRenderInfos(); + for (TextRenderInfo textRenderInfo : characterRenderInfos) { + String word = textRenderInfo.getText(); + if (word.length() > 1) { + word = word.substring(word.length() - 1, word.length()); + } + Rectangle2D.Float rectangle = textRenderInfo.getAscentLine().getBoundingRectange(); + float x = (float)rectangle.getX(); + float y = (float)rectangle.getY(); + CharPosition charPosition = new CharPosition(pageNum, (float)x, (float)y); + charPositions.add(charPosition); + contentBuilder.append(word); + } + } + public void endTextBlock() { + } + public void renderImage(ImageRenderInfo renderInfo) { + } + public String getContent() { + return contentBuilder.toString(); + } + public List getcharPositions() { + return charPositions; + } + } + + public static void main(String[] args) throws IOException { + File pdfFile = org.apache.commons.io.FileUtils.getFile("C:\\Users\\Administrator\\Desktop\\微信图片_20240122160815.jpg"); + FileInputStream inputStream = org.apache.commons.io.FileUtils.openInputStream(pdfFile); + } +} diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/PoiUtil.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/PoiUtil.java new file mode 100644 index 00000000..ea90bfb8 --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/PoiUtil.java @@ -0,0 +1,436 @@ +package com.yanzhu.manage.utils.pdf; + +import com.deepoove.poi.XWPFTemplate; +import com.deepoove.poi.config.Configure; +import com.yanzhu.common.core.utils.DateUtils; +import com.yanzhu.common.core.utils.StringUtils; +import com.yanzhu.common.core.utils.uuid.IdUtils; +import com.yanzhu.common.core.utils.uuid.Seq; +import com.yanzhu.manage.config.ProfileConfig; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * //////////////////////////////////////////////////////////////////// + * // _ooOoo_ + * // o8888888o + * // 88" . "88 + * // (| ^_^ |) + * // O\ = /O + * // ____/`---'\____ + * // .' \\| |// `. + * // / \\||| : |||// \ + * // / _||||| -:- |||||- \ + * // | | \\\ - /// | | + * // | \_| ''\---/'' | | + * // \ .-\__ `-` ___/-. / + * // ___`. .' /--.--\ `. . ___ + * // ."" '< `.___\_<|>_/___.' >'"". + * // | | : `- \`.;`\ _ /`;.`/ - ` : | | + * // \ \ `-. \_ __\ /__ _/ .-` / / + * // ========`-.____`-.___\_____/___.-`____.-'======== + * // `=---=' + * // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * // 佛祖保佑 永无BUG 永不修改 + * //////////////////////////////////////////////////////////////////// + * + * @ClassName PoiUtil + * @Description Poi工具 + * @Author JiangYuQi + * @DateTime 2021/6/8 16:50 + * @Version 1.0 + */ +public class PoiUtil { + + /** + * @Description: 根据word模板生成word文件 + * @Param: [wordTemplateFilePath, saveWordFilePath, dataMap] + * @return: void + * @Author: JiangYuQi + * @Date: 2019/8/8 11:54 + */ + public static void createWordByWordTemplate(String wordTemplateFilePath, String saveWordFilePath, Map dataMap) throws Exception { + + if (StringUtils.isNotEmpty(wordTemplateFilePath) && StringUtils.isNotEmpty(saveWordFilePath)&&saveWordFilePath.endsWith(".docx")) { + try { + dataMap = formatMap(dataMap); + Configure.ConfigureBuilder builder = Configure.newBuilder(); + builder.addPlugin('%', new MyTableRenderPolicy()); + //builder.addPlugin('&', new ShangWuBiaoTableRenderPolicy()); + XWPFTemplate template = XWPFTemplate.compile(wordTemplateFilePath, builder.build()).render(dataMap); + FileOutputStream out = FileUtils.openOutputStream(FileUtils.getFile(saveWordFilePath)); + template.write(out); + out.flush(); + out.close(); + template.close(); + } catch (IOException e) { + e.printStackTrace(); + throw e; + } + } else { + //System.out.println("params is null"); + throw new Exception("createWordByWordTemplate params is null"); + } + } + + + /** + * @Description: 根据word模板生成pdf文件 + * @Param: [wordTemplateFilePath, savePdfFilePath, dataMap] + * @return: void + * @Author: JiangYuQi + * @Date: 2019/8/14 14:08 + */ + public static void createPdfByWordTemplate(String wordTemplateFilePath, String savePdfFilePath, Map dataMap) throws Exception { + if (StringUtils.isNotEmpty(wordTemplateFilePath) && StringUtils.isNotEmpty(savePdfFilePath)) { + String saveWordFilePath = savePdfFilePath.substring(0, savePdfFilePath.lastIndexOf(".")) + ".docx"; + createWordByWordTemplate(wordTemplateFilePath, saveWordFilePath, dataMap); + WordToPdfUtil.wordToPdf(saveWordFilePath, savePdfFilePath); + } else { + throw new Exception("createPdfByWordTemplate params is null"); + } + } + + /** + * @description:根据模板生成文件(只能是pdf),返回数据库保存地址 + * @author: JiangYuQi + * @date: 2022/6/17 11:08 + * @param: wordTemplateFilePath + * @param: dataMap + **/ + public static String createPdfByWordTemplate(String wordTemplateFilePath, Map dataMap) throws Exception { + String rootPath = ProfileConfig.profilePath; + String fileName = getExtractFilename(); + File file = getAbsoluteFile(rootPath,fileName); + String savePdfFilePath =file.getPath(); + //根据模板生成文件 + wordTemplateFilePath = ProfileConfig.profilePath+wordTemplateFilePath.replaceAll("/profile/upload",""); + createPdfByWordTemplate(wordTemplateFilePath,savePdfFilePath,dataMap); + String dbFilePath = getPathFileName(rootPath,fileName); + return dbFilePath; + } + + public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException + { + File desc = new File(uploadDir + File.separator + fileName); + + if (!desc.exists()) + { + if (!desc.getParentFile().exists()) + { + desc.getParentFile().mkdirs(); + } + } + return desc.isAbsolute() ? desc : desc.getAbsoluteFile(); + } + + public static final String getPathFileName(String fileName) throws IOException + { + String pathFileName = "/" + fileName; + return pathFileName; + } + + public static final String getPathFileName(String uploadDir, String fileName) throws IOException + { + int dirLastIndex = ProfileConfig.profilePath.length() + 1; + String currentDir = StringUtils.substring(uploadDir, dirLastIndex); + return ProfileConfig.profile + "/" + currentDir + "/" + fileName; + } + + /** + * @description:根据文件后缀返回文件名 + * @author: JiangYuQi + * @date: 2022/6/17 10:28 + * @param: type + * @return: java.lang.String + **/ + public static final String getExtractFilename() + { + return StringUtils.format("{}/{}_{}.{}", DateUtils.datePath(), + FilenameUtils.getBaseName(IdUtils.fastSimpleUUID()), Seq.getId(Seq.uploadSeqType), "pdf"); + } + + + /** + * @Description: 格式化data参数 + * @Param: [dataMap] + * @return: java.util.Map + * @Author: JiangYuQi + * @Date: 2019/8/14 14:46 + */ + private static Map formatMap(Map dataMap) { + if (dataMap != null && dataMap.size() > 0) { + for (Map.Entry kv : dataMap.entrySet()) { + if (kv.getValue() == null) { + kv.setValue(""); + } + } + } + return dataMap; + } + + public static void main(String[] args) { +// Map canShuMap = new HashMap<>(); +// //测试参数 +// canShuMap.put("HTBianHao","测试合同编号"); +// canShuMap.put("HTMingCheng","测试合同名称"); +// canShuMap.put("HTJinE","测试1000000"); +// canShuMap.put("HTDaXieJinE","测试壹佰万元整"); +// canShuMap.put("HTBiZhong","测试人民币"); +// canShuMap.put("HTHuiLv","测试7.12"); +// canShuMap.put("HTRenMinBiJinE","测试1000000"); +// canShuMap.put("HTYeWuLeiXing","测试合同类型"); +// canShuMap.put("HTXiangMuLeiXing","测试项目类型"); +// canShuMap.put("HTXiangMuJiBie","测试项目级别"); +// canShuMap.put("HTCaiGouFangShi","测试采购方式"); +// canShuMap.put("HTQianDingRiQi","测试签订日期"); +// canShuMap.put("HTShengXiaoRiQi","测试生效日期"); +// canShuMap.put("HTYFGongSiMingCheng","测试乙方公司名称"); +// canShuMap.put("HTYFSheHuiXinYongDaiMa","测试乙方社会信用代码"); +// canShuMap.put("HTYFBanGongDianHua","测试乙方办公电话"); +// canShuMap.put("HTYFFaRenDaiBiao","测试乙方法人代表"); +// canShuMap.put("HTYFKaiHuHang","测试乙方开户行"); +// canShuMap.put("HTYFYinHangZhangHao","测试乙方银行账号"); +// canShuMap.put("HTYFGongSiDiZhi","测试乙方公司地址"); +// canShuMap.put("HTJingBanRen","测试经办人"); +// canShuMap.put("HTJingBanRenZJH","测试经办人证件号"); +// canShuMap.put("HTXiangMuDanWeiMingCheng","测试项目单位名称"); +// canShuMap.put("HTBeiZhu","测试合同备注"); +// canShuMap.put("HTXiangMuYuan","测试项目员"); +// canShuMap.put("HTXiangMuYuanZJH","测试项目员证件号"); +// canShuMap.put("HTXiangMuYuanLianXiDianHua","测试项目员联系电话"); +// //工程服务 +// canShuMap.put("GCFWKaiShiRiQi","测试工程服务开始日期"); +// canShuMap.put("GCFWJieShuRiQi","测试工程服务结束日期"); +// canShuMap.put("GCFWXiangMuDanWeiLianXiRen","测试项目单位联系人"); +// canShuMap.put("GCFWYFXMFZR","测试乙方项目负责人"); +// canShuMap.put("GCFWYFXMFZRSJ","测试乙方项目负责人手机"); +// canShuMap.put("GCFWYFXMFZRDH","测试乙方项目负责人电话"); +// canShuMap.put("GCFWYFXMFZREMAIL","测试乙方项目负责人Email"); +// canShuMap.put("GCFWZhiLiangDengJi","测试质量等级"); +// canShuMap.put("GCFWLvYueDiDian","测试履约地点"); +// //货物 +// canShuMap.put("HWJFFDDBR","测试甲方法定代表人"); +// canShuMap.put("HWZhiBaoQi","测试质保期(月)"); +// canShuMap.put("HWDaoHuoZhouQi","测试到货周期"); +// canShuMap.put("HWDaoHuoZhouQiDanWei","测试到货周期单位"); +// canShuMap.put("HWYFLXR","测试乙方联系人"); +// canShuMap.put("HWYFLXRSJ","测试乙方联系人手机"); +// canShuMap.put("HWYFLXRDH","测试乙方联系人电话"); +// canShuMap.put("HWYFLXREMAIL","测试乙方联系人Email"); +// //货物明细 +// List HWMXHuoWuMingChengList = new ArrayList<>(); +// HWMXHuoWuMingChengList.add("测试货物名称1"); +// HWMXHuoWuMingChengList.add("测试货物名称2"); +// canShuMap.put("HWMXHuoWuMingCheng",HWMXHuoWuMingChengList); +// List HWMXGuiGeXingHaoList = new ArrayList<>(); +// HWMXGuiGeXingHaoList.add("测试规格型号1"); +// HWMXGuiGeXingHaoList.add("测试规格型号2"); +// canShuMap.put("HWMXGuiGeXingHao",HWMXGuiGeXingHaoList); +// List HWMXPinPaiList = new ArrayList<>(); +// HWMXPinPaiList.add("测试品牌1"); +// HWMXPinPaiList.add("测试品牌2"); +// canShuMap.put("HWMXPinPai",HWMXPinPaiList); +// List HWMXShengChanChangJiaList = new ArrayList<>(); +// HWMXShengChanChangJiaList.add("测试生产厂家1"); +// HWMXShengChanChangJiaList.add("测试生产厂家2"); +// canShuMap.put("HWMXShengChanChangJia",HWMXShengChanChangJiaList); +// List HWMXShuLiangList = new ArrayList<>(); +// HWMXShuLiangList.add("测试数量1"); +// HWMXShuLiangList.add("测试数量2"); +// canShuMap.put("HWMXShuLiang",HWMXShuLiangList); +// List HWMXJiLiangDanWeiList = new ArrayList<>(); +// HWMXJiLiangDanWeiList.add("测试计量单位1"); +// HWMXJiLiangDanWeiList.add("测试计量单位2"); +// canShuMap.put("HWMXJiLiangDanWei",HWMXJiLiangDanWeiList); +// List HWMXDanJiaList = new ArrayList<>(); +// HWMXDanJiaList.add("测试单价1"); +// HWMXDanJiaList.add("测试单价2"); +// canShuMap.put("HWMXDanJia",HWMXDanJiaList); +// List HWMXZongEList = new ArrayList<>(); +// HWMXZongEList.add("测试总额1"); +// HWMXZongEList.add("测试总额2"); +// canShuMap.put("HWMXZongE",HWMXZongEList); +// +// //付款方式 +// List FKFSShiJianList = new ArrayList<>(); +// FKFSShiJianList.add("测试时间1"); +// FKFSShiJianList.add("测试时间2"); +// canShuMap.put("FKFSShiJian",FKFSShiJianList); +// List FKFSJinEList = new ArrayList<>(); +// FKFSJinEList.add("测试金额1"); +// FKFSJinEList.add("测试金额2"); +// canShuMap.put("FKFSJinE",FKFSJinEList); +// List FKFSMiaoShuList = new ArrayList<>(); +// FKFSMiaoShuList.add("测试描述1"); +// FKFSMiaoShuList.add("测试描述2"); +// canShuMap.put("FKFSMiaoShu",FKFSMiaoShuList); +// +// canShuMap.put("tables", new TableRenderData(new ArrayList(){{ +// add(new TextRenderData("d0d0d0", "节目")); +// add(new TextRenderData("d0d0d0", "次数")); +// }},new ArrayList(){{ +// add("《SNH星剧院公演》;999"); +// add("《敢ZUO敢为女声秀》;4"); +// add("《快乐大本营》;2"); +// }}, "no datas", 10600)); +// +// +// String testMoBanPath = "d:\\1.docx"; +// String saveWordFilePath = "D:\\2.docx"; +// +// String pdfPath = "d:\\3.pdf"; +// +// File file = new File(testMoBanPath); +// if(file.exists()){ +// System.out.println("文件存在"); +// }else{ +// System.out.println("文件不存在"); +// } + + try { +// PoiUtil.createWordByWordTemplate(testMoBanPath, saveWordFilePath, canShuMap); +// +// WordToPdfUtil.wordToPdf(saveWordFilePath, pdfPath); + +// System.out.println(Md5Util.StringToMd5("ZJK123qwe")); + + + /*******************************************技术标模板测试******************************************/ +// Map jiShuBiaoTable = new HashMap<>(); +// +// //组装评分项数据 +// List> pingFenXiangS = new ArrayList<>(); +// for (int i = 1; i < 7; i++) { +// LinkedHashMap pingFenXiang = new LinkedHashMap<>(); +// pingFenXiang.put("zongXiang", "总项" + i); +// pingFenXiang.put("miaoShu", "总项" + i + "描述"); +// +// List> fenXiangs = new ArrayList<>(); +// for (int k = 1; k < 4; k++) { +// LinkedHashMap fenXiang = new LinkedHashMap<>(); +// fenXiang.put("fenXiang", "分项" + i + "-" + k); +// fenXiang.put("miaoShu", "分项" + +i + "-" + k + "描述"); +// fenXiang.put("fenShuQuJian", "0-" + (i * k)); +// fenXiangs.add(fenXiang); +// } +// pingFenXiang.put("fenXiangs", fenXiangs); +// pingFenXiangS.add(pingFenXiang); +// } +// jiShuBiaoTable.put("pingFenXiangS", pingFenXiangS); +// +// //组装公司得分 +// List> gongSiDeFens = new ArrayList<>(); +// for (int i = 1; i < 3; i++) { +// LinkedHashMap gongSiDeFen = new LinkedHashMap<>(); +// gongSiDeFen.put("gongSiMingCheng", "公司1"); +// List fenShu = new ArrayList<>(); +// for (int k = 1; k < 19; k++) { +// fenShu.add(k + ""); +// } +// gongSiDeFen.put("fenShu", fenShu); +// gongSiDeFens.add(gongSiDeFen); +// } +// jiShuBiaoTable.put("gongSiDeFens", gongSiDeFens); +// +// String wordTemplateFilePath = "D:/template/jiShuBiao-template.docx"; +// String saveWordFilePath = "D:/template/jisShuBiao_out_template.pdf"; +// +// Map dataMap = new HashMap<>(); +// dataMap.put("jiShuBiaoTable", jiShuBiaoTable); +// createPdfByWordTemplate(wordTemplateFilePath, saveWordFilePath, dataMap); + + + /****************************************************商务标模板测试*****************************************************/ +// Map dataMap = new HashMap<>(); +// dataMap.put("XMBH", "陕师大(2021)06002"); +// dataMap.put("XMMC", "陕师大商务标测试项目"); +// dataMap.put("KBSJ", "2021-06-09"); +// +// for (int i = 1; i <= 12; i++) { +// dataMap.put("zj" + i, "张三" + i); //专家姓名 +// dataMap.put("zj" + i + "_qz", "[张三" + i + "]"); //专家签字关键字 +// } +// +// Map shangWuBiaoTableMap = new HashMap<>(); +// shangWuBiaoTableMap.put("ZZBJJZ", 293280); //最终报价基准 +// List> gongSiShangWuBiaoList = new ArrayList<>(); +// for (int i = 1; i <= 10; i++) { +// Map gongSiShangWuBiao = new HashMap<>(); +// gongSiShangWuBiao.put("GSMC", "北京国网中电软件股份有限公司" + i); //公司名称 +// gongSiShangWuBiao.put("ZZBJ", 349000 + i); //最终报价 +// gongSiShangWuBiao.put("JGKC", "6%"); //价格扣除 +// gongSiShangWuBiao.put("PSBJ", 328060 + i); //评审报价 +// gongSiShangWuBiao.put("ZZBJDF", 26.82 + i); //最终报价得分 +// gongSiShangWuBiao.put("BJDF", 26.82 + i); //报价总分 +// +// gongSiShangWuBiaoList.add(gongSiShangWuBiao); +// } +// shangWuBiaoTableMap.put("gongSiShangWuBiaoList", gongSiShangWuBiaoList); //公司商务标数据 +// dataMap.put("shangWuBiaoTable", shangWuBiaoTableMap); //商务标表格数据 +// String wordTemplateFilePath = "D:/template/shangWuBiao-template.docx"; +// String saveWordFilePath = "D:/template/shangWuBiao_out_template.pdf"; +// +// createPdfByWordTemplate(wordTemplateFilePath, saveWordFilePath, dataMap); + + + Map dataMap = new HashMap<>(); + dataMap.put("XMBH", "陕师大(2021)06002"); + dataMap.put("XMMC", "陕师大商务标测试项目"); + dataMap.put("KBSJ", "2021-06-09"); + + for (int i = 1; i <= 12; i++) { + dataMap.put("zj" + i, "张三" + i); //专家姓名 + dataMap.put("zj" + i + "_qz", "[张三" + i + "]"); //专家签字关键字 + } + + List> gongSiShangWuBiaoList = new ArrayList<>(); + List XH = new ArrayList<>(); + List GSMC = new ArrayList<>(); + List ZZBJ = new ArrayList<>(); + List JGKC = new ArrayList<>(); + List PSBJ = new ArrayList<>(); + List ZZBJDF = new ArrayList<>(); + List BJZF = new ArrayList<>(); + for (int i = 1; i <= 10; i++) { + XH.add(i+""); + GSMC.add("北京国网中电软件股份有限公司" + i); //公司名称 + ZZBJ.add( (349000 + i)+"元"); //最终报价 + JGKC.add("6%"); //价格扣除 + PSBJ.add((328060 + i) + "元"); //评审报价 + ZZBJDF.add((26.82 + i) + ""); //最终报价得分 + BJZF.add((26.82 + i) + ""); //报价总分 + + } + dataMap.put("XH", XH); + dataMap.put("GSMC", GSMC); + dataMap.put("ZZBJ", ZZBJ); + dataMap.put("JGKC", JGKC); + dataMap.put("PSBJ", PSBJ); + dataMap.put("ZZBJDF", ZZBJDF); + dataMap.put("BJZF", BJZF); + + Map ZZBJJZ = new HashMap<>(); + ZZBJJZ.put("ZZBJJZ", 293280+"元"); //最终报价基准 + ZZBJJZ.put("GSSIZE", 10); //公司数 + dataMap.put("ZZBJJZ", ZZBJJZ); //最终报价基准 + String wordTemplateFilePath = "D:/template/shangWuBiao-template2.docx"; + String saveWordFilePath = "D:/template/shangWuBiao_out_template2.pdf"; + + createPdfByWordTemplate(wordTemplateFilePath, saveWordFilePath, dataMap); + + + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } +} diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/ShangWuBiaoTableRenderPolicy.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/ShangWuBiaoTableRenderPolicy.java new file mode 100644 index 00000000..f7701936 --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/ShangWuBiaoTableRenderPolicy.java @@ -0,0 +1,191 @@ +package com.yanzhu.manage.utils.pdf; + +import com.deepoove.poi.policy.DynamicTableRenderPolicy; +import com.deepoove.poi.util.TableTools; +import com.yanzhu.common.core.utils.StringUtils; +import org.apache.poi.xwpf.usermodel.XWPFTable; +import org.apache.poi.xwpf.usermodel.XWPFTableCell; +import org.apache.poi.xwpf.usermodel.XWPFTableRow; + +import java.util.List; +import java.util.Map; + +/** + * //////////////////////////////////////////////////////////////////// + * // _ooOoo_ + * // o8888888o + * // 88" . "88 + * // (| ^_^ |) + * // O\ = /O + * // ____/`---'\____ + * // .' \\| |// `. + * // / \\||| : |||// \ + * // / _||||| -:- |||||- \ + * // | | \\\ - /// | | + * // | \_| ''\---/'' | | + * // \ .-\__ `-` ___/-. / + * // ___`. .' /--.--\ `. . ___ + * // ."" '< `.___\_<|>_/___.' >'"". + * // | | : `- \`.;`\ _ /`;.`/ - ` : | | + * // \ \ `-. \_ __\ /__ _/ .-` / / + * // ========`-.____`-.___\_____/___.-`____.-'======== + * // `=---=' + * // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * // 佛祖保佑 永无BUG 永不修改 + * //////////////////////////////////////////////////////////////////// + * + * @ClassName MyJiShuBiaoTableRenderPolicy + * @Description 技术标汇总表专用 + * @Author JiangYuQi + * @DateTime 2021/6/8 16:50 + * @Version 1.0 + */ +public class ShangWuBiaoTableRenderPolicy extends DynamicTableRenderPolicy { + + // 列数 + int cellNum = 8; + //行高 + int rowHeight = 100; + + float cellWidths[]={9f,3f,3f,3f,3f,3f,3f}; //列宽单位CM + + @Override + public void render(XWPFTable table, Object data) { + createTable2(table, data); + } + + private void createTable1(XWPFTable table, Object data) { + if (StringUtils.isNull(data)) { + return; + } + Map shangWuBiaoTableMap = (Map) data; + + table.removeRow(0); + /**************************创建表头-开始********************************/ + + TableTools.widthTable(table,cellWidths); + + XWPFTableRow titleNewRow = table.insertNewTableRow(0); + table.setCellMargins(5 ,2,5,2); + titleNewRow.setHeight(rowHeight); + for (int i = 0; i < cellNum; i++) { + XWPFTableCell cell = titleNewRow.createCell(); + cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + + switch (i) { + case 0: + cell.setText("序号"); + break; + case 1: + cell.setText("供应商名称"); + break; + case 2: + cell.setText("最终报价"); + break; + case 3: + cell.setText("价格扣除"); + break; + case 4: + cell.setText("评审报价"); + break; + case 5: + cell.setText("最终报价基准"); + break; + case 6: + cell.setText("最终报价得分"); + break; + case 7: + cell.setText("报价总分"); + break; + } + + } + /**************************创建表头-结束********************************/ + + /**************************创建公司商务标行并赋值-开始********************************/ + if (StringUtils.isNotEmpty(shangWuBiaoTableMap)) { + + List> gongSiShangWuBiaoList = (List>) shangWuBiaoTableMap.get("gongSiShangWuBiaoList"); + if (StringUtils.isNotEmpty(gongSiShangWuBiaoList)) { + int rowIndex = 1; //行所以 + for (Map gongSiShangWuBiao : gongSiShangWuBiaoList) { + XWPFTableRow newRow = table.insertNewTableRow(rowIndex); + newRow.setHeight(rowHeight); + for (int i = 0; i < cellNum; i++) { + XWPFTableCell cell = newRow.addNewTableCell(); + cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + + switch (i) { + case 0: + cell.setText(rowIndex + ""); + break; + case 1://公司名称 + cell.setText(toStirng(gongSiShangWuBiao.get("GSMC"))); + break; + case 2: //最终报价 + cell.setText(toStirng(gongSiShangWuBiao.get("ZZBJ"))+"元"); + break; + case 3: //价格扣除 + cell.setText(toStirng(gongSiShangWuBiao.get("JGKC"))); + break; + case 4: //评审报价 + cell.setText(toStirng(gongSiShangWuBiao.get("PSBJ"))+"元"); + break; + case 5: //最终报价基准 + break; + case 6: //最终报价得分 + cell.setText(toStirng(gongSiShangWuBiao.get("ZZBJDF"))); + break; + case 7: //报价总分 + cell.setText(toStirng(gongSiShangWuBiao.get("BJDF"))); + break; + } + } + rowIndex++; + } + //合并最终报价基准行 + TableTools.mergeCellsVertically(table, 5, 1, rowIndex - 1); + //最终报价基准赋值 + XWPFTableCell zzbjjzCell = table.getRow(1).getCell(5); + zzbjjzCell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + zzbjjzCell.setText(toStirng(shangWuBiaoTableMap.get("ZZBJJZ"))+"元"); + } + } + /**************************创建公司商务标行并赋值-开始********************************/ + } + + private void createTable2(XWPFTable table, Object data) { + if (StringUtils.isNull(data)) { + return; + } + Map ZZBJJZMap = (Map) data; + + String ZZBJJZ = toStirng(ZZBJJZMap.get("ZZBJJZ")); + int GSSIZE = ZZBJJZMap.get("GSSIZE")==null?0:Integer.parseInt(toStirng(ZZBJJZMap.get("GSSIZE"))); + //合并最终报价基准行 + TableTools.mergeCellsVertically(table, 5, 1, GSSIZE+1); + + XWPFTableCell cell = table.getRow(2).getCell(5); + cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER); + cell.setText(ZZBJJZ); + } + + /*** + * @param obj + * @return java.lang.String + * @exception + * @Author JiangYuQi + * @Description 转字符串 + * @Date 2022/6/15 16:27 + **/ + private String toStirng(Object obj) + { + if(obj!=null && "null".equals(obj)){ + return ""; + }else{ + return obj.toString(); + } + } + + +} diff --git a/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/WordToPdfUtil.java b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/WordToPdfUtil.java new file mode 100644 index 00000000..973e896d --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/java/com/yanzhu/manage/utils/pdf/WordToPdfUtil.java @@ -0,0 +1,152 @@ +package com.yanzhu.manage.utils.pdf; + +import com.aspose.words.Document; +import com.aspose.words.FontSettings; +import com.aspose.words.License; +import com.aspose.words.SaveFormat; +import com.yanzhu.manage.config.SystemUtils; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.InputStream; + +/** + * //////////////////////////////////////////////////////////////////// + * // _ooOoo_ + * // o8888888o + * // 88" . "88 + * // (| ^_^ |) + * // O\ = /O + * // ____/`---'\____ + * // .' \\| |// `. + * // / \\||| : |||// \ + * // / _||||| -:- |||||- \ + * // | | \\\ - /// | | + * // | \_| ''\---/'' | | + * // \ .-\__ `-` ___/-. / + * // ___`. .' /--.--\ `. . ___ + * // ."" '< `.___\_<|>_/___.' >'"". + * // | | : `- \`.;`\ _ /`;.`/ - ` : | | + * // \ \ `-. \_ __\ /__ _/ .-` / / + * // ========`-.____`-.___\_____/___.-`____.-'======== + * // `=---=' + * // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + * // 佛祖保佑 永无BUG 永不修改 + * //////////////////////////////////////////////////////////////////// + * + * @ClassName WordToPdfUtil + * @Description word文件转PDF文件 + * @Author JiangYuQi + * @DateTime 2021/6/8 16:50 + * @Version 1.0 + */ +public class WordToPdfUtil { + + public static String LinuxChineseFontsFolder = "/usr/local/ChineseFontsFolder/"; + + /** + * @Description: 验证License + * @Param: [] + * @return: boolean + * @Author: JiangYuQi + * @Date: 2019/8/14 9:44 + */ + private static boolean getLicense() throws Exception { + boolean result = false; + try { + // String classPath = WordToPdfUtil.class.getResource("/").getPath(); + // classPath = URLDecoder.decode(classPath, "utf-8"); + // InputStream is = new FileInputStream(classPath + "Aspose_license.xml"); + InputStream is = WordToPdfUtil.class.getClassLoader().getResourceAsStream("Aspose_license.xml"); + // InputStream is = new FileInputStream("d://Aspose_license.xml"); + License aposeLic = new License(); + aposeLic.setLicense(is); + result = true; + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + return result; + } + + public static void main(String[] args) + { + try + { + String fileName="word-2007.docx"; + String savedocx="word-2007To2007.docx"; + savedocx("d:/"+fileName,"d:/"+savedocx); + } + catch (Exception e) + { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + /** + * @Description: word文件转pdf文件 + * @Param: [inPath, outPath] + * @return: void + * @Author: JiangYuQi + * @Date: 2019/8/14 9:44 + */ + public static void wordToPdf(String wordFilePath, String pdfFilePath) throws Exception { + if(pdfFilePath.endsWith(".pdf")){ + try { + if (SystemUtils.isLinux) { + FontSettings.setFontsFolder(LinuxChineseFontsFolder, true); + } + if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生 + return; + } + long old = System.currentTimeMillis(); + File file = org.apache.commons.io.FileUtils.getFile(pdfFilePath); // 新建一个空白pdf文档 + FileOutputStream os = org.apache.commons.io.FileUtils.openOutputStream(file); + Document doc = new Document(wordFilePath); // Address是将要被转化的word文档 + doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, + // EPUB, XPS, SWF 相互转换 + long now = System.currentTimeMillis(); + if(os!=null){ + os.close(); + } + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } + } + + /** + * @Description: doc文件转docx文件 + * @Param: [inPath, outPath] + * @return: void + * @Author: JiangYuQi + * @Date: 2019/8/14 9:45 + */ + public static void savedocx(String inPath, String outPath) throws Exception { + try { + + String fileType = inPath.substring(inPath.lastIndexOf(".")+1).toUpperCase(); + if("DOCX".equals(fileType)){ + FileUtil.copyFile(inPath,outPath); + } + else if("DOC".equals(fileType)){ + if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生 + return; + } + //long old = System.currentTimeMillis(); + File file = org.apache.commons.io.FileUtils.getFile(outPath); // 新建一个空白pdf文档 + FileOutputStream os = org.apache.commons.io.FileUtils.openOutputStream(file); + Document doc = new Document(inPath); // Address是将要被转化的word文档 + doc.save(os, SaveFormat.DOCX);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, + // EPUB, XPS, SWF 相互转换 + //long now = System.currentTimeMillis(); + //System.out.println(outPath + "生成共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时 + } + + } catch (Exception e) { + e.printStackTrace(); + throw e; + } + } +} diff --git a/yanzhu-modules/yanzhu-manage/src/main/resources/Aspose_license.xml b/yanzhu-modules/yanzhu-manage/src/main/resources/Aspose_license.xml new file mode 100644 index 00000000..d90f99f5 --- /dev/null +++ b/yanzhu-modules/yanzhu-manage/src/main/resources/Aspose_license.xml @@ -0,0 +1,14 @@ + + + + Aspose.Total for Java + Aspose.Words for Java + + Enterprise + 20991231 + 20991231 + 8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7 + + sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU= + +