獲取pdf中的表格線和字的座標直接改路徑就能夠實現功能,官方給出的例子,經過本身的修改也可分開顯示各類橫線豎線。我本身的改動沒有給出。html
最後的兩個函數是在某網站上找的,沒仔細看,也是獲取表格的。java
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; } } }
參考網站:express
一、https://svn.apache.org/viewvc/pdfbox/trunk/examples/src/main/java/org/apache/pdfbox/examples/apache
二、http://www.simosh.com/article/dfeajcid-how-to-find-table-border-lines-in-pdf-using-pdfbox.htmlapp