1

我尝试使用库 PDFBox 编辑文本,但不知道如何。我不知道如何获取单个文本对象的流,所以我可以编辑文本和/或颜色。

任何想法,例如?谢谢

4

2 回答 2

1

我发现在 pdf 中编辑文本不可靠,因此尝试使用矩形(白色/背景色填充)清除文本并将新文本写入已清除的位置。这是一个示例代码。

//to add a link in footer
//to replace a text
//to replace a link/url/href
public static void editTextorUrl(String inputFile, String outputFile)
        throws IOException, COSVisitorException {
    // the document
    PDDocument doc = null;
    try {
        System.out.println(inputFile);
        doc = PDDocument.load(inputFile);
        List pages = doc.getDocumentCatalog().getAllPages();
        for (int i = 0; i < pages.size(); i++) {

            float inch = 72;
            PDGamma colourRed = new PDGamma();
            colourRed.setR(1);
            PDGamma colourBlue = new PDGamma();
            colourBlue.setB(1);
            PDGamma white = new PDGamma();
            white.setR(1);
            white.setB(1);
            white.setG(1);

            PDBorderStyleDictionary borderThick = new PDBorderStyleDictionary();
            borderThick.setWidth(inch / 12); // 12th inch
            PDBorderStyleDictionary borderThin = new PDBorderStyleDictionary();
            borderThin.setWidth(inch / 72); // 1 point
            PDBorderStyleDictionary borderULine = new PDBorderStyleDictionary();
            borderULine.setStyle(PDBorderStyleDictionary.STYLE_UNDERLINE);
            borderULine.setWidth(inch / 72); // 1 point

            PDPage page = (PDPage) pages.get(i);
                    PDFont font = PDType1Font.HELVETICA;

            PDPageContentStream contentStream = new PDPageContentStream(
                    doc, page, true, false);
            contentStream.setNonStrokingColor(Color.WHITE);
            contentStream.fillRect(55, 27, 144, 17);
            contentStream.setNonStrokingColor(Color.BLUE);
            contentStream.beginText();
            contentStream.setFont(font, 11);
            contentStream.moveTextPositionByAmount(55, 37);
            contentStream.drawString("www.loasoftwares.com"); //text to be replaced

            contentStream.endText();
            contentStream.setLineWidth(inch / 300);
            contentStream.setStrokingColor(Color.BLUE);
            contentStream.drawLine(55, 34, 188, 34);
            contentStream.close();

            PDAnnotationLink txtLink = new PDAnnotationLink();
            PDRectangle position = new PDRectangle();
            position.setLowerLeftX(55);
            position.setLowerLeftY(27);
            position.setUpperRightX(188);
            position.setUpperRightY(50);
            txtLink.setRectangle(position);

            // add an action
            PDActionURI action = new PDActionURI();
            action.setURI("www.loasoftwares.com");
            txtLink.setBorderStyle(borderULine);
            txtLink.setAction(action);
            txtLink.setColour(white);

            page.getAnnotations().add(txtLink);
        }
        doc.save(outputFile);
    } finally {
        if (doc != null) {
            doc.close();
        }
    }
}
于 2015-02-19T13:01:28.883 回答
0

备注:在特定情况下工作(ASCII'ish 字体编码加上相当长的字符串参数)

/** * 这是一个将 PDF 中的字符串替换为新字符串的示例。* * 示例取自 pdf 文件格式规范。* * @author Ben Litchfield * @version $Revision: 1.3 $ */

    public class ReplaceString
    {
        /**
         * Constructor.
         */
        public ReplaceString()
        {
            super();
        }

        /**
         * Locate a string in a PDF and replace it with a new string.
         *
         * @param inputFile The PDF to open.
         * @param outputFile The PDF to write to.
         * @param strToFind The string to find in the PDF document.
         * @param message The message to write in the file.
         *
         * @throws IOException If there is an error writing the data.
         * @throws COSVisitorException If there is an error writing the PDF.
         */
        public void doIt( String inputFile, String outputFile, String strToFind,  String message)
            throws IOException, COSVisitorException
        {
            // the document
            PDDocument doc = null;
            try
            {
                doc = PDDocument.load( inputFile );
                List pages = doc.getDocumentCatalog().getAllPages();
                for( int i=0; i<pages.size(); i++ )
                {
                    PDPage page = (PDPage)pages.get( i );
                    PDStream contents = page.getContents();
                    PDFStreamParser parser = new PDFStreamParser(contents.getStream());
                    parser.parse();
                    List tokens = parser.getTokens();
                    for( int j=0; j<tokens.size(); j++ )
                    {
                        Object next = tokens.get( j );
                        if( next instanceof PDFOperator )
                        {
                            PDFOperator op = (PDFOperator)next;
                            //Tj and TJ are the two operators that display
                            //strings in a PDF
                            if( op.getOperation().equals( "Tj" ) )
                            {
                                //Tj takes one operator and that is the string
                                //to display so lets update that operator
                                COSString previous = (COSString)tokens.get( j-1 );
                                String string = previous.getString();
                                string = string.replaceFirst( strToFind, message );
                                previous.reset();
                                previous.append( string.getBytes("ISO-8859-1") );
                            }
                            else if( op.getOperation().equals( "TJ" ) )
                            {
                                COSArray previous = (COSArray)tokens.get( j-1 );
                                for( int k=0; k<previous.size(); k++ )
                                {
                                    Object arrElement = previous.getObject( k );
                                    if( arrElement instanceof COSString )
                                    {
                                        COSString cosString = (COSString)arrElement;
                                        String string = cosString.getString();
                                        string = string.replaceFirst( strToFind, message );
                                        cosString.reset();
                                        cosString.append( string.getBytes("ISO-8859-1") );
                                    }
                                }
                            }
                        }
                    }
                    //now that the tokens are updated we will replace the
                    //page content stream.
                    PDStream updatedStream = new PDStream(doc);
                    OutputStream out = updatedStream.createOutputStream();
                    ContentStreamWriter tokenWriter = new ContentStreamWriter(out);
                    tokenWriter.writeTokens( tokens );
                    page.setContents( updatedStream );
                }
                doc.save( outputFile );
            }
            finally
            {
                if( doc != null )
                {
                    doc.close();
                }
            }
        }

        /**
         * This will open a PDF and replace a string if it finds it.
         * <br />
         * see usage() for commandline
         *
         * @param args Command line arguments.
         */
        public static void main(String[] args)
        {
            ReplaceString app = new ReplaceString();
            try
            {
                if( args.length != 4 )
                {
                    app.usage();
                }
                else
                {
                    app.doIt( args[0], args[1], args[2], args[3] );
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        /**
         * This will print out a message telling how to use this example.
         */
        private void usage()
        {
            System.err.println( "usage: " + this.getClass().getName() +
                " <input-file> <output-file> <search-string> <Message>" );
        }
    }
于 2018-10-01T08:01:26.610 回答