我尝试使用库 PDFBox 编辑文本,但不知道如何。我不知道如何获取单个文本对象的流,所以我可以编辑文本和/或颜色。
任何想法,例如?谢谢
我发现在 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();
}
}
}
备注:在特定情况下工作(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>" );
}
}