pdf操作依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.7</version>
<type>pom</type>
</dependency>
代码
@Test
public void test1() throws IOException {
String pdfPath = "C:\\Users\\DELL\\Desktop\\xxx.pdf";
String targetPath = "C:\\Users\\DELL\\Desktop\\3.pdf";
Map<String, String> keyWords = new HashMap<>();
keyWords.put("定位文字1", "文字替换");
keyWords.put("定位文字2", "20231");
keyWords.put("定位存放图片位置", "");
//加载源文件
PdfWriter pdfWriter = new PdfWriter(targetPath);
pdfWriter.setSmartMode(true);
PdfReader pdfReader = new PdfReader(pdfPath);
PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter);
int numberOfPages = pdfDocument.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++) {
PdfPage page = pdfDocument.getPage(i);
//获取关键字坐标
List<IPdfTextLocation> keyWordPositions = PdfFillUtil.getKeyWordPositions(page, keyWords);
if (CollectionUtils.isEmpty(keyWordPositions)) {
continue;
}
//根据坐标覆盖替换文件
PdfCanvas canvas = new PdfCanvas(page.newContentStreamAfter(), page.getResources(), pdfDocument);
//设置行间距
canvas.setLineWidth(0.5f);
for (IPdfTextLocation location : keyWordPositions) {
float x = 0;
float y = 0;
if (location.getText().equals("机下关时")) {
//白色遮罩层覆盖原文本
canvas.setFillColor(ColorConstants.WHITE);
//修正遮罩背景位置
Rectangle rectangle = location.getRectangle();
canvas.rectangle(rectangle);
canvas.fill();
y = location.getRectangle().getY() + 2;
x = location.getRectangle().getX();
} else if (location.getText().equals("期限至")) {
x = location.getRectangle().getX() + location.getRectangle().getWidth() + 3;
y = location.getRectangle().getY() + 2;
}
if (location.getText().equals("(接关印)")) {
PdfCanvas pdfCanvas = new PdfCanvas(pdfDocument.getPage(i));
ImageData imageData = ImageDataFactory.create("C:\\Users\\DELL\\Desktop\\showSeal.jpg");
Image image = new Image(imageData);
//设置图片透明度
// PdfExtGState tranState = new PdfExtGState();
// tranState.setFillOpacity(0.4f);
// pdfCanvas.saveState().setExtGState(tranState);
Rectangle rectangle = new Rectangle(location.getRectangle().getX(),
location.getRectangle().getY(), 80, 80);
Canvas canvas1 = new Canvas(pdfCanvas, pdfDocument, rectangle);
canvas1.add(image);
} else {
//开始文本填充
canvas.beginText();
//设置字体和大小
PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false);
canvas.setFontAndSize(font, 14);
canvas.setFillColor(ColorConstants.BLACK);
//修正填充文字位置
canvas.setTextMatrix(x, y);
Optional<Map.Entry<String, String>> first = keyWords.entrySet().stream().filter(item -> item.getKey().equals(location.getText())).findFirst();
canvas.showText(first.get().getValue());
//结束文本填充
canvas.endText();
canvas.closePath();
}
}
}
pdfDocument.close();
pdfWriter.close();
pdfReader.close();
}
public class PdfFillUtil {
public static void fillPdf(OutputStream outputStream, InputStream inputStream, List<FillVo> fillVos) throws IOException, SQLException {
//加载源文件
PdfWriter pdfWriter = new PdfWriter(outputStream);
pdfWriter.setSmartMode(true);
PdfDocument pdfDocument = new PdfDocument(new PdfReader(inputStream), pdfWriter);
//根据页数分组,分页填充
Map<Integer, List<FillVo>> collect = fillVos.stream()
.sorted(Comparator.comparing(FillVo::getPage)).collect(Collectors.groupingBy(FillVo::getPage));
//根据Key页数值填充数据
for (Map.Entry<Integer, List<FillVo>> val : collect.entrySet()) {
Integer key = val.getKey();
List<FillVo> fillConfig = val.getValue();
for (FillVo fillVo : fillConfig) {
if (key != null) {
PdfPage page = pdfDocument.getPage(key);
//获取关键字坐标
IPdfTextLocation keyWordPosition = getKeyWordPosition(page, fillVo.getKeyWord());
fillVo.setiPdfTextLocation(keyWordPosition);
}
}
}
for (FillVo fillVo : fillVos) {
extracted(pdfDocument, fillVo);
}
pdfDocument.close();
pdfWriter.close();
outputStream.close();
inputStream.close();
}
private static void extracted(PdfDocument pdfDocument, FillVo fillVo) throws IOException, SQLException {
PdfPage page = pdfDocument.getPage(fillVo.getPage());
//获取关键字坐标
IPdfTextLocation keyWordPosition = fillVo.getiPdfTextLocation();
if (keyWordPosition == null) {
return;
}
//文字填充X坐标
float positionX = keyWordPosition.getRectangle().getX() + Float.parseFloat(fillVo.getShiftX());
//根据规则,看是否正向,反向偏移关键词长度坐标
positionX = KeyWidthMoveEnum.calculatePosition(positionX, fillVo.getKeywordWidthX(), keyWordPosition.getRectangle().getWidth());
//获取Y坐标
float positionY = keyWordPosition.getRectangle().getY() + Float.parseFloat(fillVo.getShiftY());
//判断是否是靠边框,需要动态测距
if (CommonEnum.IS_TRUE.getCode().equals(fillVo.getIsBorderFill())) {
//页面最右侧坐标,减去空白宽度,计算实际内容最右侧坐标
float contentRight = page.getPageSize().getRight() - Float.parseFloat(fillVo.getConPageDic());
//X坐标超出最右侧内容宽度,则进行换行
if (positionX > contentRight) {
positionX = positionX - contentRight + Float.parseFloat(fillVo.getConPageDic());
positionY = positionY - Float.parseFloat(fillVo.getRowSpacing());
}
//X坐标超出最左侧坐标内容宽度,则向上进行换行
if (positionX < Float.parseFloat(fillVo.getConPageDic())) {
positionX = contentRight - positionX;
positionY = positionY + Float.parseFloat(fillVo.getRowSpacing());
}
}
//根据坐标覆盖替换文件
PdfCanvas canvas = new PdfCanvas(page.setIgnorePageRotationForContent(true).newContentStreamAfter(), page.getResources(), pdfDocument);
//设置行间距
canvas.setLineWidth(0.5f);
//白色覆盖原字
// canvas.setFillColor(ColorConstants.WHITE);
//修正遮罩背景位置
// Rectangle rectangle = keyWordPosition.getRectangle();
// canvas.rectangle(rectangle);
// canvas.fill();
if (fillVo.isSign() && fillVo.getSign() == null) {
return;
}
//开始文本填充
canvas.beginText();
//公章填充
if (fillVo.isSign()) {
byte[] bytes = FileUtil.BlobToBytes(fillVo.getSign());
ImageData imageData = ImageDataFactory.create(bytes);
// imageData.setWidth(80);
// imageData.setHeight(80);
// canvas.addImage(imageData, positionX, positionY, false);
Image image = new Image(imageData);
image.setTextAlignment(TextAlignment.JUSTIFIED);
Rectangle rectangle = new Rectangle(positionX, positionY, 85, 85);
PdfExtGState tranState = new PdfExtGState();
tranState.setFillOpacity(0.4f);
canvas.saveState().setExtGState(tranState);
new Canvas(canvas, pdfDocument, rectangle)
.setFontColor(ColorConstants.LIGHT_GRAY)
.add(image);
// ImageData imageData = ImageDataFactory.create("C:\\Users\\DELL\\Desktop\\公章截图.jpg");
// Image image = new Image(imageData);
// image.setTextAlignment(TextAlignment.JUSTIFIED);
// Rectangle rectangle = new Rectangle(positionX, positionY, 80, 80);
//
// PdfExtGState tranState = new PdfExtGState();
// tranState.setFillOpacity(0.4f);
// canvas.saveState().setExtGState(tranState);
// new Canvas(canvas, pdfDocument, rectangle)
// .setFontColor(ColorConstants.LIGHT_GRAY)
// .add(image);
} else {
//设置字体和大小
PdfFont font = PdfFontFactory.createFont("STSong-Light", "UniGB-UCS2-H", false);
canvas.setFontAndSize(font, Float.parseFloat(fillVo.getFontSize()));
canvas.setFillColor(ColorConstants.BLACK);
//修正填充文字位置
canvas.setTextMatrix(positionX, positionY);
canvas.showText(fillVo.getReplaceWord());
}
//结束文本填充
canvas.endText();
}
/**
* @return
* @Author xiangyong.zeng
* @Description 获取关键词坐标位置
* @Date 16:30 2023/2/22
* @Param
**/
public static List<IPdfTextLocation> getKeyWordPositions(PdfPage page, Map<String, String> keyWords) {
List<IPdfTextLocation> locations = new ArrayList<>();
for (Map.Entry<String, String> val : keyWords.entrySet()) {
RegexBasedLocationExtractionStrategy strategy = new RegexBasedLocationExtractionStrategy(val.getKey());
PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(strategy);
canvasProcessor.processPageContent(page);
Collection<IPdfTextLocation> resultantLocations = strategy.getResultantLocations();
locations.addAll(resultantLocations);
}
return locations;
}
/**
* @return
* @Author xiangyong.zeng
* @Description 获取关键词坐标位置
* @Date 16:30 2023/2/22
* @Param
**/
public static IPdfTextLocation getKeyWordPosition(PdfPage page, String keyWord) {
RegexBasedLocationExtractionStrategy strategy = new RegexBasedLocationExtractionStrategy(keyWord);
PdfCanvasProcessor canvasProcessor = new PdfCanvasProcessor(strategy);
canvasProcessor.processPageContent(page);
List<IPdfTextLocation> resultantLocations = (List<IPdfTextLocation>) strategy.getResultantLocations();
if (CollectionUtils.isEmpty(resultantLocations)) {
return null;
}
return resultantLocations.get(0);
}
ofd依赖
参考:https://gitee.com/ofdrw/ofdrw#/ofdrw/ofdrw/blob/master/ofdrw-full
<dependency>
<groupId>org.ofdrw</groupId>
<artifactId>ofdrw-full</artifactId>
<version>1.20.2</version>
</dependency>
ofd定位填充代码
@Test
public void testTemplateTextBaseKeyword() throws IOException, DocumentException {
Path inP = Paths.get("C:\\Users\\DELL\\Desktop\\xxxxx.ofd");
Path outP = Paths.get("C:\\Users\\DELL\\Desktop\\32.ofd");
try (OFDReader reader = new OFDReader(inP);
OFDDoc ofdDoc = new OFDDoc(reader, outP)) {
String t1 = "定位文字1";
String f1 = "替换文本";
String t2 = "定位文字2";
String[] keywords = {t1, t2};
List<KeywordPosition> positionList = KeywordExtractor.getKeyWordPositionList(reader, keywords);
//偏移量需要模板制作确认
float offset = 5;
Annotation annotation = null;
int num = 0;
for (KeywordPosition position : positionList) {
//创建可追加的虚拟页面
AdditionVPage page = ofdDoc.getAVPage(position.getPage());
//创建一个可以自动换行的段落
Paragraph paragraph = new Paragraph();
paragraph.setPosition(Position.Absolute)
.setWidth(f1.length() * 5.0).setHeight(10D) //设置外接矩形宽高
.setX(position.getBox().getTopLeftX() + position.getBox().getWidth() + offset) //设置x坐标
.setY(position.getBox().getTopLeftY() + 1); //设置y坐标
//创建 Span 文本控件对象
Span span = null;
if (t1.equals(position.getKeyword())) {
span = new Span(f1);
//设置Span的属性
span.setFontSize(5.0);
span.setColor(0, 0, 0);
//段落添加Span文本控件
paragraph.add(span);
//页面添加段落
page.add(paragraph);
}
num++;
if (num == 2) {
Double width = ofdDoc.getPageLayout().getWidth();
Double height = ofdDoc.getPageLayout().getHeight();
annotation = new Annotation(new ST_Box(0d, 0d, width, height), AnnotType.Watermark, ctx -> {
ctx.drawImage(Paths.get("C:\\Users\\DELL\\Desktop\\2222.jpg"), position.getBox().getTopLeftX(),
position.getBox().getTopLeftY() - 20, 40, 40);
ctx.restore();
});
}
}
//水印添加页
ofdDoc.addAnnotation(3, annotation);
}
}
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext7-core</artifactId>
<version>7.1.7</version>
<type>pom</type>
</dependency>
public static void main(String[] args) throws IOException {
PdfReader pdfReader = new PdfReader("C:\\Users\\DELL\\Desktop\\换xxx.pdf");
PdfDocument pdfDocument = new PdfDocument(pdfReader);
PdfWriter pdfWriter = new PdfWriter("C:\\Users\\DELL\\Desktop\\test111.pdf");
PdfDocument outPdfDocument = new PdfDocument(pdfWriter);
pdfDocument.copyPagesTo(1, 1, outPdfDocument);
//关闭
outPdfDocument.close();
pdfWriter.close();
pdfDocument.close();
pdfReader.close();
}