2
\$\begingroup\$

This is related to here and here. These two methods are used to programatically add a text field to a PDF document. The field can be of any user determined size and have any user determined title, and will be on the pages specified by an enum value.

private void AddFieldToPdf(Field field,
    iTextSharp.text.pdf.PdfStamper pdfStamper, int numberOfPages)
{
    var parentField = iTextSharp.text.pdf.PdfFormField.CreateTextField(
        pdfStamper.Writer, false, false, 0);
    parentField.FieldName = field.Title;
    switch (field.Pages)
    {
        case Pages.All:
            for (var pageNumber = PdfFirstPageNumber;
                pageNumber <= numberOfPages; pageNumber++)
            {
                AddFieldToPage(field, pageNumber, pdfStamper,
                    parentField);
            }
            break;
        case Pages.Odd:
            for (var pageNumber = PdfFirstPageNumber;
                pageNumber <= numberOfPages; pageNumber+=2)
            {
                AddFieldToPage(field, pageNumber, pdfStamper,
                    parentField);
            }
            break;
        case Pages.Even:
            for (var pageNumber = PdfFirstPageNumber + 1;
                pageNumber <= numberOfPages; pageNumber += 2)
            {
                AddFieldToPage(field, pageNumber, pdfStamper,
                    parentField);
            }
            break;
        case Pages.First:
            AddFieldToPage(field, PdfFirstPageNumber, pdfStamper,
                parentField);
            break;
        case Pages.Last:
            AddFieldToPage(field, numberOfPages, pdfStamper,
                parentField);
            break;
    }
    pdfStamper.AddAnnotation(parentField, 1);
}

private void AddFieldToPage(Field field, int pageNumber,
    iTextSharp.text.pdf.PdfStamper pdfStamper,
    iTextSharp.text.pdf.PdfFormField parentField)
{
    var textField = new iTextSharp.text.pdf.TextField(
        pdfStamper.Writer, new iTextSharp.text.Rectangle(
            field.TopLeftX, field.TopLeftY, field.BottomRightX,
            field.BottomRightY), null);
    var childField = textField.GetTextField();
    parentField.AddKid(childField);
    childField.PlaceInPage = pageNumber;
}
\$\endgroup\$
1

1 Answer 1

1
\$\begingroup\$

The code on your case statements is not that different. You could consider to group all cases that add many fields and those who only add one.

Another thing that is worth mentioning is that unless the option is Pages.Last you always start with PdfFirstPageNumber or that +1.

Let's give a shot to reimplement the method based on this:

private void AddFieldToPdf(Field field,
    iTextSharp.text.pdf.PdfStamper pdfStamper, int numberOfPages)
{
    var parentField = iTextSharp.text.pdf.PdfFormField.CreateTextField(
        pdfStamper.Writer, false, false, 0);
    parentField.FieldName = field.Title;
    int pageNumber = field.Pages == Pages.Last ? numberOfPages : PdfFirstPageNumber;
    switch (field.Pages)
    {
        case Pages.All:
        case Pages.Odd:
        case Pages.Even:
            int increment = field.Pages == Pages.All ? 1 : 2;
            if(field.Pages == Pages.Even){
                pageNumber += 1;
            }
            for (;pageNumber <= numberOfPages; pageNumber += increment)
            {
                AddFieldToPage(field, pageNumber, pdfStamper,
                    parentField);
            }
            break;
        case Pages.First:
        case Pages.Last:
            AddFieldToPage(field, pageNumber, pdfStamper,
                parentField);
            break;
    }
    pdfStamper.AddAnnotation(parentField, 1);
}

EDIT Continuing improvements we can now see that we have two major branches, so maybe an if fits better:

 private void AddFieldToPdf(Field field,
    iTextSharp.text.pdf.PdfStamper pdfStamper, int numberOfPages)
{
    var parentField = iTextSharp.text.pdf.PdfFormField.CreateTextField(
        pdfStamper.Writer, false, false, 0);
    parentField.FieldName = field.Title;
    int pageNumber = field.Pages == Pages.Last ? numberOfPages : PdfFirstPageNumber;

    if(field.Pages == Pages.First || field.Pages  == Pages.Last){
        AddFieldToPage(field, pageNumber, pdfStamper, parentField);
    }else{
        int increment = field.Pages == Pages.All ? 1 : 2;
        if(field.Pages == Pages.Even){
            pageNumber += 1;
        }
        for (;pageNumber <= numberOfPages; pageNumber += increment)
        {
            AddFieldToPage(field, pageNumber, pdfStamper, parentField);
        }
    }
    pdfStamper.AddAnnotation(parentField, 1);
}

There is actually a way to transform that switch statement into a Linq code.

Now I am not saying this code is more clear than yours, that may depend on who is maintaining it. But if you like Linqand would to give it a shot it works as follows:

var query = Enum.Range(PdfFirstPageNumber, numberOfPages);
if(field.Pages == Pages.Odd || field.Pages == Pages.Even){
    int parity = field.Pages == Pages.Odd ? 1 : 0;
    query = query.Where(p => p%2 == parity);
}else if(field.Pages == Pages.First){
    query = query.Take(1);
}else if(field.Pages == Pages.Last){
    query = query.Reverse().Take(1);
}
foreach(var page in query){
    AddFieldToPage(field, page, pdfStamper, parentField);
}
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for your help! I didn't copy your method exactly, but it inspired me to rewrite it so that it is neater. I put my edited version below the original in my question if you'd like to see it. \$\endgroup\$ Jun 1, 2016 at 17:25
  • \$\begingroup\$ @MichaelBrandonMorris it's not bad, see if you like my edit better, I didn't recognise it earlier. \$\endgroup\$ Jun 1, 2016 at 17:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.