ITextSharp 4.1.6 - Remove existing line from PDF Template

不羁的心 提交于 2019-11-29 16:30:51

Removing individual drawing objects can get a little tricky but its not impossible. The hardest part is deciding which objects that you want to remove. Below is some sample code targetting iTextSharp 4.1.6 that first creates a PDF with two rectangles and then creates a second PDF based on the first with one of the rectangles removed. You'll need to apply your logic to figure out which rectangle you want to remove. Its possible that you don't actually have rectangles but lines that happen to form a rectangle, in that case you'll need to modify the code a bit, too.

This first bit just creates a basic PDF on the desktop with two rectangles:

//Create a file on the desktop with two rectangles
var file1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File1.pdf");
using (var fs = new FileStream(file1, FileMode.Create, FileAccess.Write, FileShare.None)) {
    var doc = new Document();
    var writer = PdfWriter.GetInstance(doc, fs);
    doc.Open();

    var cb = writer.DirectContent;

    //Draw two rectangles
    cb.SaveState();
    cb.SetColorStroke(iTextSharp.text.Color.RED);
    cb.Rectangle(40, 60, 200, 100);
    cb.Stroke();
    cb.RestoreState();

    cb.SaveState();
    cb.SetColorStroke(iTextSharp.text.Color.BLUE);
    cb.Rectangle(500, 80, 90, 50);
    cb.Stroke();
    cb.RestoreState();

    doc.Close();
}

This next part is the more complicated part. I encourage you to do a Console.WriteLine(tokenizer.StringValue); inside of the while loop to see all of the PDF commands. You'll notice that they use RPN syntax which can take a little getting used. See the comments in the code for more questions.

//Bind a reader to our first file
var reader = new PdfReader(file1);
//Get the first page (this would normally be done in a loop)
var page = reader.GetPageN(1);
//Get the "contents" of that page
var objectReference = (PdfIndirectReference)page.Get(PdfName.CONTENTS);
//Get the actual stream of the "contents"
var stream = (PRStream)PdfReader.GetPdfObject(objectReference);
//Get the raw bytes of the stream
var streamBytes = PdfReader.GetStreamBytes(stream);
//Convert the bytes to actual PDF tokens/commands
var tokenizer = new PRTokeniser(new RandomAccessFileOrArray(streamBytes));
//We're going to re-append each token to this below buffer and remove the ones that we don't want
List<string> newBuf = new List<string>();
//Loop through each PDf token
while (tokenizer.NextToken()) {
    //Add them to our master buffer
    newBuf.Add(tokenizer.StringValue);
    //The "Other" token is used for most commands, so if we're on "Other" and the current command is "re" which is rectangle
    if (
        tokenizer.TokenType == PRTokeniser.TK_OTHER && //The "Other" token is used for most commands
        newBuf[newBuf.Count - 1] == "re" &&            //re is the rectangle command
        newBuf[newBuf.Count - 5] == "40"               //PDFs use RPN syntax so the red rectangle command was "40 60 200 100 re"
        ) {
        newBuf.RemoveRange(newBuf.Count - 5, 5);       //If the above conditions were met remove the last 5 commands
    }
}

//Convert our array to a string with newlines between each token, convert that to an ASCII byte array and push that back into the stream (erasing the current contents)
stream.SetData(System.Text.Encoding.ASCII.GetBytes(String.Join("\n", newBuf.ToArray())));

//Create a new file with the rectangle removed
var file2 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "File2.pdf");
using (var fs = new FileStream(file2, FileMode.Create, FileAccess.Write, FileShare.None)) {
    //Bind a stamper to our read above which has the altered stream
    var stamper = new PdfStamper(reader, fs);
    //Loop through each page
    int total = reader.NumberOfPages;
    for (int i = 1; i <= total; i++) {
        //Push the content over page by page
        reader.SetPageContent(i, reader.GetPageContent(i));
    }
    stamper.Close();
}
reader.Close();
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!