java 图片合并pdf

依赖

		<!--html转pdf工具 itext7 html2pdf -->
		<dependency>
			<groupId>com.itextpdf</groupId>
			<artifactId>html2pdf</artifactId>
			<version>3.0.2</version>
		</dependency>

		<!-- only needed for Asian fonts -->
		<dependency>
			<groupId>com.itextpdf</groupId>
			<artifactId>font-asian</artifactId>
			<version>7.1.13</version>
		</dependency>
		//todo str转jsonarray
		List<ImagePathData> dataList =  JSONUtil.toList(dto.getBase64Json(),ImagePathData.class);
		// 根据 fileId 进行分组
		Map<Long, List<ImagePathData>> groupedData = dataList.stream()
				.collect(Collectors.groupingBy(ImagePathData::getFileId));
		// 打印每个分组的数据
		groupedData.forEach((fileId, group) -> {
			InputStream inputStream = pdfUtilService.getPdfInputStream(group.get(0).getFileId());
			for (ImagePathData imagePathData : group) {
				inputStream = pdfUtilService.imageOverlayPdfStream(imagePathData.getBase64(),imagePathData.getPage(),imagePathData.getLeftX(),imagePathData.getBottomY(), imagePathData.getWidth(),imagePathData.getHeight(),inputStream);
			}
		});

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.json.JSONUtil;
import cn.tsit.whzb.admin.api.feign.RemoteFileService;
import cn.tsit.whzb.common.core.constant.SecurityConstants;
import cn.tsit.whzb.common.core.util.R;
import cn.tsit.whzb.server.util.ImagePathData;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.WriterProperties;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfImageXObject;
import com.itextpdf.kernel.utils.PdfMerger;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Image;
//import fr.opensagres.poi.xwpf.converter.pdf.PdfConverter;
//import fr.opensagres.poi.xwpf.converter.pdf.PdfOptions;
import io.swagger.v3.oas.models.security.SecurityScheme;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
//import org.ofdrw.converter.ConvertHelper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;

@Service
public class PdfUtilService {


	//单张插入
	public InputStream merg(List<ImagePathData> imagePathList,Long fileId) throws IOException {
		List<InputStream> sources = new ArrayList<>();
		InputStream sourcepdf = getPdfInputStream(fileId);
		InputStream sourcepdfA = getPdfInputStream(fileId);
		List<InputStream> imagepdfs = null;


		//todo 获取一个新的pdf
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		PdfWriter writer = new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(Boolean.TRUE));
		PdfDocument pdfDocument = new PdfDocument(writer);
		PdfMerger merger = new PdfMerger(pdfDocument);
		//
		imagePathList.forEach(imageData -> {
			imageData.setImageStream(imageTopdf(imageData.getBase64()));
		});

		Integer last = 0;
		List<ImagePathData> lists = getllll(imagePathList);
		for (ImagePathData pathData : lists) {
			if(!pathData.getOoo()){
				PdfDocument imagepdf = new PdfDocument(new PdfReader(pathData.getImageStream()));
				merger.merge(imagepdf,1,1);
				imagepdf.close();
			}else {
				PdfDocument source = new PdfDocument(new PdfReader(sourcepdf));
				merger.merge(source,pathData.getX(),pathData.getY());
				source.close();
			}
			last = pathData.getPage();
		}
		PdfDocument source = new PdfDocument(new PdfReader(sourcepdfA));

		if(last < source.getNumberOfPages()){
			merger.merge(source,last+1,source.getNumberOfPages());
			source.close();
		}
		merger.close();


		return new ByteArrayInputStream(outputStream.toByteArray());
	}


	 List<ImagePathData> getllll(List<ImagePathData> list){
		List<ImagePathData> kk = new ArrayList<>();
		Integer fornt = 0;
		for (ImagePathData imagePathData : list) {
			ImagePathData sssss = new ImagePathData();
			if(imagePathData.getPage() == 1){
				BeanUtil.copyProperties(imagePathData,sssss);
				sssss.setOoo(false);
				kk.add(sssss);
			}else {
				if(fornt+1 == imagePathData.getPage()){
					BeanUtil.copyProperties(imagePathData,sssss);
					sssss.setOoo(false);
					kk.add(sssss);
				}else {
					ImagePathData aaa = new ImagePathData();

					aaa.setOoo(true);
					aaa.setX(fornt+1);
					aaa.setY(imagePathData.getPage()-1);
					kk.add(aaa);

					BeanUtil.copyProperties(imagePathData,sssss);
					sssss.setOoo(false);
					kk.add(sssss);
				}
			}
			fornt = imagePathData.getPage();
		}
		System.out.println(JSONUtil.toJsonPrettyStr(kk));
		return kk;

	}



	/**
	 * imgesbase64转流
	 * @param imageBaseStr
	 * @return
	 */
	public InputStream imageTopdf(String imageBaseStr){
		// 先处理图片 转为pdf
		// 将Base64字符串转换为字节数组
		byte[] imageBytes = Base64.getMimeDecoder().decode(imageBaseStr);
		Image image = new Image(ImageDataFactory.create(imageBytes));
		//创建 PdfWriter 对象,用于生成 PDF 文件
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		PdfWriter writer = new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(Boolean.TRUE));
		PdfDocument pdfDocument = new PdfDocument(writer);
		Document document = new Document(pdfDocument);
		// 将图片添加到生成的 PDF 文件
		document.add(image);
		// 关闭生成的 PDF 文件
		document.close();
//		String  FileNamePath = "D:\\file\\生成的.pdf";
//		FileOutputStream fis = null;
//		try {
//			fis = new FileOutputStream(FileNamePath);
//		} catch (FileNotFoundException e) {
//			throw new RuntimeException(e);
//		}
//		try {
//			fis.write(outputStream.toByteArray());
//		} catch (IOException e) {
//			throw new RuntimeException(e);
//		}
		return new ByteArrayInputStream(outputStream.toByteArray());
	}



	/**
	 * 文件路径转流
	 * @param pdfFilePath
	 * @return
	 * @throws IOException
	 */
	public  InputStream convertPdfToStream(String pdfFilePath) throws IOException {
		ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
		try (FileInputStream fileInputStream = new FileInputStream(pdfFilePath)) {
			byte[] buffer = new byte[1024];
			int bytesRead;
			// 从文件输入流读取数据并写入字节数组输出流
			while ((bytesRead = fileInputStream.read(buffer)) != -1) {
				byteArrayOutputStream.write(buffer, 0, bytesRead);
			}
		}
		return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());

	}





	public static void main(String[] args) {
		byte[] imageBytes = Base64.getMimeDecoder().decode("iVBORw0KGgoAAAANSUhEUgAAABYAAAAHCAYAAAAMPr0FAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAADCSURBVChTXZFtEsMgCERz/0s1Y9IL9CNj2rNUykNQ2h87i6jPDVlkv4tpc+2PXy+hQ9ehKm19mqRQV/VX0inLAJZb94CZK3yAqRUE2BwY9SHNnPWpj6CawCTMcOuRiJr0HQLU0jrc3PqnqsNlezv4qpvx6SESAlxZs9+hAeehCQ0B7tIZ62UTDySoXcLpqSu8rdFXqKWe6z4a1UZiZhxJxw90WMig9HBPmzQe81F9LpyLGY8x4Bz0OqWdnpP/K0ZS5QuioSfuRx1FmwAAAABJRU5ErkJggg==");

		ImageData image = ImageDataFactory.create(imageBytes);
		System.out.println("image = " + image);
		
	}


	/**
	 *
	 * @param imageBaseStr 图片的base64
	 * @param page 第几页
	 * @param x 距左侧
	 * @param y 距底部
	 * @param width 图片宽度
	 * @param height 图片高度
	 * @param sourcepdf pdf源文件流
	 * @return
	 */
	public InputStream imageOverlayPdfStream(String imageBaseStr , Integer page, float x, float y,float width,float height, InputStream sourcepdf){
		ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
		try {
			byte[] imageBytes = Base64.getMimeDecoder().decode(imageBaseStr);
			PdfReader pdfReader = new PdfReader(sourcepdf);
			// 创建 PdfWriter 对象,用于写入新的 PDF 文件
			// 获取一个新的pdf
			PdfWriter pdfWriter = new PdfWriter(outputStream, new WriterProperties().setFullCompressionMode(Boolean.FALSE));
			PdfDocument pdfDocument = new PdfDocument(pdfReader,pdfWriter);
			// 创建 PdfCanvas 对象
			PdfCanvas pdfCanvas = new PdfCanvas(pdfDocument.getPage(page));
			ImageData image = ImageDataFactory.create(imageBytes);
			PageSize pageSize = pdfDocument.getDefaultPageSize();
			if(width == 0.0){
				width = pageSize.getWidth();
			}
			if(height == 0.0){
				height =pageSize.getHeight();
			}
			Rectangle rectangle = new Rectangle(x,y,width, height);
			pdfCanvas.addImageFittedIntoRectangle(image, rectangle, false);
//			pdfCanvas.addImage(image, rectangle, false); 还有其他的add方法
			// 关闭文档
			pdfDocument.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return new ByteArrayInputStream(outputStream.toByteArray());
	}

}

图片不清晰的问题解决

使用addImageFittedIntoRectangle()这个方法

将一张为pdf页大小n倍的png全透明图片,根据图片的宽高,会不失真的贴在pdf的页上,但是pdf页的大小会变得很大

 这个是base64和测试过的pdf

这个图片为1944x2750的,但是会根据pdf的页面大小贴入,并且保证清晰度不变,还有其他的addImage**()方法,根据自己的需要切换

merg 方法是 操作pdf拆分合并的方法,我这里第一次尝试的是将图片转为pdf再直接替换合并进去,发现会有清晰度问题,随后改为了addImageFittedIntoRectangle()这个方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值