Browse Source

1、图片与pdf互转功能实现

master
Aug 3 months ago
parent
commit
ad66cea837
5 changed files with 155 additions and 167 deletions
  1. +2
    -2
      jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java
  2. +5
    -8
      jeecg-boot-module-system/jeecg-boot-module-system.iml
  3. +4
    -16
      jeecg-boot-module-system/pom.xml
  4. +143
    -140
      jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/ContractServiceImpl.java
  5. +1
    -1
      jeecg-boot-module-system/src/main/resources/application-dev.yml

+ 2
- 2
jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/common/util/oss/OssBootUtil.java View File

@ -85,7 +85,7 @@ public class OssBootUtil {
/** /**
* oss 工具客户端 * oss 工具客户端
*/ */
private static OSSClient ossClient = null;
public static OSSClient ossClient = null;
/** /**
* 上传文件至阿里云 OSS * 上传文件至阿里云 OSS
@ -309,7 +309,7 @@ public class OssBootUtil {
* *
* @return * @return
*/ */
private static OSSClient initOss(String endpoint, String accessKeyId, String accessKeySecret) {
public static OSSClient initOss(String endpoint, String accessKeyId, String accessKeySecret) {
if (ossClient == null) { if (ossClient == null) {
ossClient = new OSSClient(endpoint, ossClient = new OSSClient(endpoint,
new DefaultCredentialProvider(accessKeyId, accessKeySecret), new DefaultCredentialProvider(accessKeyId, accessKeySecret),


+ 5
- 8
jeecg-boot-module-system/jeecg-boot-module-system.iml View File

@ -170,7 +170,6 @@
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.9" level="project" /> <orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.9" level="project" />
<orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" /> <orderEntry type="library" name="Maven: net.sf.json-lib:json-lib:jdk15:2.4" level="project" />
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" /> <orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.1" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.1.1" level="project" />
<orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" /> <orderEntry type="library" name="Maven: net.sf.ezmorph:ezmorph:1.0.6" level="project" />
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" /> <orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.36" level="project" />
<orderEntry type="library" name="Maven: org.jdom:jdom:1.1" level="project" /> <orderEntry type="library" name="Maven: org.jdom:jdom:1.1" level="project" />
@ -286,15 +285,13 @@
<orderEntry type="library" name="Maven: org.jodd:jodd-upload:3.7.1" level="project" /> <orderEntry type="library" name="Maven: org.jodd:jodd-upload:3.7.1" level="project" />
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" /> <orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
<orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.4" level="project" /> <orderEntry type="library" name="Maven: commons-beanutils:commons-beanutils:1.9.4" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.59" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.59" level="project" />
<orderEntry type="library" name="Maven: com.github.binarywang:weixin-java-miniapp:3.5.0" level="project" /> <orderEntry type="library" name="Maven: com.github.binarywang:weixin-java-miniapp:3.5.0" level="project" />
<orderEntry type="library" name="Maven: com.github.binarywang:weixin-java-mp:3.5.0" level="project" /> <orderEntry type="library" name="Maven: com.github.binarywang:weixin-java-mp:3.5.0" level="project" />
<orderEntry type="library" name="Maven: com.itextpdf:itextpdf:5.5.13" level="project" />
<orderEntry type="library" name="Maven: com.itextpdf:itext-asian:5.2.0" level="project" />
<orderEntry type="library" name="Maven: org.icepdf.os:icepdf-core:6.1.2" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-jdk15on:1.54" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcprov-ext-jdk15on:1.54" level="project" />
<orderEntry type="library" name="Maven: org.bouncycastle:bcpkix-jdk15on:1.54" level="project" />
<orderEntry type="library" name="Maven: javax.media:jai-core:1.1.3" level="project" />
<orderEntry type="library" name="Maven: org.apache.pdfbox:pdfbox:2.0.27" level="project" />
<orderEntry type="library" name="Maven: org.apache.pdfbox:fontbox:2.0.27" level="project" />
<orderEntry type="library" name="Maven: commons-logging:commons-logging:1.2" level="project" />
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.6.6" level="project" /> <orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.6.6" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.6" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.6.6" level="project" />
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.6" level="project" /> <orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.6.6" level="project" />


+ 4
- 16
jeecg-boot-module-system/pom.xml View File

@ -74,23 +74,11 @@
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!--pdf添加水印、文字、图片、印章-->
<!--pdf工具类-->
<dependency> <dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
<!--pdf转图片-->
<dependency>
<groupId>org.icepdf.os</groupId>
<artifactId>icepdf-core</artifactId>
<version>6.1.2</version>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.27</version>
</dependency> </dependency>
</dependencies> </dependencies>


+ 143
- 140
jeecg-boot-module-system/src/main/java/org/jeecg/modules/apiService/impl/ContractServiceImpl.java View File

@ -1,14 +1,15 @@
package org.jeecg.modules.apiService.impl; package org.jeecg.modules.apiService.impl;
import com.aliyuncs.utils.IOUtils;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import org.icepdf.core.util.GraphicsRenderingHints;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.jeecg.common.api.vo.Result; import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.oss.OssBootUtil;
import org.jeecg.config.shiro.ShiroRealm; import org.jeecg.config.shiro.ShiroRealm;
import org.jeecg.modules.apiBean.PageBean; import org.jeecg.modules.apiBean.PageBean;
import org.jeecg.modules.apiService.ContractService; import org.jeecg.modules.apiService.ContractService;
@ -20,17 +21,14 @@ import org.jeecg.modules.employContract.entity.EmployContract;
import org.jeecg.modules.employContract.service.IEmployContractService; import org.jeecg.modules.employContract.service.IEmployContractService;
import org.jeecg.modules.employContractTemplate.entity.EmployContractTemplate; import org.jeecg.modules.employContractTemplate.entity.EmployContractTemplate;
import org.jeecg.modules.employContractTemplate.service.IEmployContractTemplateService; import org.jeecg.modules.employContractTemplate.service.IEmployContractTemplateService;
import org.jeecg.modules.employResume.entity.EmployResume;
import org.jeecg.modules.employResume.service.IEmployResumeService;
import org.jeecg.modules.hanHaiMember.entity.HanHaiMember; import org.jeecg.modules.hanHaiMember.entity.HanHaiMember;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.*; import java.io.*;
import java.net.URL;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
@ -57,10 +55,6 @@ public class ContractServiceImpl implements ContractService {
//个人实名认证表 //个人实名认证表
@Resource @Resource
private IEmployAuthenticationPersonService authenticationPersonService; private IEmployAuthenticationPersonService authenticationPersonService;
//简历信息表
@Resource
private IEmployResumeService employResumeService;
/******************************************************************************************************************/ /******************************************************************************************************************/
//电子合同-获取电子合同列表 //电子合同-获取电子合同列表
@ -338,154 +332,163 @@ public class ContractServiceImpl implements ContractService {
} }
} }
/*********************************************图片与pdf互转*********************************************************/
//pdf转图片base64(一张pdf转成多个base64图片)
//pdf转图片base64
@Override @Override
public Result<?> pdf2imagebase64(String pdfPath){
//String pdfPath = "F:\\upload\\test_1736767131255.pdf";//pdf文件路径
//获取当前时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Date now = new Date();
String formattedDate = sdf.format(now);
System.out.println(formattedDate);
String imagePath = "F:\\temp\\";//图片文件路径
String fileName = formattedDate +"image_";//图片文件名字
//文件流对象
InputStream in = null;
public Result<?> pdf2imagebase64(String pdfPath) {
List<String> pathList = new ArrayList<>();//图片路径列表
List<String> codeList = new ArrayList<>();//base64列表
List<String> imageBase = null;//图片base64
try{
imageBase = convertPdfToBase64(pdfPath);
}catch (Exception e){
e.printStackTrace();
return Result.error("pdf转图片base64失败");
}
return Result.OK("图片base64", imageBase);
Map<String, Object> map = new HashMap<>();
}
//图片转pdf
@Override
public Result<?> image2pdf(String images) {
String pdfUrl = null;
try{ try{
org.icepdf.core.pobjects.Document document = new org.icepdf.core.pobjects.Document();
document.setFile(pdfPath);
float scale = 2.5f;//缩放比例
float rotation = 0f;//旋转角度
//pdf转图片
for (int i = 0; i < document.getNumberOfPages(); i++) {
BufferedImage image = (BufferedImage)
document.getPageImage(i, GraphicsRenderingHints.SCREEN, org.icepdf.core.pobjects.Page.BOUNDARY_CROPBOX, rotation, scale);
RenderedImage rendImage = image;
File fileDir = new File(imagePath);
if (!fileDir.exists()) {
fileDir.mkdirs();
}
String imgName = fileName + i + ".png";//图片名称
String filePath = imagePath + imgName;//图片文件路径
File file = new File(filePath);
ImageIO.write(rendImage, "png", file);
image.flush();
pathList.add(filePath);
}
document.dispose();//关闭流
//图片转base64
for (String path : pathList) {
String imgFile = path;// 待处理的图片
byte[] data = null;
String encode = null; // 返回Base64编码过的字节数组字符串
BASE64Encoder encoder = new BASE64Encoder();// 对字节数组Base64编码
// 读取图片字节数组
in = new FileInputStream(imgFile);
data = new byte[in.available()];
in.read(data);
encode = encoder.encode(data);
codeList.add(encode);
}
return Result.OK("pdf转图片base64成功", codeList);
// TODO 目前是本地路径项目中定义临时路径然后进行转换成 File
String outPutPath = System.getProperty("java.io.tmpdir") + File.separator + "resultPdf.pdf";
List<String> imageUrlList = Arrays.asList(images.split(";"));
convertImagesToPDF(imageUrlList,outPutPath);
// 将输出路径转换成 File后续进行 OSS 上传
File file = new File(outPutPath);
InputStream inputStream = new FileInputStream(file);
//获取当前时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Date now = new Date();
String formattedDate = sdf.format(now);
pdfUrl = OssBootUtil.upload(inputStream, formattedDate+".pdf");
//删除临时文件
file.delete();
}catch (Exception e){ }catch (Exception e){
e.printStackTrace(); e.printStackTrace();
return Result.error("pdf转图片base64失败", codeList);
}finally {
try{
if(null != in){
in.close();//关闭文件流
}
}catch (Exception e){
e.printStackTrace();
return Result.error("pdf转图片base64失败", codeList);
}
return Result.error("图片转pdf失败");
} }
return Result.OK("pdf地址", pdfUrl);
} }
/**
* pdf链接文件转换成多图片base64
* @param pdfLink
* @return
* @throws IOException
*/
public static List<String> convertPdfToBase64(String pdfLink) throws IOException {
List<String> base64Images = new ArrayList<>();
//图片转pdf
public Result<?> image2pdf(String images){
// 下载 PDF 文件
InputStream pdfInputStream = new URL(pdfLink).openStream();
//获取当前时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
Date now = new Date();
String formattedDate = sdf.format(now);
System.out.println(formattedDate);
// 加载 PDF 文档
PDDocument document = PDDocument.load(pdfInputStream);
//String images = "F:\\temp\\image_0.png;F:\\temp\\image_1.png;F:\\temp\\image_2.png";//图片文件地址
String pdfPath = "F:\\temp\\"+formattedDate+".pdf"; // 输出pdf文件路径
String[] imageList = images.split(";");
// 初始化 PDF 渲染器
PDFRenderer pdfRenderer = new PDFRenderer(document);
try{
ArrayList<String> imageUrllist = new ArrayList<String>(); //图片list集合
for (int i=0; i<imageList.length; i++) {
imageUrllist.add(imageList[i]);
}
// 遍历 PDF 每一页并转换为 Base64 编码的图片
for (int pageIndex = 0; pageIndex < document.getNumberOfPages(); pageIndex++) {
// 渲染当前页面并转成 BufferedImage
BufferedImage image = pdfRenderer.renderImage(pageIndex, 2.0f); // 2.0f 对应于 200 DPI调整为需要的分辨率
File file = Pdf(imageUrllist, pdfPath);//生成pdf
file.createNewFile();
// 将图片转换为 Base64
String base64Image = convertImageToBase64(image);
base64Images.add(base64Image);
}
return Result.OK("图片转pdf成功", pdfPath);
}catch (Exception e){
e.printStackTrace();
document.close(); // 关闭文档流
IOUtils.closeQuietly(pdfInputStream); // 关闭输入流
return Result.error("图片转pdf失败", pdfPath);
}
return base64Images;
}
/**
* 图片转换成 base64
* @param image
* @return
* @throws IOException
*/
private static String convertImageToBase64(BufferedImage image) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "PNG", byteArrayOutputStream);
byte[] imageBytes = byteArrayOutputStream.toByteArray();
return Base64.getEncoder().encodeToString(imageBytes);
} }
//生成pdf
public static File Pdf(ArrayList<String> imageUrllist, String mOutputPdfFileName) {
Document doc = new Document(PageSize.A4, 0, 0, 0, 0); //new一个pdf文档
try {
PdfWriter.getInstance(doc, new FileOutputStream(mOutputPdfFileName)); //pdf写入
doc.open();//打开文档
for (int i = 0; i < imageUrllist.size(); i++) { //循环图片List将图片加入到pdf中
doc.newPage(); //在pdf创建一页
Image png1 = Image.getInstance(imageUrllist.get(i)); //通过文件路径获取image
float heigth = png1.getHeight();
float width = png1.getWidth();
int percent = getPercent2(heigth, width);
png1.setAlignment(Image.MIDDLE);
png1.scalePercent(percent + 3);// 表示是原来图像的比例;
doc.add(png1);
}
doc.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
File mOutputPdfFile = new File(mOutputPdfFileName); //输出流
if (!mOutputPdfFile.exists()) {
mOutputPdfFile.deleteOnExit();
return null;
/**
* 多图片拼接成pdf
* @param imageUrls
* @param outputPdfPath 输出地址
* @throws Exception
*/
public static void convertImagesToPDF(List<String> imageUrls, String outputPdfPath) throws Exception {
// 创建 PDF 文档
PDDocument document = new PDDocument();
for (String imageUrl : imageUrls) {
// 创建一个新的页面
PDPage page = new PDPage();
document.addPage(page);
// 获取图片
InputStream imageStream = new URL(imageUrl).openStream();
PDImageXObject pdImage = createImageFromInputStream(document, imageStream);
// 创建内容流
PDPageContentStream contentStream = new PDPageContentStream(document, page);
// 获取图片宽高计算缩放比例
float imageWidth = pdImage.getWidth();
float imageHeight = pdImage.getHeight();
// 根据 PDF 页面大小调整图片大小
float pageWidth = page.getMediaBox().getWidth();
float pageHeight = page.getMediaBox().getHeight();
// 按比例缩放图片
float scaleFactor = Math.min(pageWidth / imageWidth, pageHeight / imageHeight);
float scaledWidth = imageWidth * scaleFactor;
float scaledHeight = imageHeight * scaleFactor;
// 设置图片的位置
float x = (pageWidth - scaledWidth) / 2;
float y = (pageHeight - scaledHeight) / 2;
// 绘制图片
contentStream.drawImage(pdImage, x, y, scaledWidth, scaledHeight);
// 关闭内容流
contentStream.close();
} }
return mOutputPdfFile; //反回文件输出流
}
public static int getPercent2(float h, float w) {
int p = 0;
float p2 = 0.0f;
p2 = 530 / w * 100;
p = Math.round(p2);
return p;
document.save(outputPdfPath);
document.close();
} }
/**
* 将图片转换成PDImageXObject对象操作
* @param document
* @param imageStream
* @return
* @throws IOException
*/
public static PDImageXObject createImageFromInputStream(PDDocument document, InputStream imageStream) throws IOException {
// 使用 ByteArrayOutputStream 读取 InputStream 中的数据
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = imageStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
}
// 将字节数组传给 PDFBox 创建图片对象
return PDImageXObject.createFromByteArray(document, byteArrayOutputStream.toByteArray(), "image");
}
} }

+ 1
- 1
jeecg-boot-module-system/src/main/resources/application-dev.yml View File

@ -196,7 +196,7 @@ jeecg :
secretKey: perarQgbRK9TPNNb2G97EojoJ6kb9H secretKey: perarQgbRK9TPNNb2G97EojoJ6kb9H
endpoint: oss-cn-beijing.aliyuncs.com endpoint: oss-cn-beijing.aliyuncs.com
bucketName: teyizhaoimg bucketName: teyizhaoimg
staticDomain: https://img.teyizhao.com/
staticDomain: https://img.teyizhao.com
# ElasticSearch 6设置 # ElasticSearch 6设置
elasticsearch: elasticsearch:
cluster-name: jeecg-ES cluster-name: jeecg-ES


Loading…
Cancel
Save