欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

itext7生成PDF

程序员文章站 2024-03-19 12:57:04
...

1、配置

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext7-core</artifactId>
    <version>7.1.11</version>
    <type>pom</type>
 </dependency>

2.PDFUtils

封装的PDF工具类,导包直接选中itext相关的就好,注意IOException不要导itext的(第一次无脑导的后果…)

public class PDFUtils {


	public static PdfFont getDefaultFont() {
		try {
//			return PdfFontFactory.createFont("C://windows//fonts//simsun.ttc,1", PdfEncodings.IDENTITY_H, false);// 引用系统字体
			return PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false);// 使用itext字体
		} catch (IOException e) {
			// 记录日志
			e.printStackTrace();
		}
		return null;
	}


	public static PdfFont getImportFont(String fontName) {
		// 获取resource下文件夹路径
		String path = "/template/";
		String fontPath = path + fontName;
		try {
			// 处理中文乱码(支持Linux系统)
			FontProgram fontProgram = FontProgramFactory.createFont(fontPath, false);
			PdfFont font = PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H, false);
			return font;
		} catch (IOException e) {
			// 记录日志
			e.printStackTrace();
		}
		return null;
	}


	public static final void replaceTextFieldPdf(String templatePdfPath, String destPdfPath,
			Map<String, String> params) {
		PdfDocument pdf = null;
		try {
			// 判断文件是否存在
			File file = new File(destPdfPath);
			if (!file.getParentFile().exists()) {
				file.getParentFile().mkdirs();
			}
			// 有参数才替换
			if (params != null && !params.isEmpty()) {
				pdf = new PdfDocument(new PdfReader(templatePdfPath), new PdfWriter(destPdfPath));
				PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
				Map<String, PdfFormField> fields = form.getFormFields(); // 获取所有的表单域
				for (String param : params.keySet()) {
					PdfFormField formField = fields.get(param); // 获取某个表单域
					if (formField != null) {
						formField.setFont(getImportFont("SourceHanSansCN-Regular.ttf")).setValue(params.get(param)); // 替换值
//						formField.setFont(getDefaultFont()).setValue(params.get(param)); // 替换值
					}
				}
				form.flattenFields();// 锁定表单,不让修改
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (pdf != null) {
				pdf.close();
			}
		}
	}

	
	public static final void replaceImageFieldPdf(String templatePdfPath, String destPdfPath,
			Map<String, String> params) throws FileNotFoundException, IOException {
		PdfDocument pdf = new PdfDocument(new PdfReader(templatePdfPath), new PdfWriter(destPdfPath));

		if (params != null && !params.isEmpty()) {// 有参数才替换
			PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
			Map<String, PdfFormField> fields = form.getFormFields(); // 获取所有的表单域
			for (String param : params.keySet()) {
				PdfFormField formField = fields.get(param);
				if (formField != null) {
					replaceFieldImage(params, pdf, param, formField); // 替换图片
				}
			}
			form.flattenFields();// 锁定表单,不让修改
		}
		pdf.close();
	}

	private static final void replaceFieldImage(Map<String, String> params, PdfDocument pdf, String param,
			PdfFormField formField) throws MalformedURLException {
		String value = params.get(param);
		String[] values = value.split("\\|");
		Rectangle rectangle = formField.getWidgets().get(0).getRectangle().toRectangle(); // 获取表单域的xy坐标
		PdfCanvas canvas = new PdfCanvas(pdf.getPage(Integer.parseInt(values[0])));
		ImageData image = ImageDataFactory.create(values[1]);
		float imageWidth = image.getWidth();
		float imageHeight = image.getHeight();
		float rectangleWidth = rectangle.getWidth();
		float rectangleHeight = rectangle.getHeight();

		float tempWidth = 0;
		float tempHeight = 0;

		int result = 1; // 压缩宽度
		if (imageWidth > rectangleWidth) {
			tempHeight = imageHeight * rectangleWidth / imageWidth;
			if (tempHeight > rectangleHeight) {
				tempHeight = rectangleHeight;
				result = 2; // 压缩高度
			} else {
				tempWidth = rectangleWidth;
				tempHeight = imageHeight * rectangleWidth / imageWidth;
			}
		} else {
			if (imageHeight > rectangleHeight) {
				tempHeight = rectangleHeight;
				result = 2;
			} else {
				result = 3;
			}
		}

		float y = 0;

		if (result == 1) { // 压缩宽度
			y = rectangleHeight - tempHeight;
		} else if (result == 3) { // 不压缩
			y = rectangleHeight - imageHeight;
		}

		// y/=2; // 如果想要图片在表单域的上下对齐,这个值除以2就行。同理可以计算x的偏移

		if (result == 1) {
			canvas.addImage(image, rectangle.getX(), rectangle.getY() + y, tempWidth, false);
		} else if (result == 2) {
			canvas.addImage(image, rectangle.getX(), rectangle.getY(), tempHeight, false, false);
		} else if (result == 3) {
			canvas.addImage(image, rectangle.getX(), rectangle.getY() + y, false);
		}
	}

	@SuppressWarnings("resource")
	public static final void addWatermark(String srcPdfPath, String destPdfPath, String watermarkText)
			throws FileNotFoundException, IOException {
		// 判断文件是否存在
		File f1 = new File(srcPdfPath);
		if (!f1.exists()) {
			return;
		}
		// 判断文件是否存在
		File f2 = new File(destPdfPath);
		if (!f2.getParentFile().exists()) {
			f2.getParentFile().mkdirs();
		}

		PdfDocument pdfDoc = new PdfDocument(new PdfReader(srcPdfPath), new PdfWriter(destPdfPath));

		pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, new IEventHandler() {
			@Override
			public void handleEvent(Event event) {
				PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
				PdfDocument pdfDoc = docEvent.getDocument();
				PdfPage page = docEvent.getPage();
				PdfFont font = null;
				font = getImportFont("STSong.ttf"); // 要显示中文水印的话,需要设置中文字体
				PdfCanvas canvas = new PdfCanvas(page);
				PdfExtGState gs1 = new PdfExtGState();
				gs1.setFillOpacity(0.7f); // 水印透明度
				canvas.setExtGState(gs1);
				new Canvas(canvas, pdfDoc, page.getPageSize()).setFontColor(ColorConstants.LIGHT_GRAY) // 颜色
						.setFontSize(60) // 字体大小
						.setFont(font) // 字体的格式 即导入的字体包
						// 水印的内容(中英文都支持) 坐标(例如:298f, 421f) 当前页数 最后的值为倾斜度(170)
						.showTextAligned(new Paragraph(watermarkText), 298, 421, pdfDoc.getPageNumber(page),
								TextAlignment.CENTER, VerticalAlignment.MIDDLE, 45);
			}
		});
		pdfDoc.close();
	}


	public static boolean pdfMerger(List<String> paths, String outputPath) {
		if (paths == null || paths.isEmpty() || StringUtils.isBlank(outputPath)) {
			return false;
		}
		// 首页与其他页创建方式不同,所以需要创建两个
		PdfDocument firstSourcePdf = null;
		PdfDocument secondSourcePdf = null;
		// 合并需要的工具类
		PdfMerger merger = null;
		try {
			for (int i = 0; i < paths.size(); i++) {
				if (i == 0) {
					PdfWriter pdfWriter = new PdfWriter(outputPath);
					// 启用完全压缩
//					pdfWriter.isFullCompression();
					firstSourcePdf = new PdfDocument(new PdfReader(paths.get(i)), pdfWriter);
					merger = new PdfMerger(firstSourcePdf);
					continue;
				}
				secondSourcePdf = new PdfDocument(new PdfReader(paths.get(i)));
				merger.merge(secondSourcePdf, 1, secondSourcePdf.getNumberOfPages());
				secondSourcePdf.close();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// 关闭流
			if (firstSourcePdf != null) {
				firstSourcePdf.close();
			}
			if (secondSourcePdf != null) {
				secondSourcePdf.close();
			}
			if (merger != null) {
				merger.close();
			}
		}
		return false;
	}

	public static String downPdf(HttpServletResponse response, String reviewName, String outputFilePath) {
		File file = new File(outputFilePath);
		if (!file.exists()) {
			return "下载文件不存在";
		}
		// 设置格式
		try {
			response.reset();
			response.setContentType("application/octet-stream");
			response.setCharacterEncoding("utf-8");
			response.setContentLength((int) file.length());
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(reviewName, "UTF-8"));
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		// 文件写出
		try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));) {
			byte[] buff = new byte[1024];
			OutputStream os = response.getOutputStream();
			int i = 0;
			while ((i = bis.read(buff)) != -1) {
				os.write(buff, 0, i);
				os.flush();
			}
		} catch (Exception e) {
			return "下载失败";
		} finally {
			// 删除服务器文件
			forceDelete(file);
		}
		return "下载成功";
	}

	public static boolean forceDelete(File f) {
		boolean result = false;
		int tryCount = 0;
		while (!result && tryCount++ < 10) {
//			System.gc();
			result = f.delete();
		}
		return result;
	}


	public static int forceBatchDelete(List<String> paths) {
		if (paths == null || paths.isEmpty()) {
			return 0;
		}
		int result = 0;
		for (int i = 0; i < paths.size(); i++) {
			boolean delete = forceDelete(new File(paths.get(i)));
			if (delete) {
				result++;
			}
		}
		return result;
	}

}

3、页码

/**
 * @author QiaoFengTao
 * @Title:
 * @Description: 生成页码辅助类
 * @date 2021/7/5 15:54
 */
public class TextFooterEventHandler implements IEventHandler {
    private Document document;
    private PdfFont font;

    public TextFooterEventHandler(Document document, PdfFont font){
        this.document = document;
        this.font = font;
    }

    @Override
    public void handleEvent(Event event) {
        PdfDocumentEvent pdfEvent = (PdfDocumentEvent) event;
        PdfPage page = pdfEvent.getPage();
        PdfDocument pdfDoc = pdfEvent.getDocument();
        //获取当前页码
        int pageNumber = pdfDoc.getPageNumber(page);
        PdfCanvas pdfCanvas = new PdfCanvas(page);
        PageSize pageSize = pdfDoc.getDefaultPageSize();
        pdfCanvas.beginText()
                .setFontAndSize(this.font, 12)
                .moveText(pageSize.getWidth() / 2 - 30, 20)
                .showText("- 第 " + pageNumber + " 页 -")
                .endText()
                .release();
    }
}

4、页眉页脚

/**
 * 页眉页脚
 * @author QiaoFengTao
 * @date 2021/7/15 18:41
 */
public class HeaderFooterHandler implements IEventHandler {

    private PdfFont font;

    public HeaderFooterHandler(PdfFont font) {
        this.font = font;
    }

    @Override
    public void handleEvent( Event event) {
        try {
            PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
            PdfDocument pdfDoc = docEvent.getDocument();
            Document doc = new Document(pdfDoc);
            PdfPage page = docEvent.getPage();
            Rectangle pageSize = page.getPageSize();
            float pdfWidth = pageSize.getWidth();
            float pdfHeight = pageSize.getHeight();
            PdfCanvas pdfCanvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);

            float tableWidth = pdfWidth - doc.getRightMargin() - doc.getLeftMargin();
            // 页眉
            float x0 = doc.getRightMargin(), y0 = pdfHeight - doc.getTopMargin() - 20;
            pdfCanvas.moveTo(x0, y0);
            Paragraph pageNameParagraph = new Paragraph();
            pageNameParagraph.setVerticalAlignment(VerticalAlignment.BOTTOM);
            pageNameParagraph.add(getLogoImage());
            pageNameParagraph.setTextAlignment(TextAlignment.RIGHT);
            pageNameParagraph.setFixedPosition(x0, y0, tableWidth);
            doc.add(pageNameParagraph);

        } catch (final Exception e) {
            e.printStackTrace();
        }

    }
    /*
     * 页眉logo
     **/
    private Image getLogoImage() {
        ClassPathResource resources = new ClassPathResource("\\static\\image\\header_logo.png");
        Image headerImg = null;
        try {
            headerImg = new Image(ImageDataFactory.create(resources.getURI().toString()));
        } catch (IOException e) {
            e.printStackTrace();
        }
        headerImg.scaleToFit(120, 150);
        return headerImg;
    }

}

5、添加图片到每页

/**
 * @author QiaoFengTao
 * @date 2021/7/19 18:02
 */
public class BackgroundEventHandler implements IEventHandler {

    public BackgroundEventHandler() {
    }

    @Override
    public void handleEvent(Event event) {

        PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
        PdfDocument pdfDoc = docEvent.getDocument();
        PdfPage page = docEvent.getPage();
        Rectangle pageSize = page.getPageSize();
        float pdfWidth = pageSize.getWidth();

        ClassPathResource resources = new ClassPathResource("\\static\\image\\pdf_bk.jpg");
        ImageData images = null;
        try {
            images = ImageDataFactory.create(resources.getURI().toString());
            images.setWidth(pdfWidth);
        } catch (IOException e) {
            e.printStackTrace();
        }
        PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);
        canvas.addImage(images,0,0,true);
    }

}
相关标签: java