很多时候,在项目中需要打单子,生成pdf格式,还需要盖章。
这个时候,就需要对pdf文件进行再次处理。
处理的方式就是:
1、获取要处理的位置
2、将要盖章的图片添加上去
代码如下:
public void printSign(OutputStream outputStream){
List<String> keyWords = new ArrayList<String>();
keyWords.add("打印人,打印机构");//支持多关键字,默认选择第一个找到的关键字
PdfReader pdfReader;
PdfStamper pdfStamper;
try {
pdfReader = new PdfReader(((ByteArrayOutputStream)outputStream).toByteArray());
pdfStamper = new PdfStamper(pdfReader, outputStream);
List<List<float[]>> arrayLists = findKeywords(keyWords, pdfReader);//查找关键字所在坐标
//一个坐标也没找到,就返回
if (ObjectUtil.isEmpty(arrayLists)) {
return;
}
if (!ObjectUtil.isEmpty(arrayLists.get(0))) {
for (int i=0; i<arrayLists.get(0).size(); i++) {
PdfContentByte overContent = pdfStamper.getOverContent((int)arrayLists.get
(0).get(i)[2]);
String imgPath = "/resource/lodop/sign.png";
float sealWidth = 150f;
float sealHeight = 95f;
InputStream pageHeaderInputstream = PDFUtil.class.getResourceAsStream
(imgPath);
Image pageHeaderImg = getImgByInputstream(pageHeaderInputstream);
pageHeaderImg.setAlignment(Element.ALIGN_LEFT);
pageHeaderImg.scaleAbsolute(sealWidth, sealHeight);// 控制签章大小
pageHeaderImg.setAbsolutePosition(arrayLists.get(0).get(i)[0],
arrayLists.get(0).get(i)[1] - sealHeight/2);// 控制图片位置
overContent.addImage(pageHeaderImg);//将图片加入pdf的内容中
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
//此处一定要关闭流,否则可能会出现乱码
if(pdfStamper != null){
pdfStamper.close();
}
}
}
/**
* 根据关键字返回对应的坐标
* @param keyWords
* @param pdfReader
* @return
*/
private static List<List<float[]>> findKeywords(final List<String> keyWords, PdfReader pdfReader) {
if (keyWords == null || keyWords.size() == 0) {
return null;
}
int pageNum = pdfReader.getNumberOfPages();
final List<List<float[]>> arrayLists = new ArrayList<List<float[]>>(keyWords.size());
for (int k=0; k<keyWords.size(); k++) {
List<float[]> positions = new ArrayList<float[]>();
arrayLists.add(positions);
}
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
try {
for (int i = 1; i <= pageNum; i++) {
final int finalI = i;
pdfReaderContentParser.processContent(i, new RenderListener() {
private StringBuilder pdfsb = new StringBuilder();
private float yy = -1f;
@Override
public void renderText(TextRenderInfo textRenderInfo) {
String text = textRenderInfo.getText();
com.itextpdf.awt.geom.Rectangle2D.Float boundingRectange =
textRenderInfo.getBaseline().getBoundingRectange();
if(yy == -1f) {
yy = boundingRectange.y;
}
if(yy != boundingRectange.y) {
yy = boundingRectange.y;
pdfsb.setLength(0);
}
pdfsb.append(text);
if (pdfsb.length()>0) {
for (int j=0; j<keyWords.size(); j++) {
List<String> key_words = ListUtil.parseList
(keyWords.get(j), ",");
//假如配置了多个关键字,找到一个就跑
for (final String key_word : key_words) {
if (arrayLists.get(j) != null)
{
break;
}
if (pdfsb.length()>0 && pdfsb.toString
().contains(key_word)) {
float[] resu = new float[3];
resu[0] = boundingRectange.x +
boundingRectange.width * (key_word.length()-1);
resu[1] = boundingRectange.y;
resu[2] = finalI;
arrayLists.get(j).add(resu);
pdfsb.setLength(0);
break;
}
}
}
}
}
@Override
public void renderImage(ImageRenderInfo arg0) {
//renderImage
}
@Override
public void endTextBlock() {
//endTextBlock
}
@Override
public void beginTextBlock() {
//beginTextBlock
}
});
}
} catch (Exception e) {
e.printStackTrace();
}
return arrayLists;
}
public static List<String> parseList(String source, String regex) {
if (source == null || "".equals(source)) {
return null;
}
List<String> strList = new ArrayList<String>();
if (regex== null || "".equals(regex)) {
strList.add(source);
} else {
String[] strArr = source.split(regex);
for (String str : strArr) {
if (str!= null || !"".equals(str)) {
strList.add(str);
}
}
}
return strList;
}
private static Image getImgByInputstream(InputStream is) {
if (is == null) {
return null;
}
ByteArrayOutputStream output = new ByteArrayOutputStream();
Image img = null;
try {
readInputStream(is, output);
try {
img = Image.getInstance(output.toByteArray());
} catch (BadElementException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
return img;
}
public static void readInputStream(InputStream inputStream, OutputStream outputStream) throws IOException{
byte[] buffer = new byte[2048];
int n = 0;
while (-1 != (n = inputStream.read(buffer))) {
outputStream.write(buffer, 0, n);
}
inputStream.close();
}
1、将上面的代码考到项目中,把该导的包导好。该方法所需的类都在iTextpdf里 https://download.csdn.net/download/esc_tab_end/10730983 。如果你的报表里还需要什么条形码生成的。可以下载条形码所需的包: https://download.csdn.net/download/esc_tab_end/10730999
2、然后调用printSign方法。
2.1 printSign方法入参是pdf的二进制流对象。
2.2 还有就是关键字写上自己所需要的关键字就行了。方法内的代码都是现成的,不需要改动,若有特殊需求可以自己微调。
注意:pdf中的关键字的字体必须是中文字体,例如:宋体,黑体,楷体等等。如果pdf生成的时候关键字是用英文字体例如:Arial,Dialog等等这些。
效果图如下: