位置:首页 » 文章/教程分享 » java pdfbox2.0.0 获取表格和字
获取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.
 * 
 * 

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

", 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

", 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)
", 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
", 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)
", 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)
", 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("

..............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;
            }
        
    }
}