s yu Ответов: 2

Как вставить прямоугольник iTextsharp.text.rectangle в абсолютное положение?


Используя приведенный ниже код (также размещенный по адресу http://stackoverflow.com/questions/38568690/how-to-insert-a-itextsharp-text-rectangle-rectangle-at-an-absolute-position),
iTextSharp.text.Rectangle rectangle = new Rectangle(10, 10, 150, 15, 0);  
   // (lower-left-x, lower-left-y, upper-right-x (llx + width), upper-right-y (lly + height), rotation angle 
rectangle.BorderColor = BaseColor.WHITE;
rectangle.BackgroundColor = BaseColor.LIGHT_GRAY;
overContent.Rectangle(rectangle);
PdfAnnotation annotation = PdfAnnotation.CreateLink(
   stamper.Writer, rectangle, PdfAnnotation.HIGHLIGHT_INVERT,
   new PdfAction("http://itextpdf.com/") );            
stamper.AddAnnotation(annotation, 1);

Я могу создать гиперссылку в сгенерированном PDF-файле. Однако прямоугольник гиперссылки всегда находится в левом нижнем углу сгенерированного PDF-файла, независимо от того, как я изменяю значения x &Y в аргументах прямоугольника (int x, int y, int width, int height). Объект аннотации не имеет метода для установки его абсолютного положения. Если у вас есть опыт использования iTextSharp и, в частности, есть знания по созданию гиперссылки в формате PDF, не могли бы вы поделиться своими знаниями? Спасибо.
// ********
Это обновление моего вопроса
Я попробовал еще один фрагмент кода, как показано ниже:
using (System.IO.FileStream fs = new FileStream(Server.MapPath("pdf") + "\\" + "PDF with graphics and images.pdf", FileMode.Create)) {
   Document document = new Document(PageSize.A4, 25, 25, 30, 30);
   PdfWriter writer = PdfWriter.GetInstance(document, fs);
   Font link = FontFactory.GetFont("Arial", 12, Font.UNDERLINE, BaseColor.BLACK);  
   iTextSharp.text.Anchor anchor = new Anchor("www.mikesdotnetting.com", link);
   anchor.Reference = "http://www.mikesdotnetting.com";
   document.Add(anchor);

Эта гиперссылка также добавляется, но ее положение находится в левом верхнем углу страницы. ITextSharp.text.Якорь делает бот есть способ функцию setabsoluteposition. Есть ли способ установить якорь в нужное положение? Спасибо.

Что я уже пробовал:

Как вставить прямоугольник iTextSharp.text.Rectangle в абсолютное положение?

2 Ответов

Рейтинг:
2

JIYAUL MUSTAPHA

PdfContentByte cb = pdfwrite.DirectContent;
              var Rectangular = new Rectangle(56, 621, 540,385);
              Rectangular.BorderWidthLeft = 0.1f;
              Rectangular.BorderWidthRight = 0.1f;
              Rectangular.BorderWidthTop = 0.1f;
              Rectangular.BorderWidthBottom = 0.1f;
              cb.Rectangle(Rectangular);
              cb.Stroke();


CHill60

Посмотрите на принятое решение. Плакат приложил много усилий для объяснения кода и общения с ОП. ОП подтвердила, что решение работало как в письменной форме, так и официально приняв ответ год назад. Что заставляет вас думать, что они оценят незафиксированный дамп кода без контекста?
Это хорошо, что вы хотите помочь, но, пожалуйста, попробуйте привнести что-то новое в темы и объяснить, почему ваше решение лучше, чем любые другие опубликованные

Рейтинг:
17

Garth J Lancaster

У меня нет опыта работы с аннотациями, но часто мне нужно разместить что - то абсолютно на странице, и я использую "поддельную" таблицу. Если вы можете добавить свою аннотацию в "ячейку", а я думаю, что можете, попробуйте сделать это

PdfContentByte cb = writer.DirectContent;
PdfPTable table = new PdfPTable(1);
table.TotalWidth = 400f;
table.AddCell(//Annotation Details Here);
table.WriteSelectedRows(0, -1, 200, 50, cb);


Вы можете установить границы стола на все, что пожелаете, я делаю их невидимыми


Итак, это "основа" моего процесса :-

PdfContentByte cb;

// Create PDF Reader For Input PDF
PdfReader reader = new PdfReader(//Source PDF File Name);

// Create Output PDF 
using (System.IO.FileStream fs = new System.IO.FileStream(//Target PDF Output File Name, System.IO.FileMode.Create))
{
    // Create PDF Stamper
    PdfStamper pdfStamper = new (PdfStamper, fs);

    // Get The Content Bytes For Page 1 
    cb = pdfStamper.GetOverContent(1);

    // Not Sure If this is needed 
    cb.BeginText();

    // Create a table and set a width

    PdfPTable table = new PdfPTable(1);
    table.TotalWidth = 400f;
    
    // Option 1 or Option 2 Here - I usually use 'builder' procedures for Tables/Paragraphs/Cells

    // Write the table at an absolute position 
    table.WriteSelectedRows(0, -1, 200, 50, cb);

    // If We've needed to use BeginText() We need this 
    cb.EndText();

    pdfStamper.FormFlattening = true;
    // Close Stamper
    pdfStamper.Close();
}


Тогда любой из этих двух вариантов


// Option 1 - Using Paragraph + Chunk Allows For Alignment 

// Create Chunk with anchor
var webAddress = new Chunk("CodeProject");
// Set The anchor
webAddress.SetAnchor("http://www.codeproject.com");
// Crate a paragraph to hold the chunk
var para = new Paragraph(webAddress);
// Add some alignment to the paragraph
para.Alignment = Element.ALIGN_CENTER;
// Create a cell
PdfPCell anchorCell = new PdfPCell();
// Add the paragraph to the cell
anchorCell.AddElement(para);
// Can set padding on cell :-)
anchorCell.Padding = 30f;
// Set the cell border off 
anchorCell.Border = Rectangle.NO_BORDER;
// Add the cell to the table
table.AddCell(anchorCell);
//


или

// Option 2 - Use Chunk, less formatting control 

// Create Chunk with anchor
var webAddress = new Chunk("CodeProject");
// Set The anchor
webAddress.SetAnchor("http://www.codeproject.com");
// Create a cell
PdfPCell anchorCell = new PdfPCell();
// Add the webAddress (chunk) to the cell
anchorCell.AddElement(webAddress);
// Set the cell border off 
anchorCell.Border = Rectangle.NO_BORDER;
// Add the cell to the table
table.AddCell(anchorCell);
//


Вам нужно будет установить

//Имя исходного PDF-файла
//Целевое имя выходного файла PDF

К значениям для PDF - файла in (я использую его как "подложку") и PDF - файла out

кстати - это набрано из рукописных заметок, я нахожусь на своем mac и в данный момент не могу добраться до своей машины dev, так что, возможно, потребуется немного отредактировать здесь и там

Вы можете скопировать вариант 1 или 2 здесь (или сделать статическую процедуру и передать в cb / ContentBytes

Цитата:
// Вариант 1 или Вариант 2 здесь - я обычно использую процедуры "строителя" для таблиц/абзацев/ячеек


. как говорится, у меня обычно есть набор "строителей", которые позволяют мне собирать шрифты, абзацы из кусков, таблицы из ячеек и т. д


Полный рабочий пример (создание PDF-файла с нуля)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using iTextSharp.text;
using iTextSharp.text.pdf;

namespace CPPDF001
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseFont bfTimesRoman = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);

            Font fTimesRomanItalic10 = new Font(bfTimesRoman, 10, Font.ITALIC, BaseColor.BLACK);

            String testPDFName = "CPPFF001.pdf";
            if (File.Exists(testPDFName))
            {
                File.Delete(testPDFName);
            }

            using (FileStream fs = new FileStream("CPPFF001.pdf", FileMode.Create))
            {
                Document doc = new Document(PageSize.A4, 25,25,30,30);
                PdfWriter writer = PdfWriter.GetInstance(doc, fs);

                doc.Open();
                PdfContentByte cb = writer.DirectContent;

                cb.BeginText();

                writeText(cb, "Garth Was Here !!!", 30, 718, bfTimesRoman, 14);

                // Note the implications of this wrt chunks in Try 1 and Try 2
                cb.SetFontAndSize(bfTimesRoman, 10);

                PdfPTable table = new PdfPTable(1);
                table.TotalWidth = 400f;

                // Try 1 : This works - NB Will Have a Rectangle Around it
                // Note that because we're using a chunk, its font/size is
                // dependand upon the statement :-
                //
                // cb.SetFontAndSize(bfTimesRoman, 10);
                //
                
                var chunk = new Chunk("CodeProject");
                chunk.SetAnchor("http://www.codeproject.com");
                chunk.SetUnderline(0.5f, -1.5f);

                PdfPCell cell = new PdfPCell();
                cell.AddElement(chunk);
                table.AddCell(cell);
                table.WriteSelectedRows(0, -1, 30, 646, cb);
                // Try 1 End


                // Try 2 : This also works - NB Will not have a Border/Rectangle Around it
                // Note that because we're using a chunk, its font/size is
                // dependand upon the statement :-
                //
                // cb.SetFontAndSize(bfTimesRoman, 10);
                //

                PdfPTable table1 = new PdfPTable(1);
                table1.TotalWidth = 100f;

                PdfPCell cell1 = new PdfPCell();
                cell1.AddElement(chunk);
                cell1.Border = Rectangle.NO_BORDER;

                table1.AddCell(cell1);
                table1.WriteSelectedRows(0, -1, 30, 574, cb);
                // Try 2 End

                // Try 3 : This also works 
                //   NB Will not have a Border/Rectangle Around it
                //      Will Be In Italic, No Underline

                PdfPTable table2 = new PdfPTable(1);
                table2.TotalWidth = 100f;

                PdfPCell cell2 = new PdfPCell();

                // Note the chunk formatting here :-)
                var chunk1 = new Chunk("CodeProject", fTimesRomanItalic10);
                chunk1.SetAnchor("http://www.codeproject.com");

                //var paragraph = new Paragraph(chunk1); 
                cell2.AddElement(chunk1);
                cell2.Border = Rectangle.NO_BORDER;

                table2.AddCell(cell2);
                table2.WriteSelectedRows(0, -1, 30, 502, cb);
                // Try 3 End

                cb.EndText();
                doc.Close();

            } // using

        } // Main

        static void writeText(PdfContentByte cb, string text, int x, int y, BaseFont font, int size)
        {
            cb.SetFontAndSize(font, size);
            cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, text, x, y, 0);
        }

        // Obviously you'd re-factor Try1-3 Into Code that looked like
        /*
           static Chunk CreateChunk(string text,
                                    string link,
                                    Font font,
                                    int fontSize)
           {
               // Create and return Chunk
           }

           static PDFPCell CreateCell(Chunk chunk,
                                    bool borderOrNot)
           {
               // Create and return Cell, using chunk
           }

           static Table CreateTable(PDFPcell cell,
                                    int rectangleSize)
           {
               // Create and return Table
           }

           static void AddAnnotation(PdfContentByte cb,
                                     string text,
                                     string link, 
                                     Font font,
                                     int fontSize,
                                     int positionX,
                                     int positionY,
                                     bool borderOrNot,
                                     int rectangleSize)
           {
                // Build Chunk using text, link, font, fontSize
                // Build Cell, Add Chunk To Cell And Turn Border Off if borderOrNot == true
                // Build Table, set width to rectangleSize
                // Write Table to cb, positionX, positionY
          
           }
        */

        }
    }
}


Полный рабочий пример (аннотирование существующего PDF-файла)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

using iTextSharp.text;
using iTextSharp.text.pdf;

namespace CPPDF001
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseFont bfTimesRoman = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);

            Font fTimesRomanItalic10 = new Font(bfTimesRoman, 10, Font.ITALIC, BaseColor.BLACK);

            //
            // ** Part 1 - Create a PDF to Stamp/Annotate **
            //

            String testPDFName = "CPPDF001.pdf";
            if (File.Exists(testPDFName))
            {
                File.Delete(testPDFName);
            }

            // Create a simple PDF to use for Underlay
            using (FileStream fs = new FileStream(testPDFName, FileMode.Create))
            {
                Document doc = new Document(PageSize.A4, 


s yu

Пробовал, но получил ошибку компиляции на
стол.AddCell(аннотация);
где annotaion-это PdfAnnotation. Какой-нибудь новый намек? Спасибо.

Garth J Lancaster

Какой-нибудь новый намек ? немного трудно, не видя вашего кода и деталей ошибки компиляции - не могу читать ваши мысли и не вижу вашего экрана отсюда

s yu

Гарт: Спасибо за ваш комментарий. Я обновил свою Q w/ 2-ю часть, которая содержит новый фрагмент кода. Не могли бы вы просмотреть его и посмотреть, сможете ли вы дать свой совет? Спасибо.

Garth J Lancaster

Я не знаю политики привязки по умолчанию ... поэтому я сомневаюсь, что это сработает - процесс, который я использую, немного (нет, намного больше) вовлечен в то, что у меня есть профессионально созданный PDF-документ, и я "штампую" информацию над ним и создаю новый pdf-файл .. Я опубликую код сегодня вечером, я не знаю, будет ли он работать для вас таким образом, он определенно позволяет мне размещать таблицы с цифрами и/или графикой везде, где я хочу, плюс я также размещаю текст

Garth J Lancaster

хорошо, взгляните на то, что я предоставил - я надеюсь, что это какое-то использование, оно, вероятно, очень отличается от того, что вам нужно, и я набрал его из заметок (я не могу использовать свой код prod для другой компании, извините)

s yu

Гарт: большое спасибо за ваш код. Я попробовал оба варианта, но сгенерированный целевой PDF-файл не может быть открыт. Сообщение об ошибке Adobe Reader гласит: "произошла ошибка при открытии этого документа. Этот файл поврежден и не может быть восстановлен. " не могли бы вы предоставить дополнительную консультацию? Спасибо.

Garth J Lancaster

это мог быть PDFStamnper/GetOverContent или позиционирование таблицы - теперь я опубликовал полный рабочий пример - опробованный и проверенный

s yu

Замечательно!!! Большое вам спасибо!

s yu

Г-н Гарт: ваш код работает как поиск для создания гиперссылок. Однако у меня возникла еще одна проблема: все содержимое исходного PDF-файла исчезло.
Моя цель - написать что - то на существующем шаблоне PDF. Ниже приведена часть моего кода:
PdfReader reader1 = новый PdfReader(startFile);
используя (файлового потока ФС = новый хранилище FileStream(markedFile, содержит filemode.Создать, FileAccess.Пиши, Файлообменник.)) {
using (PdfStamper stamper = new PdfStamper(reader1, fs)) {
...
PdfContentByte КБ = Стэмпер.GetUnderContent(i);
...
}
}
В то время как в вашем:
PdfContentByte cb = writer.DirectContent;
Не могли бы вы дать свой совет, как остановить гиперссылку на существующий PDF-файл? Спасибо.

Garth J Lancaster

посмотрите на "полный рабочий пример (аннотирование существующего PDF)" - я разделил свою оригинальную программу на две части: Часть 1 = создать PDF, часть 2 = аннотировать ее с помощью stamper. Я тоже переключился на Стэмпера.GetOverContent() - поскольку я не знаю, какие слои использует ваш PDF - файл/как он собран, я могу только предложить вам попробовать один или другой-но мой работает

s yu

Превосходно!!! Я протестировал ваш код и слился с моим приложением. Это хорошо работает. Большое спасибо!!!