diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java index c5e47f6..06f5c41 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java @@ -40,6 +40,14 @@ imageConfig.setDocName(customizedSignNames.get(i)); approvalImageList.add(imageConfig); } + ImageConfig imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(0)); + imageConfig.setDocName("检测人"); + approvalImageList.add(imageConfig); + imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(1)); + imageConfig.setDocName("核验人"); + approvalImageList.add(imageConfig); return approvalImageList; } @@ -92,6 +100,7 @@ .build(); return electronicImage; } + /** * 自动生成是根据宽度设定取空隙平均值 * 默认电子签章的图片设置,允许重写 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java index c5e47f6..06f5c41 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java @@ -40,6 +40,14 @@ imageConfig.setDocName(customizedSignNames.get(i)); approvalImageList.add(imageConfig); } + ImageConfig imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(0)); + imageConfig.setDocName("检测人"); + approvalImageList.add(imageConfig); + imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(1)); + imageConfig.setDocName("核验人"); + approvalImageList.add(imageConfig); return approvalImageList; } @@ -92,6 +100,7 @@ .build(); return electronicImage; } + /** * 自动生成是根据宽度设定取空隙平均值 * 默认电子签章的图片设置,允许重写 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java index 601612f..bf1108a 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java @@ -8,12 +8,14 @@ import com.casic.missiles.dto.business.file.FilePrintRegister; import com.casic.missiles.service.listeners.util.ParseWord07; import com.casic.missiles.service.listeners.util.PdfUtils; +import com.casic.missiles.utils.QRCodeUtil; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import com.spire.doc.*; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; +import com.spire.doc.fields.ShapeObject; import com.spire.doc.fields.TextRange; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -48,17 +50,19 @@ */ private final static Integer DEFAULT_SEAL_INDEX = 0; - private final static String INSIGNIA_KEYWORD = "公章"; + private final static String INSIGNIA_KEYWORD = "专用章"; /** * @param filePrintRegister 证书文件注册 */ - public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws RuntimeException { + public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws Exception { ElectronicImage selectSeal = null; //1、按照模板填充数据,并导出word,执行填充行数之后,再进行页数的填充 String wordOldUrl = exportWord(filePrintRegister.getTemDir(), filePrintRegister.getFileName(), filePrintRegister.getParams(), null, filePrintRegister.getCustomFileName()); + //预先生成二维码图片 + getQrCode(filePrintRegister.getTemDir(), filePrintRegister.getCustomFileName(), wordOldUrl); log.debug("执行完填充参数操作......"); if (CollectionUtils.isNotEmpty(filePrintRegister.getElectronicImageList())) { try { @@ -70,23 +74,32 @@ ); log.debug("执行关键字打合成操作,打印配置为{}.......", JSON.toJSON(sameKeyWordSealMaps)); //3、根据关键字进行添加签章和签字 - selectSeal = addSameKeyWordStamp(wordOldUrl, wordOldUrl, sameKeyWordSealMaps); + selectSeal = addSameKeyWordStamp(wordOldUrl, sameKeyWordSealMaps); //获取没有关键字的图片,即绝对路径的图片 List absolutePathImageList = filePrintRegister.getElectronicImageList().stream() .filter(electronicImage -> StringUtils.isEmpty(electronicImage.getKeyWord())) .collect(Collectors.toList()); log.debug("执行绝对打合成操作,打印配置为{}.......", JSON.toJSON(absolutePathImageList)); //根据设置的绝对路径进行图片的填充 - addAbsolutePathStamp(wordOldUrl, wordOldUrl, absolutePathImageList); + addAbsolutePathStamp(wordOldUrl, absolutePathImageList); } catch (Exception ex) { log.error("关键字异常,异常信息{}", ex); } + addWatermark(wordOldUrl); } log.debug("执行完路径设置操作"); //如果有骑缝章新增骑缝章 return checkExtendSeal(wordOldUrl, selectSeal, filePrintRegister); } + private static void getQrCode(String tempDir, String customFileName, String wordOldUrl) throws IOException { + String urlPath = StringUtils.isNotEmpty(customFileName) ? customFileName + ".jpg" : "检测.jpg"; + String content = wordOldUrl.replaceAll(".docx", "pdf"); + // 加载模板 + OutputStream output = new FileOutputStream(tempDir + urlPath); + QRCodeUtil.getQRCode(tempDir + content, output); + } + /** * 检查是否需要骑缝章 * @@ -95,13 +108,19 @@ private static String checkExtendSeal(String wordOldUrl, ElectronicImage selectSeal, FilePrintRegister filePrintRegister) { if (ObjectUtils.isNotEmpty(selectSeal)) { //默认转为docx,只需要进行docx的替换即可 - String[] pdfUrl = filePrintRegister.getFileName().split("/."); - String pdfNewUrl = pdfUrl[0] + ".pdf"; + String pdfNewUrl = ""; + if (StringUtils.isEmpty(filePrintRegister.getCustomFileName())) { + String[] pdfUrl = filePrintRegister.getFileName().split("/.docx"); + pdfNewUrl = pdfUrl[0] + ".pdf"; + } else { + pdfNewUrl = filePrintRegister.getCustomFileName() + ".pdf"; + } String tempPdfUrl = filePrintRegister.getTemDir() + "XH" + pdfNewUrl; FilePrintRegisterUtils.wordToPdf(wordOldUrl, tempPdfUrl); DocPictureProvider.wordFullSeam(tempPdfUrl, selectSeal.getElectronicSealImageUrl(), filePrintRegister.getTemDir() + pdfNewUrl); return filePrintRegister.getTemDir() + pdfNewUrl; } + return wordOldUrl; } @@ -111,11 +130,9 @@ * 2、替换书签名位置文本内容 bookmarkName传参为null,则不进行书签替换操作 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 * @param sameKeyWordSealMaps 电子印章信息 */ - public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, String - wordNewUrl, Map> sameKeyWordSealMaps) throws RuntimeException { + public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, Map> sameKeyWordSealMaps) throws RuntimeException { ElectronicImage selectSeal = null; // 加载文档 Document document = new Document(); @@ -152,11 +169,56 @@ } } //保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); return selectSeal; } + private static void addWatermark(String wordOldUrl) { + Document doc = new Document(); + doc.loadFromFile(wordOldUrl); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("航天计量"); + shape.setFillColor(Color.LIGHT_GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; + + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } + doc.saveToFile(wordOldUrl); + } + } + /** * 替换书签名位置文本内容 * @@ -222,9 +284,8 @@ * 3、 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 */ - public static void addAbsolutePathStamp(String wordOldUrl, String wordNewUrl, List absolutePathImageList) { + public static void addAbsolutePathStamp(String wordOldUrl, List absolutePathImageList) { //加载文档 Document document = new Document(); document.loadFromFile(wordOldUrl); @@ -245,7 +306,7 @@ } } // 保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); } @@ -361,9 +422,9 @@ /** * 按照模板 填充数据生成word 只支持docx * - * @param temDir 生成文件的目录 -// * @param fileNames 待处理的文件列表 - * @param params 参数 + * @param temDir 生成文件的目录 + * // * @param fileNames 待处理的文件列表 + * @param params 参数 */ public static String exportWord(String temDir, String fileName, Map params, List mergeColNames, String customFileName) { //两个文档合并为fileNames[0]文档 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java index c5e47f6..06f5c41 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java @@ -40,6 +40,14 @@ imageConfig.setDocName(customizedSignNames.get(i)); approvalImageList.add(imageConfig); } + ImageConfig imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(0)); + imageConfig.setDocName("检测人"); + approvalImageList.add(imageConfig); + imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(1)); + imageConfig.setDocName("核验人"); + approvalImageList.add(imageConfig); return approvalImageList; } @@ -92,6 +100,7 @@ .build(); return electronicImage; } + /** * 自动生成是根据宽度设定取空隙平均值 * 默认电子签章的图片设置,允许重写 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java index 601612f..bf1108a 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java @@ -8,12 +8,14 @@ import com.casic.missiles.dto.business.file.FilePrintRegister; import com.casic.missiles.service.listeners.util.ParseWord07; import com.casic.missiles.service.listeners.util.PdfUtils; +import com.casic.missiles.utils.QRCodeUtil; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import com.spire.doc.*; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; +import com.spire.doc.fields.ShapeObject; import com.spire.doc.fields.TextRange; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -48,17 +50,19 @@ */ private final static Integer DEFAULT_SEAL_INDEX = 0; - private final static String INSIGNIA_KEYWORD = "公章"; + private final static String INSIGNIA_KEYWORD = "专用章"; /** * @param filePrintRegister 证书文件注册 */ - public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws RuntimeException { + public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws Exception { ElectronicImage selectSeal = null; //1、按照模板填充数据,并导出word,执行填充行数之后,再进行页数的填充 String wordOldUrl = exportWord(filePrintRegister.getTemDir(), filePrintRegister.getFileName(), filePrintRegister.getParams(), null, filePrintRegister.getCustomFileName()); + //预先生成二维码图片 + getQrCode(filePrintRegister.getTemDir(), filePrintRegister.getCustomFileName(), wordOldUrl); log.debug("执行完填充参数操作......"); if (CollectionUtils.isNotEmpty(filePrintRegister.getElectronicImageList())) { try { @@ -70,23 +74,32 @@ ); log.debug("执行关键字打合成操作,打印配置为{}.......", JSON.toJSON(sameKeyWordSealMaps)); //3、根据关键字进行添加签章和签字 - selectSeal = addSameKeyWordStamp(wordOldUrl, wordOldUrl, sameKeyWordSealMaps); + selectSeal = addSameKeyWordStamp(wordOldUrl, sameKeyWordSealMaps); //获取没有关键字的图片,即绝对路径的图片 List absolutePathImageList = filePrintRegister.getElectronicImageList().stream() .filter(electronicImage -> StringUtils.isEmpty(electronicImage.getKeyWord())) .collect(Collectors.toList()); log.debug("执行绝对打合成操作,打印配置为{}.......", JSON.toJSON(absolutePathImageList)); //根据设置的绝对路径进行图片的填充 - addAbsolutePathStamp(wordOldUrl, wordOldUrl, absolutePathImageList); + addAbsolutePathStamp(wordOldUrl, absolutePathImageList); } catch (Exception ex) { log.error("关键字异常,异常信息{}", ex); } + addWatermark(wordOldUrl); } log.debug("执行完路径设置操作"); //如果有骑缝章新增骑缝章 return checkExtendSeal(wordOldUrl, selectSeal, filePrintRegister); } + private static void getQrCode(String tempDir, String customFileName, String wordOldUrl) throws IOException { + String urlPath = StringUtils.isNotEmpty(customFileName) ? customFileName + ".jpg" : "检测.jpg"; + String content = wordOldUrl.replaceAll(".docx", "pdf"); + // 加载模板 + OutputStream output = new FileOutputStream(tempDir + urlPath); + QRCodeUtil.getQRCode(tempDir + content, output); + } + /** * 检查是否需要骑缝章 * @@ -95,13 +108,19 @@ private static String checkExtendSeal(String wordOldUrl, ElectronicImage selectSeal, FilePrintRegister filePrintRegister) { if (ObjectUtils.isNotEmpty(selectSeal)) { //默认转为docx,只需要进行docx的替换即可 - String[] pdfUrl = filePrintRegister.getFileName().split("/."); - String pdfNewUrl = pdfUrl[0] + ".pdf"; + String pdfNewUrl = ""; + if (StringUtils.isEmpty(filePrintRegister.getCustomFileName())) { + String[] pdfUrl = filePrintRegister.getFileName().split("/.docx"); + pdfNewUrl = pdfUrl[0] + ".pdf"; + } else { + pdfNewUrl = filePrintRegister.getCustomFileName() + ".pdf"; + } String tempPdfUrl = filePrintRegister.getTemDir() + "XH" + pdfNewUrl; FilePrintRegisterUtils.wordToPdf(wordOldUrl, tempPdfUrl); DocPictureProvider.wordFullSeam(tempPdfUrl, selectSeal.getElectronicSealImageUrl(), filePrintRegister.getTemDir() + pdfNewUrl); return filePrintRegister.getTemDir() + pdfNewUrl; } + return wordOldUrl; } @@ -111,11 +130,9 @@ * 2、替换书签名位置文本内容 bookmarkName传参为null,则不进行书签替换操作 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 * @param sameKeyWordSealMaps 电子印章信息 */ - public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, String - wordNewUrl, Map> sameKeyWordSealMaps) throws RuntimeException { + public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, Map> sameKeyWordSealMaps) throws RuntimeException { ElectronicImage selectSeal = null; // 加载文档 Document document = new Document(); @@ -152,11 +169,56 @@ } } //保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); return selectSeal; } + private static void addWatermark(String wordOldUrl) { + Document doc = new Document(); + doc.loadFromFile(wordOldUrl); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("航天计量"); + shape.setFillColor(Color.LIGHT_GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; + + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } + doc.saveToFile(wordOldUrl); + } + } + /** * 替换书签名位置文本内容 * @@ -222,9 +284,8 @@ * 3、 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 */ - public static void addAbsolutePathStamp(String wordOldUrl, String wordNewUrl, List absolutePathImageList) { + public static void addAbsolutePathStamp(String wordOldUrl, List absolutePathImageList) { //加载文档 Document document = new Document(); document.loadFromFile(wordOldUrl); @@ -245,7 +306,7 @@ } } // 保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); } @@ -361,9 +422,9 @@ /** * 按照模板 填充数据生成word 只支持docx * - * @param temDir 生成文件的目录 -// * @param fileNames 待处理的文件列表 - * @param params 参数 + * @param temDir 生成文件的目录 + * // * @param fileNames 待处理的文件列表 + * @param params 参数 */ public static String exportWord(String temDir, String fileName, Map params, List mergeColNames, String customFileName) { //两个文档合并为fileNames[0]文档 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java index 43cdd09..bd70cc2 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java @@ -26,7 +26,7 @@ int chunkHeight = image.getHeight() / cropPicture.getCutRows(); // System.out.println("图片的宽度为:" + chunkWidth * cropPicture.getCutRows() + "图片的高度为:" + chunkHeight * cropPicture.getCutCols());//230,278 BufferedImage imgs[] = new BufferedImage[chunks]; - for (int x = 0,count = 0; x < cropPicture.getCutRows(); x++) { + for (int x = 0, count = 0; x < cropPicture.getCutRows(); x++) { for (int y = 0; y < cropPicture.getCutCols(); y++) { //设置小图的大小和类型 imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType()); @@ -40,7 +40,7 @@ List subfileUrls = new ArrayList<>(); // 输出小图 for (int i = 0; i < imgs.length; i++) { - subfileUrls.add(cropPicture.getSubfileUrl() + i +"."+cropPicture.getSubfileType()); + subfileUrls.add(cropPicture.getSubfileUrl() + i + "." + cropPicture.getSubfileType()); ImageIO.write(imgs[i], cropPicture.getSubfileType(), new File(subfileUrls.get(subfileUrls.size() - 1))); System.out.println(i); } diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java index c5e47f6..06f5c41 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java @@ -40,6 +40,14 @@ imageConfig.setDocName(customizedSignNames.get(i)); approvalImageList.add(imageConfig); } + ImageConfig imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(0)); + imageConfig.setDocName("检测人"); + approvalImageList.add(imageConfig); + imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(1)); + imageConfig.setDocName("核验人"); + approvalImageList.add(imageConfig); return approvalImageList; } @@ -92,6 +100,7 @@ .build(); return electronicImage; } + /** * 自动生成是根据宽度设定取空隙平均值 * 默认电子签章的图片设置,允许重写 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java index 601612f..bf1108a 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java @@ -8,12 +8,14 @@ import com.casic.missiles.dto.business.file.FilePrintRegister; import com.casic.missiles.service.listeners.util.ParseWord07; import com.casic.missiles.service.listeners.util.PdfUtils; +import com.casic.missiles.utils.QRCodeUtil; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import com.spire.doc.*; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; +import com.spire.doc.fields.ShapeObject; import com.spire.doc.fields.TextRange; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -48,17 +50,19 @@ */ private final static Integer DEFAULT_SEAL_INDEX = 0; - private final static String INSIGNIA_KEYWORD = "公章"; + private final static String INSIGNIA_KEYWORD = "专用章"; /** * @param filePrintRegister 证书文件注册 */ - public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws RuntimeException { + public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws Exception { ElectronicImage selectSeal = null; //1、按照模板填充数据,并导出word,执行填充行数之后,再进行页数的填充 String wordOldUrl = exportWord(filePrintRegister.getTemDir(), filePrintRegister.getFileName(), filePrintRegister.getParams(), null, filePrintRegister.getCustomFileName()); + //预先生成二维码图片 + getQrCode(filePrintRegister.getTemDir(), filePrintRegister.getCustomFileName(), wordOldUrl); log.debug("执行完填充参数操作......"); if (CollectionUtils.isNotEmpty(filePrintRegister.getElectronicImageList())) { try { @@ -70,23 +74,32 @@ ); log.debug("执行关键字打合成操作,打印配置为{}.......", JSON.toJSON(sameKeyWordSealMaps)); //3、根据关键字进行添加签章和签字 - selectSeal = addSameKeyWordStamp(wordOldUrl, wordOldUrl, sameKeyWordSealMaps); + selectSeal = addSameKeyWordStamp(wordOldUrl, sameKeyWordSealMaps); //获取没有关键字的图片,即绝对路径的图片 List absolutePathImageList = filePrintRegister.getElectronicImageList().stream() .filter(electronicImage -> StringUtils.isEmpty(electronicImage.getKeyWord())) .collect(Collectors.toList()); log.debug("执行绝对打合成操作,打印配置为{}.......", JSON.toJSON(absolutePathImageList)); //根据设置的绝对路径进行图片的填充 - addAbsolutePathStamp(wordOldUrl, wordOldUrl, absolutePathImageList); + addAbsolutePathStamp(wordOldUrl, absolutePathImageList); } catch (Exception ex) { log.error("关键字异常,异常信息{}", ex); } + addWatermark(wordOldUrl); } log.debug("执行完路径设置操作"); //如果有骑缝章新增骑缝章 return checkExtendSeal(wordOldUrl, selectSeal, filePrintRegister); } + private static void getQrCode(String tempDir, String customFileName, String wordOldUrl) throws IOException { + String urlPath = StringUtils.isNotEmpty(customFileName) ? customFileName + ".jpg" : "检测.jpg"; + String content = wordOldUrl.replaceAll(".docx", "pdf"); + // 加载模板 + OutputStream output = new FileOutputStream(tempDir + urlPath); + QRCodeUtil.getQRCode(tempDir + content, output); + } + /** * 检查是否需要骑缝章 * @@ -95,13 +108,19 @@ private static String checkExtendSeal(String wordOldUrl, ElectronicImage selectSeal, FilePrintRegister filePrintRegister) { if (ObjectUtils.isNotEmpty(selectSeal)) { //默认转为docx,只需要进行docx的替换即可 - String[] pdfUrl = filePrintRegister.getFileName().split("/."); - String pdfNewUrl = pdfUrl[0] + ".pdf"; + String pdfNewUrl = ""; + if (StringUtils.isEmpty(filePrintRegister.getCustomFileName())) { + String[] pdfUrl = filePrintRegister.getFileName().split("/.docx"); + pdfNewUrl = pdfUrl[0] + ".pdf"; + } else { + pdfNewUrl = filePrintRegister.getCustomFileName() + ".pdf"; + } String tempPdfUrl = filePrintRegister.getTemDir() + "XH" + pdfNewUrl; FilePrintRegisterUtils.wordToPdf(wordOldUrl, tempPdfUrl); DocPictureProvider.wordFullSeam(tempPdfUrl, selectSeal.getElectronicSealImageUrl(), filePrintRegister.getTemDir() + pdfNewUrl); return filePrintRegister.getTemDir() + pdfNewUrl; } + return wordOldUrl; } @@ -111,11 +130,9 @@ * 2、替换书签名位置文本内容 bookmarkName传参为null,则不进行书签替换操作 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 * @param sameKeyWordSealMaps 电子印章信息 */ - public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, String - wordNewUrl, Map> sameKeyWordSealMaps) throws RuntimeException { + public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, Map> sameKeyWordSealMaps) throws RuntimeException { ElectronicImage selectSeal = null; // 加载文档 Document document = new Document(); @@ -152,11 +169,56 @@ } } //保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); return selectSeal; } + private static void addWatermark(String wordOldUrl) { + Document doc = new Document(); + doc.loadFromFile(wordOldUrl); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("航天计量"); + shape.setFillColor(Color.LIGHT_GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; + + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } + doc.saveToFile(wordOldUrl); + } + } + /** * 替换书签名位置文本内容 * @@ -222,9 +284,8 @@ * 3、 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 */ - public static void addAbsolutePathStamp(String wordOldUrl, String wordNewUrl, List absolutePathImageList) { + public static void addAbsolutePathStamp(String wordOldUrl, List absolutePathImageList) { //加载文档 Document document = new Document(); document.loadFromFile(wordOldUrl); @@ -245,7 +306,7 @@ } } // 保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); } @@ -361,9 +422,9 @@ /** * 按照模板 填充数据生成word 只支持docx * - * @param temDir 生成文件的目录 -// * @param fileNames 待处理的文件列表 - * @param params 参数 + * @param temDir 生成文件的目录 + * // * @param fileNames 待处理的文件列表 + * @param params 参数 */ public static String exportWord(String temDir, String fileName, Map params, List mergeColNames, String customFileName) { //两个文档合并为fileNames[0]文档 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java index 43cdd09..bd70cc2 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java @@ -26,7 +26,7 @@ int chunkHeight = image.getHeight() / cropPicture.getCutRows(); // System.out.println("图片的宽度为:" + chunkWidth * cropPicture.getCutRows() + "图片的高度为:" + chunkHeight * cropPicture.getCutCols());//230,278 BufferedImage imgs[] = new BufferedImage[chunks]; - for (int x = 0,count = 0; x < cropPicture.getCutRows(); x++) { + for (int x = 0, count = 0; x < cropPicture.getCutRows(); x++) { for (int y = 0; y < cropPicture.getCutCols(); y++) { //设置小图的大小和类型 imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType()); @@ -40,7 +40,7 @@ List subfileUrls = new ArrayList<>(); // 输出小图 for (int i = 0; i < imgs.length; i++) { - subfileUrls.add(cropPicture.getSubfileUrl() + i +"."+cropPicture.getSubfileType()); + subfileUrls.add(cropPicture.getSubfileUrl() + i + "." + cropPicture.getSubfileType()); ImageIO.write(imgs[i], cropPicture.getSubfileType(), new File(subfileUrls.get(subfileUrls.size() - 1))); System.out.println(i); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java index f0cde62..b0a45a0 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java @@ -13,6 +13,7 @@ import com.casic.missiles.utils.QRCodeUtil; import com.casic.missiles.utils.SpringContextUtil; import io.minio.MinioClient; +import liquibase.pro.packaged.E; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Workbook; @@ -93,14 +94,13 @@ //默认转为docx,只需要进行docx的替换即可 String pdfNewUrl = printDocUrl.replaceAll(WORD_SUFFIX, PDF_SUFFIX); FilePrintRegisterUtils.wordToPdf(printDocUrl, pdfNewUrl); - printDocUrl = pdfNewUrl; } } catch (Exception rex) { log.error("文件打印出现异常,打印参数信息为{},异常信息为{}", JSON.toJSON(registerParameters.getCustomObject()), rex); } finally { if (printDocUrl != null) { //如果文件路径不为空,回传文件流 - miniName = createResponseFileInput(printDocUrl, registerParameters.getResponse()); + miniName = createResponseFileInput(printDocUrl, registerParameters.getQrUrl(), registerParameters.getResponse()); } //删除无效的文件 File invalidFile = new File(tempLocalFileDir); @@ -115,7 +115,7 @@ /** * 拆分成excel和word格式开发, */ - private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) { + private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) throws Exception { //获取文件夹目录,没有则创建 tempLocalFileDir = tempLocalFileDir + filePrintRegister.getFileNameId() + File.separator; createLocalFileDir(tempLocalFileDir); diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java index c5e47f6..06f5c41 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java @@ -40,6 +40,14 @@ imageConfig.setDocName(customizedSignNames.get(i)); approvalImageList.add(imageConfig); } + ImageConfig imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(0)); + imageConfig.setDocName("检测人"); + approvalImageList.add(imageConfig); + imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(1)); + imageConfig.setDocName("核验人"); + approvalImageList.add(imageConfig); return approvalImageList; } @@ -92,6 +100,7 @@ .build(); return electronicImage; } + /** * 自动生成是根据宽度设定取空隙平均值 * 默认电子签章的图片设置,允许重写 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java index 601612f..bf1108a 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java @@ -8,12 +8,14 @@ import com.casic.missiles.dto.business.file.FilePrintRegister; import com.casic.missiles.service.listeners.util.ParseWord07; import com.casic.missiles.service.listeners.util.PdfUtils; +import com.casic.missiles.utils.QRCodeUtil; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import com.spire.doc.*; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; +import com.spire.doc.fields.ShapeObject; import com.spire.doc.fields.TextRange; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -48,17 +50,19 @@ */ private final static Integer DEFAULT_SEAL_INDEX = 0; - private final static String INSIGNIA_KEYWORD = "公章"; + private final static String INSIGNIA_KEYWORD = "专用章"; /** * @param filePrintRegister 证书文件注册 */ - public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws RuntimeException { + public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws Exception { ElectronicImage selectSeal = null; //1、按照模板填充数据,并导出word,执行填充行数之后,再进行页数的填充 String wordOldUrl = exportWord(filePrintRegister.getTemDir(), filePrintRegister.getFileName(), filePrintRegister.getParams(), null, filePrintRegister.getCustomFileName()); + //预先生成二维码图片 + getQrCode(filePrintRegister.getTemDir(), filePrintRegister.getCustomFileName(), wordOldUrl); log.debug("执行完填充参数操作......"); if (CollectionUtils.isNotEmpty(filePrintRegister.getElectronicImageList())) { try { @@ -70,23 +74,32 @@ ); log.debug("执行关键字打合成操作,打印配置为{}.......", JSON.toJSON(sameKeyWordSealMaps)); //3、根据关键字进行添加签章和签字 - selectSeal = addSameKeyWordStamp(wordOldUrl, wordOldUrl, sameKeyWordSealMaps); + selectSeal = addSameKeyWordStamp(wordOldUrl, sameKeyWordSealMaps); //获取没有关键字的图片,即绝对路径的图片 List absolutePathImageList = filePrintRegister.getElectronicImageList().stream() .filter(electronicImage -> StringUtils.isEmpty(electronicImage.getKeyWord())) .collect(Collectors.toList()); log.debug("执行绝对打合成操作,打印配置为{}.......", JSON.toJSON(absolutePathImageList)); //根据设置的绝对路径进行图片的填充 - addAbsolutePathStamp(wordOldUrl, wordOldUrl, absolutePathImageList); + addAbsolutePathStamp(wordOldUrl, absolutePathImageList); } catch (Exception ex) { log.error("关键字异常,异常信息{}", ex); } + addWatermark(wordOldUrl); } log.debug("执行完路径设置操作"); //如果有骑缝章新增骑缝章 return checkExtendSeal(wordOldUrl, selectSeal, filePrintRegister); } + private static void getQrCode(String tempDir, String customFileName, String wordOldUrl) throws IOException { + String urlPath = StringUtils.isNotEmpty(customFileName) ? customFileName + ".jpg" : "检测.jpg"; + String content = wordOldUrl.replaceAll(".docx", "pdf"); + // 加载模板 + OutputStream output = new FileOutputStream(tempDir + urlPath); + QRCodeUtil.getQRCode(tempDir + content, output); + } + /** * 检查是否需要骑缝章 * @@ -95,13 +108,19 @@ private static String checkExtendSeal(String wordOldUrl, ElectronicImage selectSeal, FilePrintRegister filePrintRegister) { if (ObjectUtils.isNotEmpty(selectSeal)) { //默认转为docx,只需要进行docx的替换即可 - String[] pdfUrl = filePrintRegister.getFileName().split("/."); - String pdfNewUrl = pdfUrl[0] + ".pdf"; + String pdfNewUrl = ""; + if (StringUtils.isEmpty(filePrintRegister.getCustomFileName())) { + String[] pdfUrl = filePrintRegister.getFileName().split("/.docx"); + pdfNewUrl = pdfUrl[0] + ".pdf"; + } else { + pdfNewUrl = filePrintRegister.getCustomFileName() + ".pdf"; + } String tempPdfUrl = filePrintRegister.getTemDir() + "XH" + pdfNewUrl; FilePrintRegisterUtils.wordToPdf(wordOldUrl, tempPdfUrl); DocPictureProvider.wordFullSeam(tempPdfUrl, selectSeal.getElectronicSealImageUrl(), filePrintRegister.getTemDir() + pdfNewUrl); return filePrintRegister.getTemDir() + pdfNewUrl; } + return wordOldUrl; } @@ -111,11 +130,9 @@ * 2、替换书签名位置文本内容 bookmarkName传参为null,则不进行书签替换操作 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 * @param sameKeyWordSealMaps 电子印章信息 */ - public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, String - wordNewUrl, Map> sameKeyWordSealMaps) throws RuntimeException { + public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, Map> sameKeyWordSealMaps) throws RuntimeException { ElectronicImage selectSeal = null; // 加载文档 Document document = new Document(); @@ -152,11 +169,56 @@ } } //保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); return selectSeal; } + private static void addWatermark(String wordOldUrl) { + Document doc = new Document(); + doc.loadFromFile(wordOldUrl); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("航天计量"); + shape.setFillColor(Color.LIGHT_GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; + + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } + doc.saveToFile(wordOldUrl); + } + } + /** * 替换书签名位置文本内容 * @@ -222,9 +284,8 @@ * 3、 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 */ - public static void addAbsolutePathStamp(String wordOldUrl, String wordNewUrl, List absolutePathImageList) { + public static void addAbsolutePathStamp(String wordOldUrl, List absolutePathImageList) { //加载文档 Document document = new Document(); document.loadFromFile(wordOldUrl); @@ -245,7 +306,7 @@ } } // 保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); } @@ -361,9 +422,9 @@ /** * 按照模板 填充数据生成word 只支持docx * - * @param temDir 生成文件的目录 -// * @param fileNames 待处理的文件列表 - * @param params 参数 + * @param temDir 生成文件的目录 + * // * @param fileNames 待处理的文件列表 + * @param params 参数 */ public static String exportWord(String temDir, String fileName, Map params, List mergeColNames, String customFileName) { //两个文档合并为fileNames[0]文档 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java index 43cdd09..bd70cc2 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java @@ -26,7 +26,7 @@ int chunkHeight = image.getHeight() / cropPicture.getCutRows(); // System.out.println("图片的宽度为:" + chunkWidth * cropPicture.getCutRows() + "图片的高度为:" + chunkHeight * cropPicture.getCutCols());//230,278 BufferedImage imgs[] = new BufferedImage[chunks]; - for (int x = 0,count = 0; x < cropPicture.getCutRows(); x++) { + for (int x = 0, count = 0; x < cropPicture.getCutRows(); x++) { for (int y = 0; y < cropPicture.getCutCols(); y++) { //设置小图的大小和类型 imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType()); @@ -40,7 +40,7 @@ List subfileUrls = new ArrayList<>(); // 输出小图 for (int i = 0; i < imgs.length; i++) { - subfileUrls.add(cropPicture.getSubfileUrl() + i +"."+cropPicture.getSubfileType()); + subfileUrls.add(cropPicture.getSubfileUrl() + i + "." + cropPicture.getSubfileType()); ImageIO.write(imgs[i], cropPicture.getSubfileType(), new File(subfileUrls.get(subfileUrls.size() - 1))); System.out.println(i); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java index f0cde62..b0a45a0 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java @@ -13,6 +13,7 @@ import com.casic.missiles.utils.QRCodeUtil; import com.casic.missiles.utils.SpringContextUtil; import io.minio.MinioClient; +import liquibase.pro.packaged.E; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Workbook; @@ -93,14 +94,13 @@ //默认转为docx,只需要进行docx的替换即可 String pdfNewUrl = printDocUrl.replaceAll(WORD_SUFFIX, PDF_SUFFIX); FilePrintRegisterUtils.wordToPdf(printDocUrl, pdfNewUrl); - printDocUrl = pdfNewUrl; } } catch (Exception rex) { log.error("文件打印出现异常,打印参数信息为{},异常信息为{}", JSON.toJSON(registerParameters.getCustomObject()), rex); } finally { if (printDocUrl != null) { //如果文件路径不为空,回传文件流 - miniName = createResponseFileInput(printDocUrl, registerParameters.getResponse()); + miniName = createResponseFileInput(printDocUrl, registerParameters.getQrUrl(), registerParameters.getResponse()); } //删除无效的文件 File invalidFile = new File(tempLocalFileDir); @@ -115,7 +115,7 @@ /** * 拆分成excel和word格式开发, */ - private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) { + private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) throws Exception { //获取文件夹目录,没有则创建 tempLocalFileDir = tempLocalFileDir + filePrintRegister.getFileNameId() + File.separator; createLocalFileDir(tempLocalFileDir); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java index 4487b65..6dde846 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java @@ -37,10 +37,9 @@ * @param printDocUrl 文件流路径,pdf,word * @param response */ - protected String createResponseFileInput(String printDocUrl, HttpServletResponse response) { + protected String createResponseFileInput(String printDocUrl, String customFileName, HttpServletResponse response) { if (response == null) { -// return null; - return uploadCertificate(printDocUrl); + return uploadCertificate(printDocUrl, customFileName); } File file = new File(printDocUrl); InputStream in = null; @@ -132,18 +131,18 @@ /** * 通过生成的证书报告,将证书报告上传到远程mini的文件服务器 */ - protected String uploadCertificate(String certificatePrintUrl) { + protected String uploadCertificate(String certificatePrintUrl, String customFileName) { //上传证书 File file = new File(certificatePrintUrl); //获取file对象的文件输入流 FileInputStream input = null; - List nameList = null; + String minioFileName = null; try { input = new FileInputStream(file); MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), MediaType.MULTIPART_FORM_DATA_VALUE, IOUtils.toByteArray(input)); - MultipartFile[] multipartFiles = new MultipartFile[1]; - multipartFiles[0] = multipartFile; - nameList = minioUtil.upload(multipartFiles); +// MultipartFile[] multipartFiles = new MultipartFile[1]; +// multipartFiles[0] = multipartFile; + minioFileName = minioUtil.uploadCustomName(multipartFile, customFileName); } catch (IOException ie) { log.error("Description Failed to upload the certificate to the server,the failed reason is {}...", ie); } finally { @@ -154,7 +153,7 @@ log.error("the upload Certificate input stream release is anomaly"); } } - return nameList.get(0); + return minioFileName; } } @@ -175,7 +174,7 @@ protected void deleteFile(File invalidFile) { //返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。 File[] files = invalidFile.listFiles(); - int length=files.length; + int length = files.length; if (files != null) {//如果包含文件进行删除操作 for (int i = 0; i < length; i++) { if (files[i].isFile()) { diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java index c5e47f6..06f5c41 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java @@ -40,6 +40,14 @@ imageConfig.setDocName(customizedSignNames.get(i)); approvalImageList.add(imageConfig); } + ImageConfig imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(0)); + imageConfig.setDocName("检测人"); + approvalImageList.add(imageConfig); + imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(1)); + imageConfig.setDocName("核验人"); + approvalImageList.add(imageConfig); return approvalImageList; } @@ -92,6 +100,7 @@ .build(); return electronicImage; } + /** * 自动生成是根据宽度设定取空隙平均值 * 默认电子签章的图片设置,允许重写 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java index 601612f..bf1108a 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java @@ -8,12 +8,14 @@ import com.casic.missiles.dto.business.file.FilePrintRegister; import com.casic.missiles.service.listeners.util.ParseWord07; import com.casic.missiles.service.listeners.util.PdfUtils; +import com.casic.missiles.utils.QRCodeUtil; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import com.spire.doc.*; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; +import com.spire.doc.fields.ShapeObject; import com.spire.doc.fields.TextRange; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -48,17 +50,19 @@ */ private final static Integer DEFAULT_SEAL_INDEX = 0; - private final static String INSIGNIA_KEYWORD = "公章"; + private final static String INSIGNIA_KEYWORD = "专用章"; /** * @param filePrintRegister 证书文件注册 */ - public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws RuntimeException { + public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws Exception { ElectronicImage selectSeal = null; //1、按照模板填充数据,并导出word,执行填充行数之后,再进行页数的填充 String wordOldUrl = exportWord(filePrintRegister.getTemDir(), filePrintRegister.getFileName(), filePrintRegister.getParams(), null, filePrintRegister.getCustomFileName()); + //预先生成二维码图片 + getQrCode(filePrintRegister.getTemDir(), filePrintRegister.getCustomFileName(), wordOldUrl); log.debug("执行完填充参数操作......"); if (CollectionUtils.isNotEmpty(filePrintRegister.getElectronicImageList())) { try { @@ -70,23 +74,32 @@ ); log.debug("执行关键字打合成操作,打印配置为{}.......", JSON.toJSON(sameKeyWordSealMaps)); //3、根据关键字进行添加签章和签字 - selectSeal = addSameKeyWordStamp(wordOldUrl, wordOldUrl, sameKeyWordSealMaps); + selectSeal = addSameKeyWordStamp(wordOldUrl, sameKeyWordSealMaps); //获取没有关键字的图片,即绝对路径的图片 List absolutePathImageList = filePrintRegister.getElectronicImageList().stream() .filter(electronicImage -> StringUtils.isEmpty(electronicImage.getKeyWord())) .collect(Collectors.toList()); log.debug("执行绝对打合成操作,打印配置为{}.......", JSON.toJSON(absolutePathImageList)); //根据设置的绝对路径进行图片的填充 - addAbsolutePathStamp(wordOldUrl, wordOldUrl, absolutePathImageList); + addAbsolutePathStamp(wordOldUrl, absolutePathImageList); } catch (Exception ex) { log.error("关键字异常,异常信息{}", ex); } + addWatermark(wordOldUrl); } log.debug("执行完路径设置操作"); //如果有骑缝章新增骑缝章 return checkExtendSeal(wordOldUrl, selectSeal, filePrintRegister); } + private static void getQrCode(String tempDir, String customFileName, String wordOldUrl) throws IOException { + String urlPath = StringUtils.isNotEmpty(customFileName) ? customFileName + ".jpg" : "检测.jpg"; + String content = wordOldUrl.replaceAll(".docx", "pdf"); + // 加载模板 + OutputStream output = new FileOutputStream(tempDir + urlPath); + QRCodeUtil.getQRCode(tempDir + content, output); + } + /** * 检查是否需要骑缝章 * @@ -95,13 +108,19 @@ private static String checkExtendSeal(String wordOldUrl, ElectronicImage selectSeal, FilePrintRegister filePrintRegister) { if (ObjectUtils.isNotEmpty(selectSeal)) { //默认转为docx,只需要进行docx的替换即可 - String[] pdfUrl = filePrintRegister.getFileName().split("/."); - String pdfNewUrl = pdfUrl[0] + ".pdf"; + String pdfNewUrl = ""; + if (StringUtils.isEmpty(filePrintRegister.getCustomFileName())) { + String[] pdfUrl = filePrintRegister.getFileName().split("/.docx"); + pdfNewUrl = pdfUrl[0] + ".pdf"; + } else { + pdfNewUrl = filePrintRegister.getCustomFileName() + ".pdf"; + } String tempPdfUrl = filePrintRegister.getTemDir() + "XH" + pdfNewUrl; FilePrintRegisterUtils.wordToPdf(wordOldUrl, tempPdfUrl); DocPictureProvider.wordFullSeam(tempPdfUrl, selectSeal.getElectronicSealImageUrl(), filePrintRegister.getTemDir() + pdfNewUrl); return filePrintRegister.getTemDir() + pdfNewUrl; } + return wordOldUrl; } @@ -111,11 +130,9 @@ * 2、替换书签名位置文本内容 bookmarkName传参为null,则不进行书签替换操作 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 * @param sameKeyWordSealMaps 电子印章信息 */ - public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, String - wordNewUrl, Map> sameKeyWordSealMaps) throws RuntimeException { + public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, Map> sameKeyWordSealMaps) throws RuntimeException { ElectronicImage selectSeal = null; // 加载文档 Document document = new Document(); @@ -152,11 +169,56 @@ } } //保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); return selectSeal; } + private static void addWatermark(String wordOldUrl) { + Document doc = new Document(); + doc.loadFromFile(wordOldUrl); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("航天计量"); + shape.setFillColor(Color.LIGHT_GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; + + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } + doc.saveToFile(wordOldUrl); + } + } + /** * 替换书签名位置文本内容 * @@ -222,9 +284,8 @@ * 3、 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 */ - public static void addAbsolutePathStamp(String wordOldUrl, String wordNewUrl, List absolutePathImageList) { + public static void addAbsolutePathStamp(String wordOldUrl, List absolutePathImageList) { //加载文档 Document document = new Document(); document.loadFromFile(wordOldUrl); @@ -245,7 +306,7 @@ } } // 保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); } @@ -361,9 +422,9 @@ /** * 按照模板 填充数据生成word 只支持docx * - * @param temDir 生成文件的目录 -// * @param fileNames 待处理的文件列表 - * @param params 参数 + * @param temDir 生成文件的目录 + * // * @param fileNames 待处理的文件列表 + * @param params 参数 */ public static String exportWord(String temDir, String fileName, Map params, List mergeColNames, String customFileName) { //两个文档合并为fileNames[0]文档 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java index 43cdd09..bd70cc2 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java @@ -26,7 +26,7 @@ int chunkHeight = image.getHeight() / cropPicture.getCutRows(); // System.out.println("图片的宽度为:" + chunkWidth * cropPicture.getCutRows() + "图片的高度为:" + chunkHeight * cropPicture.getCutCols());//230,278 BufferedImage imgs[] = new BufferedImage[chunks]; - for (int x = 0,count = 0; x < cropPicture.getCutRows(); x++) { + for (int x = 0, count = 0; x < cropPicture.getCutRows(); x++) { for (int y = 0; y < cropPicture.getCutCols(); y++) { //设置小图的大小和类型 imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType()); @@ -40,7 +40,7 @@ List subfileUrls = new ArrayList<>(); // 输出小图 for (int i = 0; i < imgs.length; i++) { - subfileUrls.add(cropPicture.getSubfileUrl() + i +"."+cropPicture.getSubfileType()); + subfileUrls.add(cropPicture.getSubfileUrl() + i + "." + cropPicture.getSubfileType()); ImageIO.write(imgs[i], cropPicture.getSubfileType(), new File(subfileUrls.get(subfileUrls.size() - 1))); System.out.println(i); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java index f0cde62..b0a45a0 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java @@ -13,6 +13,7 @@ import com.casic.missiles.utils.QRCodeUtil; import com.casic.missiles.utils.SpringContextUtil; import io.minio.MinioClient; +import liquibase.pro.packaged.E; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Workbook; @@ -93,14 +94,13 @@ //默认转为docx,只需要进行docx的替换即可 String pdfNewUrl = printDocUrl.replaceAll(WORD_SUFFIX, PDF_SUFFIX); FilePrintRegisterUtils.wordToPdf(printDocUrl, pdfNewUrl); - printDocUrl = pdfNewUrl; } } catch (Exception rex) { log.error("文件打印出现异常,打印参数信息为{},异常信息为{}", JSON.toJSON(registerParameters.getCustomObject()), rex); } finally { if (printDocUrl != null) { //如果文件路径不为空,回传文件流 - miniName = createResponseFileInput(printDocUrl, registerParameters.getResponse()); + miniName = createResponseFileInput(printDocUrl, registerParameters.getQrUrl(), registerParameters.getResponse()); } //删除无效的文件 File invalidFile = new File(tempLocalFileDir); @@ -115,7 +115,7 @@ /** * 拆分成excel和word格式开发, */ - private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) { + private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) throws Exception { //获取文件夹目录,没有则创建 tempLocalFileDir = tempLocalFileDir + filePrintRegister.getFileNameId() + File.separator; createLocalFileDir(tempLocalFileDir); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java index 4487b65..6dde846 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java @@ -37,10 +37,9 @@ * @param printDocUrl 文件流路径,pdf,word * @param response */ - protected String createResponseFileInput(String printDocUrl, HttpServletResponse response) { + protected String createResponseFileInput(String printDocUrl, String customFileName, HttpServletResponse response) { if (response == null) { -// return null; - return uploadCertificate(printDocUrl); + return uploadCertificate(printDocUrl, customFileName); } File file = new File(printDocUrl); InputStream in = null; @@ -132,18 +131,18 @@ /** * 通过生成的证书报告,将证书报告上传到远程mini的文件服务器 */ - protected String uploadCertificate(String certificatePrintUrl) { + protected String uploadCertificate(String certificatePrintUrl, String customFileName) { //上传证书 File file = new File(certificatePrintUrl); //获取file对象的文件输入流 FileInputStream input = null; - List nameList = null; + String minioFileName = null; try { input = new FileInputStream(file); MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), MediaType.MULTIPART_FORM_DATA_VALUE, IOUtils.toByteArray(input)); - MultipartFile[] multipartFiles = new MultipartFile[1]; - multipartFiles[0] = multipartFile; - nameList = minioUtil.upload(multipartFiles); +// MultipartFile[] multipartFiles = new MultipartFile[1]; +// multipartFiles[0] = multipartFile; + minioFileName = minioUtil.uploadCustomName(multipartFile, customFileName); } catch (IOException ie) { log.error("Description Failed to upload the certificate to the server,the failed reason is {}...", ie); } finally { @@ -154,7 +153,7 @@ log.error("the upload Certificate input stream release is anomaly"); } } - return nameList.get(0); + return minioFileName; } } @@ -175,7 +174,7 @@ protected void deleteFile(File invalidFile) { //返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。 File[] files = invalidFile.listFiles(); - int length=files.length; + int length = files.length; if (files != null) {//如果包含文件进行删除操作 for (int i = 0; i < length; i++) { if (files[i].isFile()) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java index 603200f..873513d 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java @@ -142,7 +142,7 @@ //添加二维码,在指定位置,添加公章等信息 if (!ObjectUtils.isEmpty(id)) { //写死 - ElectronicImage electronicImage = defaultElectronicImage("检定专用章"); + ElectronicImage electronicImage = defaultElectronicImage("专用章"); electronicImage.setIsSealImage(true); electronicImageSeals.add(doPopulateElectronicSignSeal(id, electronicImage, filePrintRegister)); @@ -152,7 +152,6 @@ electronicImage.setIsSealImage(true); electronicImageSeals.add(doPopulateQRCode(electronicImage, filePrintRegister)); - //添加电子认定章逻辑 if (StringUtils.isNotEmpty(approvalSignIds)) { String[] noKeyWordsSigns = approvalSignIds.split(","); @@ -221,7 +220,7 @@ * @return */ protected final ElectronicImage doPopulateQRCode(ElectronicImage electronicImage, FilePrintRegister filePrintRegister) { - String qrCodeName = "QrCode.jpg"; + String qrCodeName = StringUtils.isEmpty(filePrintRegister.getCustomFileName()) ? "检测.jpg":filePrintRegister.getCustomFileName()+".jpg"; //设置集合 electronicImage.setElectronicSealImageUrl(filePrintRegister.getTemDir() + qrCodeName); //放入待下载的文件集合 diff --git a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java index 40fea08..f910bd0 100644 --- a/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java +++ b/casic-metering-common/src/main/java/com/casic/missiles/utils/MinioUtil.java @@ -7,6 +7,7 @@ import io.minio.messages.DeleteObject; import io.minio.messages.Item; import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; @@ -107,6 +108,47 @@ } /** + * description: 自定义上传单个的文件名称 + * + * @param file + * @return: java.lang.String + */ + public String uploadCustomName(MultipartFile file, String customFileName) { + if (StringUtils.isEmpty(customFileName)) { + String fileName = file.getOriginalFilename(); + String[] split = fileName.split("\\."); + if (split.length > 1) { + fileName = split[0] + "_" + System.currentTimeMillis() + "." + split[1]; + } else { + fileName = fileName + System.currentTimeMillis(); + } + customFileName = fileName; + } + InputStream in = null; + try { + in = file.getInputStream(); + minioClient.putObject(PutObjectArgs.builder() + .bucket(bucketName) + .object(customFileName) + .stream(in, in.available(), -1) + .contentType(file.getContentType()) + .build() + ); + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return customFileName; + } + + /** * description: 上传文件 * * @param multipartFile @@ -152,7 +194,7 @@ * description: 下载文件 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public ResponseEntity download(String fileName) { ResponseEntity responseEntity = null; @@ -199,7 +241,7 @@ * description: 下载文件流 * * @param fileName - * @return: org.springframework.http.ResponseEntity + * @return: org.springframework.http.ResponseEntity */ public void downloadStream(String fileName, HttpServletResponse response) { InputStream in = null; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java index 3131969..0e5e23b 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/certificate/RegisterCustomParameters.java @@ -28,7 +28,7 @@ private String customFileName; /*** - * 二维码生成会记录,及名称 + * 二维码生成内容 */ private String QrUrl; diff --git a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java index f2b2383..7132a32 100644 --- a/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java +++ b/casic-metering-model/src/main/java/com/casic/missiles/dto/business/file/FilePrintRegister.java @@ -63,6 +63,17 @@ */ private Boolean templateWordType; + public void setElectronicImageList(List imageList) { + //健壮性校验 + if (CollectionUtil.isEmpty(imageList)) { + return; + } + if (CollectionUtil.isEmpty(electronicImageList)) { + electronicImageList = new ArrayList<>(); + } + electronicImageList.addAll(imageList); + } + public void setMergeColNames(List newMergeColNames) { //健壮性校验 if (CollectionUtil.isEmpty(newMergeColNames)) { diff --git a/casic-metering-service/pom.xml b/casic-metering-service/pom.xml index c837516..e41bb81 100644 --- a/casic-metering-service/pom.xml +++ b/casic-metering-service/pom.xml @@ -84,9 +84,20 @@ com.itextpdf itextpdf - 5.0.6 + 5.5.13 + + com.itextpdf + itext-asian + 5.2.0 + + + + org.apache.pdfbox + pdfbox + 2.0.24 + diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java index d2f433c..8a5e8fe 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/DocPictureProvider.java @@ -5,22 +5,25 @@ import com.casic.missiles.dto.business.certificate.ElectronicImage; import com.casic.missiles.dto.business.certificate.ImageConfig; import com.casic.missiles.dto.business.file.CropPicture; -import com.itextpdf.text.BadElementException; +import com.itextpdf.text.*; import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.*; +import com.spire.doc.Document; +import com.spire.doc.Section; import com.spire.doc.collections.RowCollection; -import com.spire.doc.documents.HorizontalAlignment; +import com.spire.doc.documents.*; import com.spire.doc.documents.Paragraph; -import com.spire.doc.documents.TextSelection; -import com.spire.doc.documents.TextWrappingStyle; import com.spire.doc.fields.DocPicture; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; @@ -244,6 +247,7 @@ (ObjectUtils.isNotEmpty(imageConfig.getColIndex()) && imageConfig.getColIndex() != -1)) { //指定电子章位置 Section section = textSelections[keyWordIndex].getAsOneRange().getDocument().getLastSection(); + docPicture.setFillColor(Color.white); //水平位置 docPicture.setHorizontalAlignment(ShapeHorizontalAlignment.Center); //垂直位置 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java index 7fc7114..96fae46 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/Example.java @@ -7,12 +7,33 @@ import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Element; +import com.itextpdf.text.Rectangle; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfContentByte; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import com.spire.doc.Document; import com.spire.doc.FileFormat; +import com.spire.doc.HeaderFooter; +import com.spire.doc.Section; +import com.spire.doc.documents.Paragraph; +import com.spire.doc.documents.ShapeLineStyle; +import com.spire.doc.documents.ShapeType; +import com.spire.doc.fields.ShapeObject; +import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; +import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.font.PDType1Font; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xwpf.usermodel.XWPFPicture; +import org.springframework.util.ResourceUtils; import javax.imageio.ImageIO; +import java.awt.*; +import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.io.*; import java.util.ArrayList; @@ -129,71 +150,92 @@ } } - /** - * 1、生成二维码图片 - * 2、二维码图片进行图片的合成 - * 3、 - * - * @param args - * @throws Exception - */ - public static void main(String[] args) throws Exception { - // 加载模板 - OutputStream output = new FileOutputStream("D:\\casic\\cut\\test.png"); - QRCodeUtil.getQRCode("D:\\casic\\cut\\1航天检定模版v1.xls", output); + public static void main(String[] args) { + //加载示例文档 + Document doc = new Document(); + doc.loadFromFile("D:\\casic\\cut\\123.docx"); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("长城计量"); + shape.setFillColor(Color.GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; - // 加载模板 - TemplateExportParams params = new TemplateExportParams( - "D:\\casic\\cut\\航天检定证书模板.xlsx"); - Map>> sheetsMap = new HashMap<>(); - // ****** 准备数据 ******* - // 日期 - -// for (int i = 0; i < 2; i++) { - List> list = new ArrayList(); - Map dateMap = new HashMap(); - dateMap.put("customerName", "2020-03-16"); - dateMap.put("sampleName", "1000"); - dateMap.put("sampleModelName", "100"); - dateMap.put("manufacturingNo", "50"); - dateMap.put("manufacturer", "100"); -// dateMap.put("sheetName", "sheet名称" + (i + 1)); - List MapList = new ArrayList<>(); - for (int j = 0; j < 2; j++) { - Map map = new HashMap(); - map.put("model", "123" + j); - map.put("manufacturingNo", "12345"); - map.put("range", "12345"); - map.put("grade", "12345"); - map.put("certificateNo", "12345"); - map.put("validDate", "2024/3/12"); - MapList.add(map); + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); } -// ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); -// BufferedImage bufferImg = ImageIO.read(BarcodeUtil.generateToStream("001")); -// ImageIO.write(bufferImg, "jpg", byteArrayOut); -// ImageEntity imageEntity = new ImageEntity(byteArrayOut.toByteArray(), 200, 1000); -// XWPFPicture image = new XWPFPicture(); -// //#2、这里是设置合并单元格,但是千万不要再模板你提前合并单元格。合并了这里会报错。行合并多少个格子在这里设置。 -// image.setRowspan(1);//向下合并三行 -// image.setColspan(1);//向右合并两列 -// //添加图片 -// image.setUrl("D:\\casic\\cut\\test.png"); -// dateMap.put("qr", image); -// // **** 准备数据结束**** -// dateMap.put("mapList", MapList); - list.add(dateMap); -// sheetsMap.put(i, list); -// } - try { - Workbook workbook = ExcelExportUtil.exportExcel(params,dateMap); - FileOutputStream fos = new FileOutputStream("D:\\casic\\cut\\test2.xlsx"); - workbook.write(fos); - fos.close(); - } catch (IOException ioe) { - System.out.println(""); + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } } - ; + //保存文档 + doc.saveToFile("D:\\casic\\cut\\111.docx", FileFormat.Docx_2013); } + public static void mainss(String[] args) throws IOException, DocumentException { + // 读取原始 PDF 文件 + PdfReader reader = new PdfReader("file:///D:/casic/cut/1.pdf"); + PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("D:\\casic\\cut\\output.pdf")); + // 获取 PDF 中的页数和页面大小 + int pageCount = reader.getNumberOfPages(); + Rectangle pageSize = reader.getPageSize(1); + // 添加水印到每个页面 + for (int i = 1; i <= pageCount; i++) { + addWatermark(stamper, i, pageSize); + } + // 保存修改后的 PDF 文件并关闭文件流 + stamper.close(); + reader.close(); + } + + private static void addWatermark(PdfStamper stamper, int pageNumber, Rectangle pageSize) throws DocumentException, IOException { + // 获取页面内容 + PdfContentByte contentByte = stamper.getUnderContent(pageNumber); + // 定义水印间隔 + float intervalX = 100; + float intervalY = 100; + //旋转角度 + float angle = 45; + // 添加水印 + contentByte.beginText(); + contentByte.setFontAndSize(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED), 16f); + contentByte.setColorFill(BaseColor.GRAY); + for (float x = -pageSize.getHeight(); x < pageSize.getWidth(); x += 3 * intervalX) { + for (float y = -pageSize.getHeight(); y < pageSize.getHeight(); y += 3 * intervalY) { + // 旋转坐标系 + contentByte.saveState(); + contentByte.concatCTM(AffineTransform.getRotateInstance(Math.toRadians(angle), x, y)); + // 显示水印 + contentByte.showTextAligned(Element.ALIGN_CENTER, "航天计量", x, y, 0); + // 恢复坐标系 + contentByte.restoreState(); + } + } + contentByte.endText(); + } } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java index c5e47f6..06f5c41 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FileImageTemplateProvider.java @@ -40,6 +40,14 @@ imageConfig.setDocName(customizedSignNames.get(i)); approvalImageList.add(imageConfig); } + ImageConfig imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(0)); + imageConfig.setDocName("检测人"); + approvalImageList.add(imageConfig); + imageConfig = new ImageConfig(); + imageConfig.setFiledName(keyParamList.get(1)); + imageConfig.setDocName("核验人"); + approvalImageList.add(imageConfig); return approvalImageList; } @@ -92,6 +100,7 @@ .build(); return electronicImage; } + /** * 自动生成是根据宽度设定取空隙平均值 * 默认电子签章的图片设置,允许重写 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java index 601612f..bf1108a 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/FilePrintRegisterUtils.java @@ -8,12 +8,14 @@ import com.casic.missiles.dto.business.file.FilePrintRegister; import com.casic.missiles.service.listeners.util.ParseWord07; import com.casic.missiles.service.listeners.util.PdfUtils; +import com.casic.missiles.utils.QRCodeUtil; import com.deepoove.poi.XWPFTemplate; import com.deepoove.poi.config.Configure; import com.deepoove.poi.config.ConfigureBuilder; import com.spire.doc.*; import com.spire.doc.documents.*; import com.spire.doc.fields.DocPicture; +import com.spire.doc.fields.ShapeObject; import com.spire.doc.fields.TextRange; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -48,17 +50,19 @@ */ private final static Integer DEFAULT_SEAL_INDEX = 0; - private final static String INSIGNIA_KEYWORD = "公章"; + private final static String INSIGNIA_KEYWORD = "专用章"; /** * @param filePrintRegister 证书文件注册 */ - public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws RuntimeException { + public static String filePrintGenerate(FilePrintRegister filePrintRegister) throws Exception { ElectronicImage selectSeal = null; //1、按照模板填充数据,并导出word,执行填充行数之后,再进行页数的填充 String wordOldUrl = exportWord(filePrintRegister.getTemDir(), filePrintRegister.getFileName(), filePrintRegister.getParams(), null, filePrintRegister.getCustomFileName()); + //预先生成二维码图片 + getQrCode(filePrintRegister.getTemDir(), filePrintRegister.getCustomFileName(), wordOldUrl); log.debug("执行完填充参数操作......"); if (CollectionUtils.isNotEmpty(filePrintRegister.getElectronicImageList())) { try { @@ -70,23 +74,32 @@ ); log.debug("执行关键字打合成操作,打印配置为{}.......", JSON.toJSON(sameKeyWordSealMaps)); //3、根据关键字进行添加签章和签字 - selectSeal = addSameKeyWordStamp(wordOldUrl, wordOldUrl, sameKeyWordSealMaps); + selectSeal = addSameKeyWordStamp(wordOldUrl, sameKeyWordSealMaps); //获取没有关键字的图片,即绝对路径的图片 List absolutePathImageList = filePrintRegister.getElectronicImageList().stream() .filter(electronicImage -> StringUtils.isEmpty(electronicImage.getKeyWord())) .collect(Collectors.toList()); log.debug("执行绝对打合成操作,打印配置为{}.......", JSON.toJSON(absolutePathImageList)); //根据设置的绝对路径进行图片的填充 - addAbsolutePathStamp(wordOldUrl, wordOldUrl, absolutePathImageList); + addAbsolutePathStamp(wordOldUrl, absolutePathImageList); } catch (Exception ex) { log.error("关键字异常,异常信息{}", ex); } + addWatermark(wordOldUrl); } log.debug("执行完路径设置操作"); //如果有骑缝章新增骑缝章 return checkExtendSeal(wordOldUrl, selectSeal, filePrintRegister); } + private static void getQrCode(String tempDir, String customFileName, String wordOldUrl) throws IOException { + String urlPath = StringUtils.isNotEmpty(customFileName) ? customFileName + ".jpg" : "检测.jpg"; + String content = wordOldUrl.replaceAll(".docx", "pdf"); + // 加载模板 + OutputStream output = new FileOutputStream(tempDir + urlPath); + QRCodeUtil.getQRCode(tempDir + content, output); + } + /** * 检查是否需要骑缝章 * @@ -95,13 +108,19 @@ private static String checkExtendSeal(String wordOldUrl, ElectronicImage selectSeal, FilePrintRegister filePrintRegister) { if (ObjectUtils.isNotEmpty(selectSeal)) { //默认转为docx,只需要进行docx的替换即可 - String[] pdfUrl = filePrintRegister.getFileName().split("/."); - String pdfNewUrl = pdfUrl[0] + ".pdf"; + String pdfNewUrl = ""; + if (StringUtils.isEmpty(filePrintRegister.getCustomFileName())) { + String[] pdfUrl = filePrintRegister.getFileName().split("/.docx"); + pdfNewUrl = pdfUrl[0] + ".pdf"; + } else { + pdfNewUrl = filePrintRegister.getCustomFileName() + ".pdf"; + } String tempPdfUrl = filePrintRegister.getTemDir() + "XH" + pdfNewUrl; FilePrintRegisterUtils.wordToPdf(wordOldUrl, tempPdfUrl); DocPictureProvider.wordFullSeam(tempPdfUrl, selectSeal.getElectronicSealImageUrl(), filePrintRegister.getTemDir() + pdfNewUrl); return filePrintRegister.getTemDir() + pdfNewUrl; } + return wordOldUrl; } @@ -111,11 +130,9 @@ * 2、替换书签名位置文本内容 bookmarkName传参为null,则不进行书签替换操作 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 * @param sameKeyWordSealMaps 电子印章信息 */ - public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, String - wordNewUrl, Map> sameKeyWordSealMaps) throws RuntimeException { + public static ElectronicImage addSameKeyWordStamp(String wordOldUrl, Map> sameKeyWordSealMaps) throws RuntimeException { ElectronicImage selectSeal = null; // 加载文档 Document document = new Document(); @@ -152,11 +169,56 @@ } } //保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); return selectSeal; } + private static void addWatermark(String wordOldUrl) { + Document doc = new Document(); + doc.loadFromFile(wordOldUrl); + //添加艺术字并设置大小 + ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text); + shape.setWidth(60); + shape.setHeight(20); + //设置艺术字文本内容、位置及样式 + shape.setVerticalPosition(30); + shape.setHorizontalPosition(20); + shape.setRotation(315); + shape.getWordArt().setFontFamily("黑体"); + shape.getWordArt().setText("航天计量"); + shape.setFillColor(Color.LIGHT_GRAY); + shape.setLineStyle(ShapeLineStyle.Single); + shape.setStrokeColor(new Color(192, 192, 192, 255)); + shape.setStrokeWeight(1); + Section section; + HeaderFooter header; + for (int n = 0; n < doc.getSections().getCount(); n++) { + section = doc.getSections().get(n); + //获取section的页眉 + header = section.getHeadersFooters().getHeader(); + Paragraph paragraph; + + if (header.getParagraphs().getCount() > 0) { + //如果页眉有段落,取它第一个段落 + paragraph = header.getParagraphs().get(0); + } else { + //否则新增加一个段落到页眉 + paragraph = header.addParagraph(); + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + //复制艺术字并设置多行多列位置 + shape = (ShapeObject) shape.deepClone(); + shape.setVerticalPosition(50 + 150 * i); + shape.setHorizontalPosition(20 + 160 * j); + paragraph.getChildObjects().add(shape); + } + } + doc.saveToFile(wordOldUrl); + } + } + /** * 替换书签名位置文本内容 * @@ -222,9 +284,8 @@ * 3、 * * @param wordOldUrl word文件路径 - * @param wordNewUrl 新word文件路径 */ - public static void addAbsolutePathStamp(String wordOldUrl, String wordNewUrl, List absolutePathImageList) { + public static void addAbsolutePathStamp(String wordOldUrl, List absolutePathImageList) { //加载文档 Document document = new Document(); document.loadFromFile(wordOldUrl); @@ -245,7 +306,7 @@ } } // 保存添加电子章的Word文档 - document.saveToFile(wordNewUrl); + document.saveToFile(wordOldUrl); document.dispose(); } @@ -361,9 +422,9 @@ /** * 按照模板 填充数据生成word 只支持docx * - * @param temDir 生成文件的目录 -// * @param fileNames 待处理的文件列表 - * @param params 参数 + * @param temDir 生成文件的目录 + * // * @param fileNames 待处理的文件列表 + * @param params 参数 */ public static String exportWord(String temDir, String fileName, Map params, List mergeColNames, String customFileName) { //两个文档合并为fileNames[0]文档 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java index 43cdd09..bd70cc2 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/ImageTool.java @@ -26,7 +26,7 @@ int chunkHeight = image.getHeight() / cropPicture.getCutRows(); // System.out.println("图片的宽度为:" + chunkWidth * cropPicture.getCutRows() + "图片的高度为:" + chunkHeight * cropPicture.getCutCols());//230,278 BufferedImage imgs[] = new BufferedImage[chunks]; - for (int x = 0,count = 0; x < cropPicture.getCutRows(); x++) { + for (int x = 0, count = 0; x < cropPicture.getCutRows(); x++) { for (int y = 0; y < cropPicture.getCutCols(); y++) { //设置小图的大小和类型 imgs[count] = new BufferedImage(chunkWidth, chunkHeight, image.getType()); @@ -40,7 +40,7 @@ List subfileUrls = new ArrayList<>(); // 输出小图 for (int i = 0; i < imgs.length; i++) { - subfileUrls.add(cropPicture.getSubfileUrl() + i +"."+cropPicture.getSubfileType()); + subfileUrls.add(cropPicture.getSubfileUrl() + i + "." + cropPicture.getSubfileType()); ImageIO.write(imgs[i], cropPicture.getSubfileType(), new File(subfileUrls.get(subfileUrls.size() - 1))); System.out.println(i); } diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java index f0cde62..b0a45a0 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileRegister.java @@ -13,6 +13,7 @@ import com.casic.missiles.utils.QRCodeUtil; import com.casic.missiles.utils.SpringContextUtil; import io.minio.MinioClient; +import liquibase.pro.packaged.E; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.apache.poi.ss.usermodel.Workbook; @@ -93,14 +94,13 @@ //默认转为docx,只需要进行docx的替换即可 String pdfNewUrl = printDocUrl.replaceAll(WORD_SUFFIX, PDF_SUFFIX); FilePrintRegisterUtils.wordToPdf(printDocUrl, pdfNewUrl); - printDocUrl = pdfNewUrl; } } catch (Exception rex) { log.error("文件打印出现异常,打印参数信息为{},异常信息为{}", JSON.toJSON(registerParameters.getCustomObject()), rex); } finally { if (printDocUrl != null) { //如果文件路径不为空,回传文件流 - miniName = createResponseFileInput(printDocUrl, registerParameters.getResponse()); + miniName = createResponseFileInput(printDocUrl, registerParameters.getQrUrl(), registerParameters.getResponse()); } //删除无效的文件 File invalidFile = new File(tempLocalFileDir); @@ -115,7 +115,7 @@ /** * 拆分成excel和word格式开发, */ - private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) { + private String populateWordPrintFile(String tempLocalFileDir, FilePrintRegister filePrintRegister, String customFileName) throws Exception { //获取文件夹目录,没有则创建 tempLocalFileDir = tempLocalFileDir + filePrintRegister.getFileNameId() + File.separator; createLocalFileDir(tempLocalFileDir); diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java index 4487b65..6dde846 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/PrintFileSupport.java @@ -37,10 +37,9 @@ * @param printDocUrl 文件流路径,pdf,word * @param response */ - protected String createResponseFileInput(String printDocUrl, HttpServletResponse response) { + protected String createResponseFileInput(String printDocUrl, String customFileName, HttpServletResponse response) { if (response == null) { -// return null; - return uploadCertificate(printDocUrl); + return uploadCertificate(printDocUrl, customFileName); } File file = new File(printDocUrl); InputStream in = null; @@ -132,18 +131,18 @@ /** * 通过生成的证书报告,将证书报告上传到远程mini的文件服务器 */ - protected String uploadCertificate(String certificatePrintUrl) { + protected String uploadCertificate(String certificatePrintUrl, String customFileName) { //上传证书 File file = new File(certificatePrintUrl); //获取file对象的文件输入流 FileInputStream input = null; - List nameList = null; + String minioFileName = null; try { input = new FileInputStream(file); MultipartFile multipartFile = new MockMultipartFile("file", file.getName(), MediaType.MULTIPART_FORM_DATA_VALUE, IOUtils.toByteArray(input)); - MultipartFile[] multipartFiles = new MultipartFile[1]; - multipartFiles[0] = multipartFile; - nameList = minioUtil.upload(multipartFiles); +// MultipartFile[] multipartFiles = new MultipartFile[1]; +// multipartFiles[0] = multipartFile; + minioFileName = minioUtil.uploadCustomName(multipartFile, customFileName); } catch (IOException ie) { log.error("Description Failed to upload the certificate to the server,the failed reason is {}...", ie); } finally { @@ -154,7 +153,7 @@ log.error("the upload Certificate input stream release is anomaly"); } } - return nameList.get(0); + return minioFileName; } } @@ -175,7 +174,7 @@ protected void deleteFile(File invalidFile) { //返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。 File[] files = invalidFile.listFiles(); - int length=files.length; + int length = files.length; if (files != null) {//如果包含文件进行删除操作 for (int i = 0; i < length; i++) { if (files[i].isFile()) { diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java index 603200f..873513d 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/PrintFileApprovalDataSupport.java @@ -142,7 +142,7 @@ //添加二维码,在指定位置,添加公章等信息 if (!ObjectUtils.isEmpty(id)) { //写死 - ElectronicImage electronicImage = defaultElectronicImage("检定专用章"); + ElectronicImage electronicImage = defaultElectronicImage("专用章"); electronicImage.setIsSealImage(true); electronicImageSeals.add(doPopulateElectronicSignSeal(id, electronicImage, filePrintRegister)); @@ -152,7 +152,6 @@ electronicImage.setIsSealImage(true); electronicImageSeals.add(doPopulateQRCode(electronicImage, filePrintRegister)); - //添加电子认定章逻辑 if (StringUtils.isNotEmpty(approvalSignIds)) { String[] noKeyWordsSigns = approvalSignIds.split(","); @@ -221,7 +220,7 @@ * @return */ protected final ElectronicImage doPopulateQRCode(ElectronicImage electronicImage, FilePrintRegister filePrintRegister) { - String qrCodeName = "QrCode.jpg"; + String qrCodeName = StringUtils.isEmpty(filePrintRegister.getCustomFileName()) ? "检测.jpg":filePrintRegister.getCustomFileName()+".jpg"; //设置集合 electronicImage.setElectronicSealImageUrl(filePrintRegister.getTemDir() + qrCodeName); //放入待下载的文件集合 diff --git a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/certificate/CertificateReportApprovalData.java b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/certificate/CertificateReportApprovalData.java index b465431..6f0152a 100644 --- a/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/certificate/CertificateReportApprovalData.java +++ b/casic-metering-service/src/main/java/com/casic/missiles/service/listeners/register/data/certificate/CertificateReportApprovalData.java @@ -53,6 +53,7 @@ List approvalImageList = customizedSignNamesParamCreator(); //初始化,生成模板文件 FilePrintRegister filePrintRegister = initialization(templateFileDir, metaData.getId(), metaData.getCertificateReportFile()); + filePrintRegister.setCustomFileName(registerParameters.getCustomFileName()); filePrintRegister.setParams(new HashMap()); //定制化签名开发 List electronicSignList = this.createSignNames(ApprovalLogMap, filePrintRegister, approvalImageList);