结合网上各路大神代码汇总而来,如果需要将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.mon.config.HfzxConfig;import com.hfzx.mon.exception.CustomException;import com.hfzx.mon.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.monConverterManager;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 -03-07*/@Slf4jpublic 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.mon.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 mons.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.mon.config.HfzxConfig;import com.hfzx.mon.exception.CustomException;import com.hfzx.mon.utils.StringUtils;import com.hfzx.mon.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.monConverterManager;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并加上水印**/@Slf4jpublic 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 进行合并 添加水印》对你有帮助,请点赞、收藏,并留下你的观点哦!