Java pdf转图片 或者 图片转pdf (pdfbox)(itext)

前言:图片转pdf的过程中,能不用**ImageIO.read()**方法就不用,这个方法读取图片会耗费大量时间,转pdf的时间尽量控制在1秒之内

提醒: 传进来的参数不一定要MultipartFile, 读取本地图片或者url(慢点)也可以达到这个速度,注释里有写读取本地图片或url方法的方法

读取url第一种方法:

org.apache.commons.io.FileUtils.toFile()

1. 导入依赖

	<dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>2.0.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.12</version>
        </dependency>
         <!-- https://mvnrepository.com/artifact/com.itextpdf/itextpdf -->
        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itextpdf</artifactId>
            <version>5.5.5</version>
        </dependency>

        <dependency>
            <groupId>com.itextpdf</groupId>
            <artifactId>itext-asian</artifactId>
            <version>5.2.0</version>
        </dependency>

2. pdfbox方式

2.1. 图片转pdf

这里不一定要MultipartFile,就算是本地图片也可以PDImageXObject.createFromFile(imagePath, document);支持本地图片的读取

public static byte[] getPdfBytes(MultipartFile[] imagesFiles) throws IOException {
		PDDocument document = new PDDocument();
		for (MultipartFile datum : imagesFiles) {
			String filename = datum.getOriginalFilename();
			String fileSuffix = filename.substring(filename.lastIndexOf(".") + 1);
			Iterator readers = ImageIO.getImageReadersByFormatName(fileSuffix);
			ImageReader reader = (ImageReader) readers.next();
			ImageInputStream input = ImageIO.createImageInputStream(datum.getInputStream());
			reader.setInput(input, true);
			int width = reader.getWidth(0);
			int height = reader.getHeight(0);
			PDPage pdPage = new PDPage(new PDRectangle(width, height));
			document.addPage(pdPage);
			PDImageXObject pdImageXObject = PDImageXObject.createFromByteArray(document, datum.getBytes(), "构建图片错误");
			//如果没有文件的字节数组,也可以用下面这个
			//String imagePath = "/test";
			//PDImageXObject pdImageXObject = PDImageXObject.createFromFile(imagePath, document);
			//如果只有url,可以用hutool包的HttpUtil方法下载下来,得到的结果是字节数组,不过会耗时长
			PDPageContentStream contentStream = new PDPageContentStream(document, pdPage);
			//写入图片
			contentStream.drawImage(pdImageXObject, 0, 0);
			contentStream.close();
		}
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		document.save(output);
		document.close();
		return output.toByteArray();
	}

2.2. pdf+ 图片转pdf

很简单直接将上面的PDDocument document = new PDDocument();
		换成
	//读取上传pdf文件
      PDDocument document = PDDocument.load(pdfFile.getInputStream()); //pdfFile也是MultipartFile,这里直接用需要读取pdf文件流就可以了
      下面的代码和上面的方法一样

2.3. pdf转图片

/**
	 * @ Author     :chl
	 * @ Date       :Created in 14:40 2023/3/1
	 * @ Description:可以改成返回值为List<byte[]>
	 * @param imageFolderPath 存放图片文件路径
	 * @param pdfSourcePath 需要读取的pdf路径
	 * @param dpi 这个越大,图片越清晰,300挺清楚了
	 * @param formatName
	 * @ return void
	 */
	public static void loadPdf2Image(String imageFolderPath, String pdfSourcePath, int dpi, String formatName) throws Exception {
		PDDocument document = PDDocument.load(new File(pdfSourcePath));
		PDFRenderer renderer = new PDFRenderer(document);
		for (int i = 0; i < document.getNumberOfPages(); i++) {
			BufferedImage bufferedImage = renderer.renderImageWithDPI(i, dpi);
			String imagePath = imageFolderPath + i + "." + formatName;
			FileOutputStream fileOutputStream = new FileOutputStream(imagePath);
			ImageIO.write(bufferedImage, formatName, fileOutputStream);
		}
		document.close();
	}

3、itext 方式

3.1. 图片转pdf

/**
	 * @ Author     :chl
	 * @ Date       :Created in 11:08 2023/3/2
	 * @ Description:性能翻倍
	 * @param data
	 * @ return byte[]
	 */
	public static byte[] multipartFile2pdf2(MultipartFile[] data) {
		Document document = new Document();
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try {
			PdfWriter.getInstance(document, bos);
			document.open();
			for (MultipartFile datum : data) {
				Image image = null;
				ImageInputStream input = null;
				int width = 0;
				int height = 0;
				try {
					String filename = datum.getOriginalFilename();
					String fileSuffix = filename.substring(filename.lastIndexOf(".") + 1);
					Iterator readers = ImageIO.getImageReadersByFormatName(fileSuffix);
					ImageReader reader = (ImageReader) readers.next();
					input = ImageIO.createImageInputStream(datum.getInputStream());
					reader.setInput(input, true);
					width = reader.getWidth(0);
					height = reader.getHeight(0);
					//加载图片
					image = Image.getInstance(datum.getBytes());
					//如果不能直接得到图片字节数组,可以直接,不用再用FileOutputStream读了
					//image = Image.getInstance(filePath);
					//居中
					image.setAlignment(Image.MIDDLE);
				} catch (BaseException e) {
					throw new BaseException("加载上传图片错误");
				}
				//页面大小是图片大小, 和newPage位置不能对调,否则生成烂图
				document.setPageSize(new Rectangle(width, height));
				document.newPage();
				document.add(image);
				input.close();
			}
			document.close();
		} catch (BaseException be) {
			throw new BaseException("加载上传图片错误");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bos.toByteArray();
	}

3.2. 图片+pdf 转成pdf

public static byte[] pdfAndImage2Pdf(MultipartFile pdfFile, MultipartFile[] imagesFiles) throws IOException {
		PdfReader pdfReader = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		PdfStamper pdfStamper = null;
		try {
			//load pdf
			pdfReader = new PdfReader(pdfFile.getBytes());
			//打开pdf编辑器
			pdfStamper = new PdfStamper(pdfReader, bos);

			for (MultipartFile datum : imagesFiles) {
				String filename = datum.getOriginalFilename();
				String fileSuffix = filename.substring(filename.lastIndexOf(".") + 1);
				Iterator readers = ImageIO.getImageReadersByFormatName(fileSuffix);
				ImageReader reader = (ImageReader) readers.next();
				ImageInputStream input = ImageIO.createImageInputStream(datum.getInputStream());
				reader.setInput(input, true);
				int width = reader.getWidth(0);
				int height = reader.getHeight(0);
				Image image = Image.getInstance(datum.getBytes());
				image.setAlignment(Image.MIDDLE);
				//添加空白页
				pdfStamper.insertPage(pdfReader.getNumberOfPages() + 1, new Rectangle(width, height));
				//捕获空白页
				PdfContentByte overContent = pdfStamper.getOverContent(pdfReader.getNumberOfPages());
				image.scaleAbsolute(width, height);
				//设置绝对位置
				image.setAbsolutePosition(0, 0);
				overContent.addImage(image);
				input.close();
			}

		}catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				pdfStamper.close();
				pdfReader.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return bos.toByteArray();
	}
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值