获取pdf中的表格线和字的坐标直接改路径就可以实现功能,官方给出的例子,通过自己的修改也可分开显示各种横线竖线。我自己的改动没有给出。
最后的两个函数是在某网站上找的,没仔细看,也是获取表格的。
package testpdf1;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.pdfbox.contentstream.PDFGraphicsStreamEngine;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.graphics.color.PDColor;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotation;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.rendering.PageDrawer;
import org.apache.pdfbox.rendering.PageDrawerParameters;
import org.apache.pdfbox.util.Matrix;
import org.apache.pdfbox.util.Vector;
/**
* Example showing custom rendering by subclassing PageDrawer.
*
* <p>If you want to do custom graphics processing rather than Graphics2D rendering, then you should
* subclass {@link PDFGraphicsStreamEngine} instead. Subclassing PageDrawer is only suitable for
* cases where the goal is to render onto a Graphics2D surface.
*
* @author John Hewson
*/
public class CustomPageDrawer
{
public static void main(String[] args) throws IOException
{
File file = new File("/Users/pengfei/Desktop/person2.pdf");
PDDocument doc = PDDocument.load(file);
PDFRenderer renderer = new MyPDFRenderer(doc);
BufferedImage image = renderer.renderImage(0);
ImageIO.write(image, "PNG", new File("/Users/pengfei/Desktop/custom-render.png"));
doc.close();
}
/**
* Example PDFRenderer subclass, uses MyPageDrawer for custom rendering.
*/
private static class MyPDFRenderer extends PDFRenderer
{
MyPDFRenderer(PDDocument document)
{
super(document);
}
@Override
protected PageDrawer createPageDrawer(PageDrawerParameters parameters) throws IOException
{
return new MyPageDrawer(parameters);
}
}
/**
* Example PageDrawer subclass with custom rendering.
*/
private static class MyPageDrawer extends PageDrawer
{
MyPageDrawer(PageDrawerParameters parameters) throws IOException
{
super(parameters);
}
/**
* Color replacement.
*/
@Override
protected Paint getPaint(PDColor color) throws IOException
{
// if this is the non-stroking color
if (getGraphicsState().getNonStrokingColor() == color)
{
// find red, ignoring alpha channel
if (color.toRGB() == (Color.RED.getRGB() & 0x00FFFFFF))
{
// replace it with blue
return Color.BLUE;
}
}
return super.getPaint(color);
}
/**
* Glyph bounding boxes.
*/
@Override
protected void showGlyph(Matrix textRenderingMatrix, PDFont font, int code, String unicode,
Vector displacement) throws IOException
{
// draw glyph
super.showGlyph(textRenderingMatrix, font, code, unicode, displacement);
// bbox in EM -> user units
Shape bbox = new Rectangle2D.Float(0, 0, font.getWidth(code) / 1000, 1);
AffineTransform at = textRenderingMatrix.createAffineTransform();
bbox = at.createTransformedShape(bbox);
// save
Graphics2D graphics = getGraphics();
Color color = graphics.getColor();
Stroke stroke = graphics.getStroke();
Shape clip = graphics.getClip();
// draw
graphics.setClip(graphics.getDeviceConfiguration().getBounds());
graphics.setColor(Color.BLACK);
graphics.setStroke(new BasicStroke(.5f));
graphics.draw(bbox);
// restore
graphics.setStroke(stroke);
graphics.setColor(color);
graphics.setClip(clip);
}
/**
* Filled path bounding boxes.
*/
@Override
public void fillPath(int windingRule) throws IOException
{
//printPath();
//System.out.printf("Fill; windingrule: %s\n\n", windingRule);
//getLinePath().reset();
// bbox in user units
Shape bbox = getLinePath().getBounds2D();
System.out.print("fillpath:");
System.out.println(bbox);
// draw path (note that getLinePath() is now reset)
super.fillPath(windingRule);
// save
Graphics2D graphics = getGraphics();
Color color = graphics.getColor();
Stroke stroke = graphics.getStroke();
Shape clip = graphics.getClip();
// draw
graphics.setClip(graphics.getDeviceConfiguration().getBounds());
graphics.setColor(Color.RED);
graphics.setStroke(new BasicStroke(.5f));
graphics.draw(bbox);
// restore
graphics.setStroke(stroke);
graphics.setColor(color);
graphics.setClip(clip);
getLinePath().reset();
}
@Override
public void strokePath() throws IOException
{
//printPath();
//System.out.printf("Stroke; unscaled width: %s\n\n", getGraphicsState().getLineWidth());
// bbox in user units
Shape bbox = getLinePath().getBounds2D();
System.out.print("stroke:");
System.out.println(bbox);
// draw path (note that getLinePath() is now reset)
// super.fillPath(windingRule);
// save
Graphics2D graphics = getGraphics();
Color color = graphics.getColor();
Stroke stroke = graphics.getStroke();
Shape clip = graphics.getClip();
// draw
graphics.setClip(graphics.getDeviceConfiguration().getBounds());
graphics.setColor(Color.RED);
graphics.setStroke(new BasicStroke(.5f));
graphics.draw(bbox);
// restore
graphics.setStroke(stroke);
graphics.setColor(color);
graphics.setClip(clip);
getLinePath().reset();
}
/**
* Custom annotation rendering.
*/
@Override
public void showAnnotation(PDAnnotation annotation) throws IOException
{
// save
saveGraphicsState();
// 35% alpha
getGraphicsState().setNonStrokeAlphaConstants(0.35);
super.showAnnotation(annotation);
// restore
restoreGraphicsState();
}
int countlines = 0;
/**
* 网站上的找的
*/
void printPath()
{
GeneralPath path = getLinePath();
PathIterator pathIterator = path.getPathIterator(null);
double x = 0, y = 0;
double coords[] = new double[6];
while (!pathIterator.isDone()) {
countlines ++;
switch (pathIterator.currentSegment(coords)) {
case PathIterator.SEG_MOVETO:
System.out.printf("Move to (%s %s)\n", coords[0], (coords[1]));
x = coords[0];
y = coords[1];
break;
case PathIterator.SEG_LINETO:
double width = getEffectiveWidth(coords[0] - x, coords[1] - y);
System.out.printf("Line to (%s %s), scaled width %s\n", coords[0], (coords[1]), width);
x = coords[0];
y = coords[1];
break;
case PathIterator.SEG_QUADTO:
System.out.printf("Quad along (%s %s) and (%s %s)\n", coords[0], (coords[1]), coords[2], (coords[3]));
x = coords[2];
y = coords[3];
break;
case PathIterator.SEG_CUBICTO:
System.out.printf("Cubic along (%s %s), (%s %s), and (%s %s)\n", coords[0], (coords[1]), coords[2], (coords[3]), coords[4], (coords[5]));
x = coords[4];
y = coords[5];
break;
case PathIterator.SEG_CLOSE:
System.out.println("Close path");
}
pathIterator.next();
}
System.out.printf("\n\n..............countlines:%d",countlines);
}
double getEffectiveWidth(double dirX, double dirY)
{
if (dirX == 0 && dirY == 0)
return 0;
Matrix ctm = getGraphicsState().getCurrentTransformationMatrix();
double widthX = dirY;
double widthY = -dirX;
double widthXTransformed = widthX * ctm.getValue(0, 0) + widthY * ctm.getValue(1, 0);
double widthYTransformed = widthX * ctm.getValue(0, 1) + widthY * ctm.getValue(1, 1);
double factor = Math.sqrt((widthXTransformed*widthXTransformed + widthYTransformed*widthYTransformed) / (widthX*widthX + widthY*widthY));
return getGraphicsState().getLineWidth() * factor;
}
}
}
参考网站:
1、https://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/
2、http://www.simosh.com/article/dfeajcid-how-to-find-table-border-lines-in-pdf-using-pdfbox.html