更新时间:2021-11-29
@[PDF]工具类涉及:1.添加水印 2.设置签名域 3.获取文件签名域信息
这里的方法基于com.itextpdf.text包
maven坐标:
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.13.2</version>
</dependency>
1.添加水印
/** * * @param filePath 需要添加水印的文件 * @param waterMark 水印内容 * @param outPath 输出文件路径 * @throws Exception */
public static void waterMarkAdd(String filePath,String waterMark,String outPath) throws Exception{
byte[] bytes = getByteString(filePath);
PdfReader reader = new PdfReader(bytes);
PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(outPath));
BaseFont baseFont = BaseFont.createFont();
Rectangle pageRect = null;
PdfGState pdfGState = new PdfGState();
pdfGState.setFillOpacity(0.3f);
pdfGState.setStrokeOpacity(0.4f);
int total = reader.getNumberOfPages()+1;
JLabel label = new JLabel();
FontMetrics fontMetrics;
int textHeight = 0;
int textWidth = 0;
label.setText(waterMark);
fontMetrics = label.getFontMetrics(label.getFont());
textHeight = fontMetrics.getHeight();
textWidth = fontMetrics.stringWidth(label.getText());
PdfContentByte contentByte;
int numJ = 0 ;
int numK = 0 ;
for(int i=1; i<total;i++){
pageRect = reader.getPageSizeWithRotation(i);
contentByte = stamper.getOverContent(i);
contentByte.saveState();
contentByte.setGState(pdfGState);
contentByte.beginText();
contentByte.setFontAndSize(baseFont,24);
contentByte.setColorFill(BaseColor.BLACK);
// 你可以随心所欲的改你自己想要的角度
for (int height = textHeight; height < pageRect
.getHeight(); height = height + textHeight * 5) {
numJ ++ ;
for (int width = textWidth; width < pageRect
.getWidth() + textWidth; width = width + textWidth * 3) {
numK ++ ;
// 设置水印文字成角度倾斜
contentByte.showTextAligned(Element.ALIGN_LEFT,
waterMark, width - textWidth, height - textWidth,
35);
}
}
// contentByte.showTextAligned(Element.ALIGN_LEFT,
// waterMark, reader.getPageSize(i).getWidth()/2, reader.getPageSize(i).getHeight()/2,
// 45);
// 添加水印文字
contentByte.endText();
}
stamper.close();
reader.close();
}
/** * 文件转byte流 * @param path 文件路径 * @return 返回byte[] * @throws IOException */
private static byte[] getByteString(String path) throws IOException {
File file = new File(path);
byte[] buf = new byte[1024];
int len = 0;
FileInputStream fis = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
while((len = fis.read(buf))!=-1){
bos.write(buf,0,len);
}
bos.flush();
fis.close();
bos.close();
return bos.toByteArray();
}
2.设置签名域
public static byte[] setSignArea(byte[] tail,Map position, List posConfigSet) throws Exception {
int xIndex = 0;
int yIndex = 0;
int yMax = 780;
int yMin = 72;
PdfReader reader = new PdfReader(tail);
ByteArrayOutputStream baoPdfStream = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, baoPdfStream);
// 创建数组签名域
int width = 50, height = 50;
int pageNo = position.getInt("PAGE_NUM");
float x_pos = Float.parseFloat(position.getString("X_POS"))-xIndex;
float y_pos = Float.parseFloat(position.getString("Y_POS"))-yIndex;
y_pos = y_pos > yMax ? yMax : y_pos;
y_pos = y_pos < yMin ? yMin : y_pos;
Rectangle areaSignatureRect =
new Rectangle(x_pos,y_pos,x_pos + width,y_pos + height);
PdfFormField pdfFormField = PdfFormField.createSignature(stamper.getWriter());
pdfFormField.setWidget(areaSignatureRect, PdfAnnotation.HIGHLIGHT_NONE);
pdfFormField.setFieldName("signatureOne"); // 签名域标识
pdfFormField.setPage(pageNo);
stamper.addAnnotation(pdfFormField, pageNo);
//必须关闭,否则创建的PDF为0KB
stamper.close();
return baoPdfStream.toByteArray();
}
3.查看签名域信息
需要 com.spire.pdf 包
/** * * @param filePath 文件路径 * @return list 返回签名域信息集 */
public List<Map<String,String>> getSignature(String filePath) {
List<Map<String,String>> list = new ArrayList<>();
Map<String,String> result = new HashMap<>();
//创建PdfDocument实例
PdfDocument pdf = new PdfDocument();
//加载含有签名的PDF文件
pdf.loadFromFile(filePath);
//获取域集合
PdfFormWidget pdfFormWidget = (PdfFormWidget) pdf.getForm();
PdfFormFieldWidgetCollection pdfFormFieldWidgetCollection = pdfFormWidget.getFieldsWidget();
//遍历域
for (int i = 0; i < pdfFormFieldWidgetCollection.getCount(); i++) {
//判定是否为签名域
if (pdfFormFieldWidgetCollection.get(i) instanceof PdfSignatureFieldWidget) {
//获取签名域
PdfSignatureFieldWidget signatureFieldWidget = (PdfSignatureFieldWidget) pdfFormFieldWidgetCollection
.get(i);
//获取签名
PdfSignature signature = signatureFieldWidget.getSignature();
String location = signature.getLocationInfo();
String reason = signature.getReason();
String data = signature.getDate().toString();
String name = signature.getSignatureName();
result.put("location",location);
result.put("reason",reason);
result.put("data",data);
result.put("name",name);
list.add(result);
System.out.println(
"location:" + location + ",reason:" + reason + ",data:" + data + ",name:" + name);
}
}
return list;
}
4 获取关键字位置坐标
//因匿名内部类原因定义为成员变量
private int i = 0;
/** * 获取关键字位置坐标 * @param pdfIn pdf文件byte流 * @param keyWord 关键字 * @return 位置信息列表 [0]:x [1]:y [2]页数 * @throws Exception */
public List getPosition(byte[] pdfIn, String keyWord) throws Exception {
List list = new ArrayList();
PdfReader pdfReader = new PdfReader(pdfIn);
int numberOfPages = pdfReader.getNumberOfPages();
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
for (i = 1; i <= numberOfPages; i++) {
pdfReaderContentParser.processContent(i, new RenderListener() {
@Override
public void renderText(TextRenderInfo textRenderInfo) {
String text = textRenderInfo.getText(); // 整页内容
if (null != text && text.contains(keyWord)) {
Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
float[] arr = new float[3];
arr[0] = boundingRectange.x;
arr[1] = boundingRectange.y;
arr[2] = i;
list.add(arr);
}
}
@Override
public void renderImage(ImageRenderInfo arg0) {
}
@Override
public void endTextBlock() {
}
@Override
public void beginTextBlock() {
}
});
}
return list;
}
5 签章签名填充日期换页时位置调整
/** * * @param pageSet 文件byte流 * @param position 页数 x y * @return * @throws IOException * @throws DocumentException */
public static byte[] fillDate(byte[] pageSet,List<Float> position) throws IOException, DocumentException {
//盖章日期填充偏移量 签名与日期同页偏移
float y = -40f;
float x = 0f;
//判断是否翻页标志位
float index = 73;
File modelFile = new File(System.getProperty("user.dir"));
if (!modelFile.exists()) {
modelFile.mkdirs();
}
String nowDate = LocalDate.now().toString();
PdfReader reader = new PdfReader(pageSet);
FileOutputStream fos = new FileOutputStream(System.getProperty("user.dir") + "/" + nowDate + ".pdf");
PdfStamper stamper = new PdfStamper(reader,fos);
Integer pageNum = Integer.parseInt(position.get(2).toString());
String xPos = position.get(0).toString();
String yPos = position.get(1).toString();
//签名与日期分页时特殊处理 ,如间距更大需继续特殊处理
if (java.lang.Float.parseFloat(yPos) < index) {
pageNum++;
// 第一行:68 (729)第二行56 (711)第三行44(723)
if(java.lang.Float.parseFloat(yPos)<74&& java.lang.Float.parseFloat(yPos)>60){
y = 729;
}else if(java.lang.Float.parseFloat(yPos)<60&& java.lang.Float.parseFloat(yPos)>52){
y= 711;
}else if (java.lang.Float.parseFloat(yPos)<48&& java.lang.Float.parseFloat(yPos)>40){
y = 723;
}
}
PdfContentByte pdfContentByte = stamper.getOverContent(pageNum);
pdfContentByte.beginText();
// 设置字体及字号
pdfContentByte.setColorFill(BaseColor.DARK_GRAY);
pdfContentByte.setFontAndSize(BaseFont.createFont(), 10);
pdfContentByte.showTextAligned(Element.ALIGN_LEFT, nowDate,
java.lang.Float.parseFloat(xPos) + x, y+ java.lang.Float.parseFloat(yPos), 0);
pdfContentByte.endText();
stamper.close();
// 将输出流关闭
fos.close();
reader.close();
File file = new File(System.getProperty("user.dir") + "/" + nowDate+ ".pdf");
byte[] outputStream = FileCopyUtils.copyToByteArray(file);
delFile(file);
return outputStream;
}
public static void delFile(File file) {
if (file.exists() && file.isFile()) {
file.delete();
}
}
6.PDF模板数据填充
pom依赖
<dependency>
<groupId>freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.9</version>
</dependency>
/** * * @param param 填充参数 * @param bytes 待文件文件流 * @param fileName 文件名 * @return * @throws Exception */
public static String processHtmlParam(Map param,byte[] bytes,String fileName) throws Exception {
File modelFile = new File(System.getProperty("user.dir"));
if (!modelFile.exists()) {
modelFile.mkdirs();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(System.getProperty("user.dir") + "/" + fileName);
fos.write(bytes);
}catch (Exception e) {
System.out.println("文件写入失败 : " + e.getMessage());
} finally {
if ( null!=fos ) {
fos.close();
}
}
Configuration config = new Configuration();
config .setDirectoryForTemplateLoading(modelFile);
config .setObjectWrapper(new DefaultObjectWrapper());
config .setDefaultEncoding("UTF-8");
config .setClassicCompatible(true);
Template template = config .getTemplate(fileName);
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
template.process(param, writer);
String htmlStr = stringWriter.toString();
writer.flush();
writer.close();
delFile(System.getProperty("user.dir"),fileName);
return htmlStr;
}
7.将字符串转换为PDF
/** * 根据html字符串内容生成pdf * * @param pdfFilePath pdf文件存储位置 * @param htmlcontent html内容 */
public static void parseHtml2PdfByString(String pdfFilePath, String htmlcontent) throws Exception{
Document document = new Document();
PdfWriter writer = null;
try {
writer = PdfWriter.getInstance(document, new FileOutputStream(pdfFilePath));
// 设置底部距离60,解决重叠问题
document.setPageSize(PageSize.A4);
document.setMargins(50, 45, 50, 60);
document.setMarginMirroring(false);
document.open();
XMLWorkerHelper.getInstance().parseXHtml(writer, document, new ByteArrayInputStream(htmlcontent.getBytes("UTF-8")), null, Charset
.forName("UTF-8"), new MyFontProvider("C:\\Users\\rw\\Desktop\\ss.ttf"));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != document) {
document.close();
}
if (null != writer) {
writer.close();
}
}
}
未完待续…
今天的文章java.pdf_java提取pdf文件中某一页分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88600.html