结合网上各路大神代码汇总而来,如果需要将pdf统一格式,可将pdf转成图片后重新转为pdf合并至一起,使用itext的PdfCanvas未成功解决该问题,主要也是因为我菜且时间紧没空查文档了。对于itext7中的添加水印的方法也没有看完,故也尝试了itext5中的合并pdf及添加水印功能。

一些小问题:

1.RandomAccessSource not opened

itext5的pdf-copy功能存在某些文件复制进pdf后进行pdfDocument.close()时出现RandomAccessSource not opened的异常提示,切换至itext7的合并尝试后,并没有出现该问题。

2.PdfReader is not opened with owner password

该问题的出现是因为pdf被加密保护,如果需要继续读取则需要加上跳过密码对应的代码

itext5:

PdfReader.unethicalreading = true;

itext7:

PdfReader reader = new PdfReader(sourceFile);
reader.setUnethicalReading(true);

一. itext7版

1.依赖

其中,itext7用于pdf合并,aspose-cells用于将excel转换为pdf,最后一个则为使用liberoffice将word、ppt、txt转换为pdf使用。

        <dependency><groupId>com.itextpdf</groupId><artifactId>itext7-core</artifactId><version>7.2.4</version><type>pom</type></dependency><dependency><groupId>com.luhuiguo</groupId><artifactId>aspose-cells</artifactId><version>23.1</version></dependency><dependency><groupId>com.liumapp.workable.converter</groupId><artifactId>workable-converter</artifactId><version>v1.2.0</version></dependency>

2.文件格式转换及合并pdf

import com.aspose.cells.License;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;
import com.hfzx.web.controller.common.config.HfzxConfig;
import com.hfzx.web.controller.common.exception.CustomException;
import com.hfzx.web.controller.common.utils.StringUtils;
import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.kernel.pdf.xobject.PdfFormXObject;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfStamper;
import com.liumapp.workable.converter.WorkableConverter;
import com.liumapp.workable.converter.core.ConvertPattern;
import com.liumapp.workable.converter.exceptions.ConvertFailedException;
import com.liumapp.workable.converter.factory.CommonConverterManager;
import com.liumapp.workable.converter.factory.ConvertPatternManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.jodconverter.document.DefaultDocumentFormatRegistry;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;/*** 合并pdf并加上水印* @date 2023-03-07*/
@Slf4j
public class MergePdfUtil {/*** doc docx ppt pptx转pdf** @param inputFile 源文件* @param pdfFile   输出文件*/public static void word2PDF(String inputFile, String pdfFile) {File file = new File(inputFile);if (!file.exists()) {log.error("文件不存在");return;}FileInputStream is = null;FileOutputStream os = null;try {WorkableConverter converter = new WorkableConverter();ConvertPattern pattern = ConvertPatternManager.getInstance();is = new FileInputStream(file);os = new FileOutputStream(pdfFile);// 处理网络文件pattern.streamToStream(is, os);pattern.setSrcFilePrefix(DefaultDocumentFormatRegistry.DOCX);pattern.setDestFilePrefix(DefaultDocumentFormatRegistry.PDF);converter.setConverterType(CommonConverterManager.getInstance());converter.convert(pattern.getParameter());} catch (ConvertFailedException e) {log.error("文件:{},转换失败:{}", inputFile, e.getMessage());} catch (FileNotFoundException e) {log.error("文件:{}不存在或liceroffice未安装", inputFile);} finally {try {is.close();os.close();} catch (IOException e) {log.error("文件流关闭失败");}}}/*** excel转pdf*/public static void excel2PDF(String excelPath, String pdfPath) {File file = new File(excelPath);if (!file.exists()) {throw new CustomException("文件不存在");}// 验证Licenseif (!getLicense()) {return;}FileInputStream fileInputStream;try {fileInputStream = new FileInputStream(file);Workbook workbook = new Workbook(fileInputStream);File pdfFile = new File(pdfPath);PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();//把excel所有内容放在一张PDF 页面上;pdfSaveOptions.setOnePagePerSheet(false);//把excel所有表头放在一张pdf上pdfSaveOptions.setAllColumnsInOnePagePerSheet(true);FileOutputStream fileOS = new FileOutputStream(pdfFile);workbook.save(fileOS, pdfSaveOptions);fileInputStream.close();fileOS.close();} catch (Exception e) {throw new CustomException(e.getMessage());}}/**** 图片转pdf* @param source* @param target*/public static void img2Pdf(String source, String target) {File file = new File(source);if (!file.exists()) {log.error("文件不存在");return;}Document document;try {PdfWriter writer = new PdfWriter(target);PdfDocument pdf = new PdfDocument(writer);document = new Document(pdf);Image image = new Image(ImageDataFactory.create(source));image.setAutoScale(true);image.setAutoScaleHeight(true);image.setAutoScaleWidth(true);Paragraph p = new Paragraph().add(image);document.add(p);//关闭文档document.close();writer.close();} catch (Exception e) {log.error("图片:{},转pdf失败:{}", source, e.getMessage());}}/**** PDF文件转PNG图片,全部页数** @param pdfFilePath pdf完整路径* @param dpi dpi越大转换后越清晰,相对转换速度越慢*/public static List<String> pdf2Image(String pdfFilePath, int dpi) {File file = new File(pdfFilePath);PDDocument pdDocument = null;List<String> imgList = new ArrayList<>();try {String imgPdfPath = file.getParent();int dot = file.getName().lastIndexOf('.');// 获取图片文件名String imagePdfName = file.getName().substring(0, dot);pdDocument = PDDocument.load(file);PDFRenderer renderer = new PDFRenderer(pdDocument);/* dpi越大转换后越清晰,相对转换速度越慢 */StringBuffer imgFilePath;PdfReader reader = new PdfReader(pdfFilePath);int pages = pdDocument.getNumberOfPages();for (int i = 0; i < pages; i++) {String imgFilePathPrefix = imgPdfPath + File.separator + imagePdfName;imgFilePath = new StringBuffer();imgFilePath.append(imgFilePathPrefix);imgFilePath.append("_");imgFilePath.append((i + 1));imgFilePath.append(".png");File dstFile = new File(imgFilePath.toString());BufferedImage image = renderer.renderImageWithDPI(i, dpi);ImageIO.write(image, "png", dstFile);imgList.add(imgFilePath.toString());}pdDocument.close();return imgList;} catch (IOException e) {log.error("pdf转换图片异常:{}", e.getMessage());}}/*** 统一格式pdf** @param savePath* @param readPath* @throws IOException*/public static void setPageStyle(String savePath, String readPath) {PdfReader pdfReader = null;PdfDocument pdfDocument = null;PdfWriter pdfWriter = null;PdfDocument outPDfDoc = null;try {pdfReader = new PdfReader(readPath);pdfDocument = new PdfDocument(pdfReader);pdfWriter = new PdfWriter(savePath);outPDfDoc = new PdfDocument(pdfWriter);outPDfDoc.setDefaultPageSize(PageSize.A4);for (int i = 1; i < pdfDocument.getNumberOfPages() + 1; i++) {PdfPage page = pdfDocument.getPage(i);PdfFormXObject formXObject = page.copyAsFormXObject(outPDfDoc);float xPercent = PageSize.A4.getWidth() / page.getPageSize().getWidth();float yPercent = PageSize.A4.getHeight() / page.getPageSize().getHeight();PdfCanvas pdfCanvas = new PdfCanvas(outPDfDoc.addNewPage());pdfCanvas.addXObjectWithTransformationMatrix(formXObject, xPercent, 0, 0, yPercent, 0, 0);}pdfWriter.flush();} catch (Exception e) {log.error("转换异常:{}", e.getMessage());} finally {try {if (pdfReader != null) {pdfReader.close();}if (pdfDocument != null) {pdfDocument.close();}if (outPDfDoc != null) {outPDfDoc.close();}if (pdfWriter != null) {pdfWriter.close();}} catch (IOException e) {log.error("IO流关闭失败");}}}/**** 合并pdf并加上水印* @param sourceFileList 待合并文件* @param destinationPath 合并文件输出地址* @throws IOException*/public static void mergePdf(String[] sourceFileList, String destinationPath) {File file = new File(destinationPath);//获取父目录File fileParent = file.getParentFile();if (!fileParent.exists()) {// 创建父目录文件夹fileParent.mkdirs();}try {PdfWriter writer = new PdfWriter(destinationPath);PdfDocument writerDoc = new PdfDocument(writer);//合并pdffor (String sourceFile : sourceFileList) {File readFile = new File(sourceFile);if (!readFile.exists()) {log.error("文件不存在:" + sourceFile);continue;}PdfReader reader = new PdfReader(sourceFile);//忽略pdf密码进行读取reader.setUnethicalReading(true);log.info("项目文书-读取文件:" + sourceFile);PdfDocument readerDoc = new PdfDocument(reader);for (int i = 1; i <= readerDoc.getNumberOfPages(); i++) {//copy功能PdfPage readerPage = readerDoc.getPage(i);writerDoc.addPage(readerPage.copyTo(writerDoc));/*//写入pdf并统一样式为A4 暂不使用PdfPage page = readerDoc.getPage(i);PdfFormXObject formXObject = page.copyAsFormXObject(writerDoc);float xPercent = PageSize.A4.getWidth() /     page.getPageSize().getWidth();float yPercent = PageSize.A4.getHeight() / page.getPageSize().getHeight();PdfCanvas pdfCanvas = new PdfCanvas(writerDoc.addNewPage());pdfCanvas.addXObjectWithTransformationMatrix(formXObject, xPercent, 0, 0, yPercent, 0, 0);*/}/*//合并PdfMerger merger = new PdfMerger(writerDoc);merger.merge(readerDoc, 1, readerDoc.getNumberOfPages());*/readerDoc.close();reader.close();}writerDoc.close();} catch (FileNotFoundException e) {log.error("文件生成失败:{}", e.getMessage());} catch (IOException e) {log.error("文件生成失败:{}", e.getMessage());}}/*** 验证License** @return*/private static boolean getLicense() {boolean result = false;try {// license路径InputStream license = Files.newInputStream("D:\\resource\\license.xml").toPath());License asposeLic = new License();asposeLic.setLicense(license);result = true;} catch (Exception e) {e.printStackTrace();}return result;}/*** pdf添加水印** @param inputFile         需要添加水印的文件* @param outputFile        添加完水印的文件存放路径* @param waterMarkName     需要添加的水印文字* @param imgWaterMarkUrl   水印图片* @param lastWaterMarkName 水印文字(暂定页脚左下角)* @param pageHeader        页眉* @param skipFirstPage     是否跳过首页* @return*/public static boolean addWaterMark(String inputFile, String outputFile, String pageHeader, String waterMarkName, String lastWaterMarkName, String imgWaterMarkUrl, boolean skipFirstPage) {File file = new File(inputFile);if (!file.exists()) {return false;}PdfFont pdfFont = null;try {pdfFont = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H");} catch (IOException e) {log.error("pdf水印字体获取失败");return false;}try {FileOutputStream outputStream = new FileOutputStream(new File(outputFile));PdfWriter pdfWriter = new PdfWriter(outputStream);PdfDocument outDocument = new PdfDocument(pdfWriter);PdfReader pdfReader = new PdfReader(inputFile);PdfDocument redDocument = new PdfDocument(pdfReader);// 添加事件,该事件拥有添加水印outDocument.addEventHandler(PdfDocumentEvent.INSERT_PAGE, new PdfPageMarker(pdfFont, skipFirstPage));outDocument.addEventHandler(PdfDocumentEvent.INSERT_PAGE,new PdfWaterMarker(pdfFont, lastWaterMarkName, waterMarkName, imgWaterMarkUrl));outDocument.addEventHandler(PdfDocumentEvent.INSERT_PAGE,new PdfHeaderMarker(pdfFont, pageHeader, skipFirstPage));//获取总页数int numberOfPages = redDocument.getNumberOfPages();for (int i = 1; i <= numberOfPages; i++) {PdfPage page = redDocument.getPage(i);//复制每页内容添加到新的文件中outDocument.addPage(page.copyTo(outDocument));}outDocument.close();redDocument.close();pdfReader.close();log.info("水印添加成功");return true;} catch (IOException e) {log.error("水印生成失败");return false;}}public static void main(String[] args) {addWaterMark("D:\\test1.pdf", "D:\\test2.pdf", "页眉", "全页水印长长长", "页尾水印", null, true);}
}

3.添加页眉、页脚、水印,该事件不建议加在合并文件时使用,可能会出现一些文件加上水印、一些文件没加上水印的问题(我是懒狗)

对应copy来源:SpringBoot + Itext7 html转pdf 解决分页,表格被分割留出空白,水印,页眉页脚页码。_持伞走过故人路的博客-CSDN博客

- 页眉

import com.hfzx.web.controller.common.utils.StringUtils;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;/*** PDF页眉**/
public class PdfHeaderMarker implements IEventHandler {private PdfFont pdfFont;private String title;private boolean skipFirstPage;public PdfHeaderMarker(PdfFont pdfFont, String title, boolean skipFirstPage) {this.pdfFont = pdfFont;this.title = title;this.skipFirstPage = skipFirstPage;}@Overridepublic void handleEvent(Event event) {if (StringUtils.isNotEmpty(title)) {PdfDocumentEvent docEvent = (PdfDocumentEvent) event;PdfDocument pdf = docEvent.getDocument();PdfPage page = docEvent.getPage();int pageNumber = pdf.getPageNumber(page);// 封面不展示页眉页脚if (skipFirstPage ? pageNumber != 1 : true) {Rectangle pageSize = page.getPageSize();PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), pdf);Canvas canvas = new Canvas(pdfCanvas, pageSize);float x = (pageSize.getLeft() + pageSize.getRight()) / 2;float y = pageSize.getTop() - 25;Paragraph p = new Paragraph(title).setFontSize(12).setFont(pdfFont);// 顶部中间位置canvas.showTextAligned(p, x, y, TextAlignment.CENTER);canvas.close();}}}}

-页脚

import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;/*** pdf 页脚**/
public class PdfFooterMarker implements IEventHandler {private PdfFont pdfFont;private boolean skipFirstPage;public PdfFooterMarker(PdfFont pdfFont, boolean skipFirstPage) {this.pdfFont = pdfFont;this.skipFirstPage = skipFirstPage;}@Overridepublic void handleEvent(Event event) {PdfDocumentEvent docEvent = (PdfDocumentEvent) event;PdfDocument pdf = docEvent.getDocument();PdfPage page = docEvent.getPage();int pageNumber = pdf.getPageNumber(page);// 封面不展示页眉页脚if (skipFirstPage ? pageNumber != 1 : true) {pageNumber = skipFirstPage ? pageNumber - 1 : pageNumber;Rectangle pageSize = page.getPageSize();PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), pdf);Canvas canvas = new Canvas(pdfCanvas, pageSize);float x = (pageSize.getLeft() + pageSize.getRight()) / 2;float y = pageSize.getBottom() + 15;Paragraph p = new Paragraph("第" + pageNumber + "页").setFontSize(12).setFont(pdfFont);// 底部中间位置canvas.showTextAligned(p, x, y, TextAlignment.CENTER);canvas.close();}}}

-水印

import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.events.Event;
import com.itextpdf.kernel.events.IEventHandler;
import com.itextpdf.kernel.events.PdfDocumentEvent;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Image;
import com.itextpdf.layout.element.Paragraph;
import com.itextpdf.layout.properties.TextAlignment;
import com.itextpdf.layout.properties.VerticalAlignment;
import org.apache.commons.lang3.StringUtils;import java.io.*;/**** pdf 水印*/
public class PdfWaterMarker implements IEventHandler {private PdfFont pdfFont;private String waterContent;private String waterAllContent;private String waterImgPath;/*** 全页水印字体大小*/private static final int WATER_ALL_FONT_SIZE = 30;/*** 全页水印字体透明度*/private static float OPACITY = 0.2f;/*** 全页水印倾斜角度(0-360)*/private static int ANGLE = 120;/*** 数值越大每页竖向水印越少*/private static int HEIGHT_DENSITY = 6;/*** 高度倍数*/private static float HEIGHT_MULTIPLE = 2;/*** 数值越大每页横向水印越少*/private static int WIDTH_DENSITY = 3;/*** 宽度倍数*/private static float WIDTH_MULTIPLE = 1.5f;public PdfWaterMarker(PdfFont pdfFont, String waterContent, String waterAllContent, String waterImgPath) {this.pdfFont = pdfFont;this.waterContent = waterContent;this.waterAllContent = waterAllContent;this.waterImgPath = waterImgPath;}@Overridepublic void handleEvent(Event event) {PdfDocumentEvent docEvent = (PdfDocumentEvent) event;PdfDocument pdf = docEvent.getDocument();PdfPage page = docEvent.getPage();Rectangle pageSize = page.getPageSize();PdfCanvas pdfCanvas = new PdfCanvas(page.getLastContentStream(), page.getResources(), pdf);Canvas canvas = new Canvas(pdfCanvas, pageSize);int pageNumber = pdf.getPageNumber(page);//页脚水印if (StringUtils.isNotBlank(waterContent)) {Paragraph waterMarker = new Paragraph(waterContent).setFont(pdfFont).setOpacity(.5f).setFontSize(13);// 右下角位置canvas.showTextAligned(waterMarker, pageSize.getRight() - 150,pageSize.getBottom() + 15, pdf.getNumberOfPages(),TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);}//全页水印if (StringUtils.isNotBlank(waterAllContent)) {Paragraph waterMarker = new Paragraph(waterAllContent).setFont(pdfFont).setOpacity(OPACITY).setFontSize(WATER_ALL_FONT_SIZE);float textH = WATER_ALL_FONT_SIZE;float textW = WATER_ALL_FONT_SIZE * waterAllContent.length();for (float height = textH; height < page.getPageSize().getHeight() * HEIGHT_MULTIPLE;height = height + textH * HEIGHT_DENSITY) {for (float width = textW; width < page.getPageSize().getWidth() * WIDTH_MULTIPLE + textW;width = width + textW * WIDTH_DENSITY) {//第一行贴左展示canvas.showTextAligned(waterMarker, width - textW + 5, height - textH, pdf.getNumberOfPages(),TextAlignment.LEFT, VerticalAlignment.BOTTOM, ANGLE);//第二行跨行展示canvas.showTextAligned(waterMarker, width, height - textH, pdf.getNumberOfPages(),TextAlignment.LEFT, VerticalAlignment.BOTTOM, ANGLE);}}}// 水印图片Image waterImg = null;if (StringUtils.isNotBlank(waterImgPath)) {try {InputStream inputStream = returnInputStream(waterImgPath);if (inputStream != null) {ImageData waterImgData = ImageDataFactory.create(toByteArray(inputStream));waterImg = new Image(waterImgData);}} catch (IOException e) {e.printStackTrace();}}// 图片水印if (waterImg != null) {int length = waterContent.length();// 设置坐标 X YwaterImg.setFixedPosition(pdf.getNumberOfPages(), pageSize.getRight() - (168 + length),pageSize.getBottom() + 30);// 设置等比缩放;// 自定义大小waterImg.scaleAbsolute(100, 100);// 写入图片水印canvas.add(waterImg);}canvas.close();}public static byte[] toByteArray(InputStream input) throws IOException {ByteArrayOutputStream output = new ByteArrayOutputStream();byte[] buffer = new byte[4096];int n = 0;while (-1 != (n = input.read(buffer))) {output.write(buffer, 0, n);}return output.toByteArray();}public static InputStream returnInputStream(String filePath) throws IOException {File file = new File(filePath);if (!file.exists()) {return null;}InputStream inputStream = new FileInputStream(file);return inputStream;}}

二、 itext5

就附个代码了,合并和水印网上都有

import com.aspose.cells.License;
import com.aspose.cells.PdfSaveOptions;
import com.aspose.cells.Workbook;
import com.hfzx.web.controller.common.config.HfzxConfig;
import com.hfzx.web.controller.common.exception.CustomException;
import com.hfzx.web.controller.common.utils.StringUtils;
import com.hfzx.web.controller.common.utils.file.FileUtils;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.liumapp.workable.converter.WorkableConverter;
import com.liumapp.workable.converter.core.ConvertPattern;
import com.liumapp.workable.converter.exceptions.ConvertFailedException;
import com.liumapp.workable.converter.factory.CommonConverterManager;
import com.liumapp.workable.converter.factory.ConvertPatternManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.jodconverter.document.DefaultDocumentFormatRegistry;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;/*** 合并pdf并加上水印**/
@Slf4j
public class MergePDFUtilTmp {//水印字体透明度private static float opacity = 0.2f;//水印字体大小private static int fontsize = 30;//水印倾斜角度(0-360)private static int angle = 30;//数值越大每页竖向水印越少private static int heightDensity = 12;//数值越大每页横向水印越少private static int widthDensity = 6;/**** 图片*/public static String[] PHOTO = new String[]{"bmp", "jpg", "jpeg", "png", "tif", "gif", "psd", "pcx", "tga", "exif", "fpx", "svg", "ai", "eps", "ufo", "dxf", "pcd", "cdr","raw", "wmf", "webp", "avif"};/**** 文档*/public static String[] WORD = new String[]{"doc", "docx", "txt"};/*** excel*/public static String[] EXCEL = new String[]{"xls", "xlsx"};/*** ppt*/public static String[] PPT = new String[]{"ppt", "pptx"};public static void trans(String filePath, String pdfPath, String type) {toPdf(filePath, pdfPath, type);}//转换private static void toPdf(String filePath, String pdfPath, String type) {if ("word".equals(type)) {word2PDF(filePath, pdfPath);} else if ("excel".equals(type)) {excel2PDF(filePath, pdfPath);} else if ("ppt".equals(type)) {word2PDF(filePath, pdfPath);} else if ("photo".equals(type)) {convert(filePath, pdfPath);}}private static void word2PDF(String inputFile, String pdfFile) {File file = new File(inputFile);if (!file.exists()) {return;}FileInputStream is = null;FileOutputStream os = null;try {WorkableConverter converter = new WorkableConverter();ConvertPattern pattern = ConvertPatternManager.getInstance();is = new FileInputStream(file);os = new FileOutputStream(pdfFile);// 处理网络文件pattern.streamToStream(is, os);pattern.setSrcFilePrefix(DefaultDocumentFormatRegistry.DOCX);pattern.setDestFilePrefix(DefaultDocumentFormatRegistry.PDF);converter.setConverterType(CommonConverterManager.getInstance());boolean result = converter.convert(pattern.getParameter());} catch (ConvertFailedException e) {log.error("文件转换失败");} catch (FileNotFoundException e) {log.error("文件不存在或liberoffice不存在");} finally {try {is.close();os.close();} catch (IOException e) {log.error("文件流关闭失败");}}}public static void excelFirstHandel(String excelPath, String pdfPath) {// 获取图片文件名String tempPdfPath = pdfPath.substring(0, pdfPath.lastIndexOf(".")) + "temp.pdf";excel2PDF(excelPath, tempPdfPath);String img = pdf2Image(tempPdfPath, 100);if (StringUtils.isNotEmpty(img)) {convert(img, pdfPath);FileUtils.deleteFile(img);}}public static void excel2PDF(String excelPath, String pdfPath) {File file = new File(excelPath);if (!file.exists()) {return;}// 验证Licenseif (!getLicense()) {return;}FileInputStream fileInputStream;try {fileInputStream = new FileInputStream(file);Workbook workbook = new Workbook(fileInputStream);File pdfFile = new File(pdfPath);PdfSaveOptions pdfSaveOptions = new PdfSaveOptions();//把excel所有内容放在一张PDF 页面上;pdfSaveOptions.setOnePagePerSheet(false);//把excel所有表头放在一张pdf上pdfSaveOptions.setAllColumnsInOnePagePerSheet(true);FileOutputStream fileOS = new FileOutputStream(pdfFile);workbook.save(fileOS, pdfSaveOptions);fileInputStream.close();fileOS.close();} catch (Exception e) {log.error(e.getMessage());}}/**** PDF文件转PNG图片,全部页数** @param pdfFilePath pdf完整路径* @param dpi dpi越大转换后越清晰,相对转换速度越慢*/public static String pdf2Image(String pdfFilePath, int dpi) {File file = new File(pdfFilePath);PDDocument pdDocument = null;try {String imgPdfPath = file.getParent();int dot = file.getName().lastIndexOf('.');// 获取图片文件名String imagePdfName = file.getName().substring(0, dot);pdDocument = PDDocument.load(file);PDFRenderer renderer = new PDFRenderer(pdDocument);/* dpi越大转换后越清晰,相对转换速度越慢 */StringBuffer imgFilePath;
//            PdfReader reader = new PdfReader(pdfFilePath);
//            int pages = reader.getNumberOfPages();
//            for (int i = 0; i < pages; i++) {
//                String imgFilePathPrefix = imgPdfPath + File.separator + imagePdfName;
//                imgFilePath = new StringBuffer();
//                imgFilePath.append(imgFilePathPrefix);
//                imgFilePath.append("_");
//                imgFilePath.append((i + 1));
//                imgFilePath.append(".png");
//                File dstFile = new File(imgFilePath.toString());
//                BufferedImage image = renderer.renderImageWithDPI(i, dpi);
//                ImageIO.write(image, "png", dstFile);
//            }String imgFilePathPrefix = imgPdfPath + File.separator + imagePdfName;imgFilePath = new StringBuffer();imgFilePath.append(imgFilePathPrefix);imgFilePath.append(".png");File dstFile = new File(imgFilePath.toString());BufferedImage image = renderer.renderImageWithDPI(0, dpi);ImageIO.write(image, "png", dstFile);pdDocument.close();return imgFilePath.toString();} catch (IOException e) {throw new CustomException(e.getMessage());}}private static boolean getLicense() {boolean result = false;try {// license路径InputStream license = Files.newInputStream(new File(HfzxConfig.getDownloadPath() + "resource/license.xml").toPath());License aposeLic = new License();aposeLic.setLicense(license);result = true;} catch (Exception e) {e.printStackTrace();}return result;}//图片转pdfpublic static void convert(String source, String target) {File file = new File(source);if (!file.exists()) {return;}Document document = new Document();//设置文档页边距document.setMargins(40, 57, 5, 57);FileOutputStream fos = null;try {fos = new FileOutputStream(target);PdfWriter.getInstance(document, fos);//打开文档document.open();//获取图片的宽高Image image = Image.getInstance(source);float imageHeight = image.getScaledHeight();float imageWidth = image.getScaledWidth();// 设置图片自适应页面宽高Rectangle pageSize = document.getPageSize();float width = pageSize.getWidth();float height = pageSize.getHeight();float wSize = imageWidth / width;if (wSize > 1f) {image.scaleAbsolute(imageWidth / wSize, imageHeight / wSize);}float hSize = image.getScaledHeight()/height;if (hSize > 1f) {image.scaleAbsolute(image.getScaledWidth() / hSize, image.getScaledHeight() / hSize);}//图片居中image.setAlignment(Image.ALIGN_CENTER);//新建一页添加图片document.newPage();document.add(image);} catch (Exception ioe) {log.error("图片不存在");} finally {//关闭文档document.close();try {fos.flush();fos.close();} catch (IOException e) {log.error("文件流关闭失败");}}}public static boolean mergePdfFiles(String[] files, String newfile) {boolean retValue = false;Document document = null;PdfReader first = null;//跳过密码PdfReader.unethicalreading = true;// 临时生成文件路径File f = new File(newfile);//获取父目录File fileParent = f.getParentFile();if (!fileParent.exists()) {// 创建父目录文件夹fileParent.mkdirs();}try {first = new PdfReader(files[0]);document = new Document(first.getPageSize(1));PdfCopy copy = new PdfCopy(document, new FileOutputStream(newfile));document.open();for (int i = 0; i < files.length; i++) {File c = new File(files[i]);if (!c.exists()) {log.error("文件不存在:" + files[i]);continue;}PdfReader reader = null;try {reader = new PdfReader(files[i]);int n = reader.getNumberOfPages();for (int j = 1; j <= n; j++) {document.newPage();PdfImportedPage page = copy.getImportedPage(reader, j);copy.addPage(page);}log.info("文件合并成功:" + files[i]);reader.close();} catch (IOException e) {e.printStackTrace();log.error("存在无法复制文件:{},对应文件目录:{}", e.getMessage(), files[i]);} finally {if (null != reader) {reader.close();}if (null != first) {first.close();}}}retValue = true;} catch (Exception e) {log.error("合并文件失败:" + e.getMessage());} finally {if (null != document) {document.close();}if (null != first) {first.close();}}return retValue;}/*** pdf添加水印** @param inputFile     需要添加水印的文件* @param outputFile    添加完水印的文件存放路径* @param waterMarkName 需要添加的水印文字* @param cover         是否覆盖* @return*/public static boolean addWaterMark(String inputFile, String outputFile, String waterMarkName, boolean cover) {if (!cover) {File file = new File(outputFile);if (file.exists()) {return true;}}File file = new File(inputFile);if (!file.exists()) {return false;}PdfReader reader = null;PdfStamper stamper = null;try {reader = new PdfReader(inputFile);stamper = new PdfStamper(reader, new FileOutputStream(outputFile));BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);Rectangle pageRect = null;PdfGState gs = new PdfGState();//这里是透明度设置gs.setFillOpacity(opacity);//这里是条纹不透明度gs.setStrokeOpacity(0.2f);int total = reader.getNumberOfPages() + 1;System.out.println("Pdf页数:" + reader.getNumberOfPages());JLabel label = new JLabel();FontMetrics metrics;int textH = 0;int textW = 0;label.setText(waterMarkName);metrics = label.getFontMetrics(label.getFont());//字符串的高,   只和字体有关textH = metrics.getHeight();//字符串的宽textW = metrics.stringWidth(label.getText());PdfContentByte under;//循环PDF,每页添加水印for (int i = 1; i < total; i++) {pageRect = reader.getPageSizeWithRotation(i);//在内容上方添加水印under = stamper.getOverContent(i);under.saveState();under.setGState(gs);under.beginText();//这里是水印字体大小under.setFontAndSize(base, fontsize);for (int height = textH; height < pageRect.getHeight() * 2; height = height + textH * heightDensity) {for (int width = textW; width < pageRect.getWidth() * 1.5 + textW; width = width + textW * widthDensity) {// rotation:倾斜角度under.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, angle);}}//添加水印文字under.endText();}System.out.println("添加水印成功!");return true;} catch (IOException e) {log.error("添加水印失败!错误信息为: " + e);return false;} catch (DocumentException e) {log.error("添加水印失败!错误信息为: " + e);return false;} finally {//关闭流if (stamper != null) {try {stamper.close();} catch (DocumentException e) {log.error("文件流关闭失败");} catch (IOException e) {log.error("文件流关闭失败");}}if (reader != null) {reader.close();}}}
}

JAVA itext 多种文件转pdf,进行合并 添加水印相关推荐

  1. Java输出PPT文件(一) - 合并PPT

    Java输出PPT文件(一) - 合并PPT 文章目录 Java输出PPT文件(一) - 合并PPT 0. 前言 1. 依赖 2. 代码 3. 测试 3.1 模板准备 3.2 合并结果 4. 问题 4 ...

  2. JAVA 多种文件转pdf,进行合并,统一pdf文件页面样式

    JAVA 将word.execl.ptt.txt.图片等文件转为pdf文件.合并为一个pdf文件,并统一pdf文件页面样式 准备 1.jar包 2.对应的dll文件放到jdk或jre的bin目录下: ...

  3. java iText 的jar导出pdf格式,禁止浏览器预览,直接下载功能

    后台使用iText来生成一个pdf文件,提供一个服务器的pdf访问地址,让前端拿到,浏览器下载,不过直接使用loaction.href的形式,浏览器都会默认进入一个预览的界面,这就导致很不好用,需要回 ...

  4. Java itext实现图片转pdf

    一.引入pom依赖 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf< ...

  5. java实现word文件转pdf功能

    项目需要使用java将后台生成的word文件转化为pdf,第一次做这个所以找了很多资料和代码,但一直都有问题. 有的可以转化但在第一页有水印:Evaluation Warning: The docum ...

  6. Java将OFD文件转PDF文件

    OFDRW 提供了将 OFD 文档导出为其他格式文档的能力,如导出为 PDF.图片.SVG.TXT.HTML 等. OFDRW 转换模块在 2.0.0 之后抽象了多种文档导出接口,使用统一的 API ...

  7. itext根据模版生成PDF与合并多个PDF以及向已存在PDF增加水印设置权限等操作

    我之前写了一篇文章讲了itext的基础操作常用方法(https://my.oschina.net/itazi/blog/1812042),但是有时涉及到比较复杂的PDF生成,手工操作就很复杂,可以使用 ...

  8. java itext根据模板生成pdf

    很久没有更新过了,稍微闲一点,顺势总结下N久之前用到的小技巧. 这里生成pdf主要使用itext.jar.如想生成一个pdf,其实很简单的啦!第一种:全部使用代码生成:第二种:根据pdf模板生成.当前 ...

  9. java中doc文件转为pdf文件_java将doc文件转换为pdf文件的三种方法

    标签: http://feifei.im/archives/93 ---------------------------------------------- 项目要用到doc转pdf的功能,一番go ...

最新文章

  1. GRNet网络:3D网格进行点云卷积,实现点云补全
  2. spring 注解@PathVariable
  3. Android --- Android Studio 内无法直接运行 main 方法
  4. C语言的math相关的函数
  5. leetcode242. 有效的字母异位词(两种方法map或数组)
  6. 电子工程可以报考二建_非工程类专业也能报考二建吗?
  7. Billboard HDU - 2795(树状数组,单点修改,区间查询)
  8. MongoDB Insert(插入)
  9. latex 错误: BibTeX: empty journal in Lv2021
  10. 洛谷OJ P1802 5倍经验日 动态规划
  11. 关于对ffmpeg中SAR/DAR/PAR的理解
  12. [C#]使用Process的StandardInput与StandardOutput写入读取控制台数据
  13. Linux内核之PCI设备
  14. C语言康威生命游戏,【2020存档】康威生命游戏(CGoL)研究进展
  15. 菲律宾巴拉望:无忧无虑的快乐天堂
  16. 申宝正规股票下周市场将迎来抛压
  17. js文字无限循环向上滚动
  18. Python autoit 窗口基本使用
  19. matlab进行数据平滑,matlab数据平滑程序Word版
  20. 【开发工具】PacketTracer

热门文章

  1. 源码安装Apache(ab性能测试)
  2. C反汇编实例(详细注解版)(一)
  3. 微服务与领域驱动设计,架构实践总结
  4. Android 获取FPS
  5. 信号量Semaphore
  6. Java读写excel方法大全,对特定的数据给上特定的背景颜色,加生备注信息等等。
  7. go-pitaya学习笔记(2)-chatDemo分析
  8. 奶爸生活-打电话的真实意图
  9. seata的xid是如何传播的?
  10. Node.js 内存管理和 V8 垃圾回收机制