【问题标题】:cell background image with text itextsharp带有文本 itextsharp 的单元格背景图像
【发布时间】:2015-07-01 18:45:32
【问题描述】:

提前谢谢,我知道你很忙..所以我根据你给我的代码编辑了这个...... 首先我想让你看看我在尝试你的代码时得到了什么..

我用作背景的图片是:

如你所见,我遇到了几个问题:

1- 图像不是单元格的背景,我希望它被拉伸。

2- 我试图将文本放在不同的位置,但失败了。

3 - 我还有一个未显示的丢失单元格。

我使用的代码是:

1- ImageEvent 类:

 class ImageEvent : IPdfPCellEvent
{
protected Image img;
public ImageEvent(Image img) {
    this.img = img;
}
 void IPdfPCellEvent.CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
{
    img.ScaleToFit(position.Width, position.Height);

    img.SetAbsolutePosition(position.Left + (position.Width - img.Width) / 2,
            position.Bottom + (position.Height - img.ScaledHeight / 2));
    PdfContentByte canvas = canvases[PdfPTable.BACKGROUNDCANVAS];
    try {
        canvas.AddImage(img);
    } catch (DocumentException ex) {
        // do nothing
    }
}

}

2- 职位类别:

 class PositionEvent : IPdfPCellEvent
{
    protected Phrase content;
    protected string pos;

    public PositionEvent(Phrase content, string pos)
    {
        this.content = content;
        this.pos = pos;
    }

     void IPdfPCellEvent.CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
    {
        PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS];
        float x = 0;
        float y = 0;
        int alignment = 0;
        switch (pos)
        {
            case "TOP_LEFT":
                x = position.GetLeft(3);
                y = position.GetTop(content.Leading);
                alignment = Element.ALIGN_LEFT;
                break;
            case "TOP_RIGHT":
                x = position.GetRight(3);
                y = position.GetTop(content.Leading);
                alignment = Element.ALIGN_RIGHT;
                break;
            case "BOTTOM_LEFT":
                x = position.GetLeft(3);
                y = position.GetBottom(3);
                alignment = Element.ALIGN_LEFT;
                break;
            case "BOTTOM_RIGHT":
                x = position.GetRight(3);
                y = position.GetBottom(3);
                alignment = Element.ALIGN_RIGHT;
                break;
            case "CENTER_TOP":
                x = position.GetRight(3) + position.GetLeft(3) / 2; 
                y = position.GetTop(3);
                alignment = Element.ALIGN_RIGHT;
                break;
            case "CENTER_BOTTOM":
                x = position.GetRight(3) + position.GetLeft(3) / 2;
                y = position.GetBottom(3);
                alignment = Element.ALIGN_RIGHT;
                break;
            case "CENTER_MIDDLE":
                x = position.GetRight(3) + position.GetLeft(3) / 2;
                y = x;
                alignment = Element.ALIGN_RIGHT;
                break;
        }
        ColumnText.ShowTextAligned(canvas, alignment, content, x, y, 0);
    }
}

3- 方法:

  public void createPdf(string dest)
    {
        // 1. Create a Document which contains a table:
        Document document = new Document();
        PdfWriter.GetInstance(document, new FileStream(dest, FileMode.Create));

        document.Open();
        PdfPTable table = new PdfPTable(3);
        table.WidthPercentage = 100f;
        PdfPCell cell1 = new PdfPCell();
        PdfPCell cell2 = new PdfPCell();
        PdfPCell cell3 = new PdfPCell();
        PdfPCell cell4 = new PdfPCell();
        PdfPCell cell5 = new PdfPCell();
        PdfPCell cell6 = new PdfPCell();
        PdfPCell cell7 = new PdfPCell();
        // 2. Inside that table, make each cell with specific height:
        cell1.FixedHeight=50;
        cell2.FixedHeight = 50;
        cell3.FixedHeight = 50;
        cell4.FixedHeight = 50;
        cell5.FixedHeight = 50;
        cell6.FixedHeight = 50;
        cell7.FixedHeight = 50;
        // 3. Each cell has the same background image
        string path = string.Concat(this.openFileDialog_pic.FileName);
        string imageFilePath = string.Concat(Environment.GetEnvironmentVariable("."), path);
        iTextSharp.text.Image IMG = iTextSharp.text.Image.GetInstance(imageFilePath);

        ImageEvent imgEvent = new ImageEvent(iTextSharp.text.Image.GetInstance(IMG));
        cell1.CellEvent=imgEvent;
        cell2.CellEvent = imgEvent;
        cell3.CellEvent = imgEvent;
        cell4.CellEvent = imgEvent;
        cell5.CellEvent = imgEvent;
        cell6.CellEvent = imgEvent;
        cell7.CellEvent = imgEvent;
        // 4. Add text in front of the image at specific position
        cell1.CellEvent= new PositionEvent(new Phrase("Top left"), "TOP_LEFT");
        cell2.CellEvent=new PositionEvent(new Phrase("Top right"), "TOP_RIGHT");
        cell3.CellEvent=new PositionEvent(new Phrase("Bottom left"), "BOTTOM_LEFT");
        cell4.CellEvent=new PositionEvent(new Phrase("Bottom right"), "BOTTOM_RIGHT");
        cell5.CellEvent = new PositionEvent(new Phrase("Center Top"), "CENTER_TOP");
        cell6.CellEvent = new PositionEvent(new Phrase("Center Bottom"), "CENTER_BOTTOM");
        cell7.CellEvent = new PositionEvent(new Phrase("Center Middle"), "CENTER_MIDDLE");
        // Wrap it all up!
        table.AddCell(cell1);
        table.AddCell(cell2);
        table.AddCell(cell3);
        table.AddCell(cell4);
        table.AddCell(cell5);
        table.AddCell(cell6);
        table.AddCell(cell7);
        document.Add(table);
        document.Close();
    }

【问题讨论】:

  • 问题的标题具有误导性。我看到你使用了一个名为CellBackgroundEventPdfPCellEvent。我假设您正在将图像添加为此类中的背景。您没有共享该代码,因此我认为这是可行的。你分享了@98​​7654328@ 方法,似乎创建了一个嵌套表,但你没有告诉我们它有什么问题。
  • 问题是我无法控制从 'GetCard()' 方法获得的文本的位置 .. 所以我尝试了填充,如您所见 .. 我将文本放在顶部或单元格的中间..但填充不准确
  • 那仍然不准确。除了您之外,没有人知道您的期望。如果您要求其他人帮助您,请理解我们无法调查您的想法。阐明。做一张图。解释!
  • 感谢您的回复...抱歉误导...所以我会尽量简化...忘记我写的所有编码...1 - 我想创建一个包含一个表格的文档.. 在该表格内,单元格.... 2- 我想让每个单元格具有特定的高度 3- 每个单元格都具有相同的背景图像。 4-我想在单元格内我想要的位置在图像前面放置一个文本。例如:单元格的左上角,单元格的右下角..etc ........我做了 1,2 和 3 .. 但我做不到 4 ..
  • 我希望我上次的评论很清楚......请我需要帮助@BrunoLowagie

标签: c# file pdf itextsharp cell


【解决方案1】:

在附加评论中,您阐明了您的要求:

  1. 我想创建一个包含一个表格的文档。在该表内,单元格
  2. 我想让每个单元格都有特定的高度
  3. 每个单元格都有相同的背景图片
  4. 我想在图像前面的单元格内我想要的位置放置一个文本。例如:单元格的左上角,单元格的右下角

换句话说:你想要这样的东西:position_content_in_cell.pdf

有不止一种方法可以做到这一点。我不明白您在问题中使用的代码示例。它使用嵌套表,我不明白您为什么需要嵌套表。

PositionContentInCell 示例中,我使用了一种方法,可以让您真正微调文本的确切位置。我创建了一个ImageEvent 来缩放和居中图像:

class ImageEvent implements PdfPCellEvent {
    protected Image img;
    public ImageEvent(Image img) {
        this.img = img;
    }
    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        img.scaleToFit(position.getWidth(), position.getHeight());
        img.setAbsolutePosition(position.getLeft() + (position.getWidth() - img.getScaledWidth()) / 2,
                position.getBottom() + (position.getHeight() - img.getScaledHeight()) / 2);
        PdfContentByte canvas = canvases[PdfPTable.BACKGROUNDCANVAS];
        try {
            canvas.addImage(img);
        } catch (DocumentException ex) {
            // do nothing
        }
    }
}

我创建了一个PositionEvent 在单元格内添加文本:

class PositionEvent implements PdfPCellEvent {
    protected Phrase content;
    protected POSITION pos;

    public PositionEvent(Phrase content, POSITION pos) {
        this.content = content;
        this.pos = pos;
    }

    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS];
        float x = 0;
        float y = 0;
        int alignment = 0;
        switch (pos) {
            case TOP_LEFT:
                x = position.getLeft(3);
                y = position.getTop(content.getLeading());
                alignment = Element.ALIGN_LEFT;
                break;
            case TOP_RIGHT:
                x = position.getRight(3);
                y = position.getTop(content.getLeading());
                alignment = Element.ALIGN_RIGHT;
                break;
            case BOTTOM_LEFT:
                x = position.getLeft(3);
                y = position.getBottom(3);
                alignment = Element.ALIGN_LEFT;
                break;
            case BOTTOM_RIGHT:
                x = position.getRight(3);
                y = position.getBottom(3);
                alignment = Element.ALIGN_RIGHT;
                break;
        }
        ColumnText.showTextAligned(canvas, alignment, content, x, y, 0);
    }
}

这就是我使用这些事件的方式:

public void createPdf(String dest) throws IOException, DocumentException {
    // 1. Create a Document which contains a table:
    Document document = new Document();
    PdfWriter.getInstance(document, new FileOutputStream(dest));
    document.open();
    PdfPTable table = new PdfPTable(2);
    PdfPCell cell1 = new PdfPCell();
    PdfPCell cell2 = new PdfPCell();
    PdfPCell cell3 = new PdfPCell();
    PdfPCell cell4 = new PdfPCell();
    // 2. Inside that table, make each cell with specific height:
    cell1.setFixedHeight(50);
    cell2.setFixedHeight(50);
    cell3.setFixedHeight(50);
    cell4.setFixedHeight(50);
    // 3. Each cell has the same background image
    ImageEvent imgEvent = new ImageEvent(Image.getInstance(IMG));
    cell1.setCellEvent(imgEvent);
    cell2.setCellEvent(imgEvent);
    cell3.setCellEvent(imgEvent);
    cell4.setCellEvent(imgEvent);
    // 4. Add text in front of the image at specific position
    cell1.setCellEvent(new PositionEvent(new Phrase("Top left"), POSITION.TOP_LEFT));
    cell2.setCellEvent(new PositionEvent(new Phrase("Top right"), POSITION.TOP_RIGHT));
    cell3.setCellEvent(new PositionEvent(new Phrase("Bottom left"), POSITION.BOTTOM_LEFT));
    cell4.setCellEvent(new PositionEvent(new Phrase("Bottom right"), POSITION.BOTTOM_RIGHT));
    // Wrap it all up!
    table.addCell(cell1);
    table.addCell(cell2);
    table.addCell(cell3);
    table.addCell(cell4);
    document.add(table);
    document.close();
}

通常,我会以更有效的方式编写此代码,但我对代码行进行排序,以便它们从字面上反映您的要求 1、2、3 和 4。

更新:

在 cmets 中,您提出了几个额外的问题。例如:如何拉伸图像:

你能够回答大部分这些问题,例如根据我使用ScaleAbsolute的提示:

public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
    img.scaleAbsolute(position.getWidth(), position.getHeight());
    img.setAbsolutePosition(position.getLeft(), position.getBottom());
    PdfContentByte canvas = canvases[PdfPTable.BACKGROUNDCANVAS];
    try {
        canvas.addImage(img);
    } catch (DocumentException ex) {
        // do nothing
    }
}

您还有一个问题需要额外的示例(很难在评论框中解释)。我将该示例命名为PositionContentInCell2

您没有使用POSITION 枚举,而是询问是否可以传递xy 值。您可以这样做,但您可能并不总是知道单元格的宽度和高度,所以为什么不定义诸如wPcthPct 之类的百分比以及对齐方式:

class PositionEvent implements PdfPCellEvent {
    protected Phrase content;
    protected float wPct;
    protected float hPct;
    protected int alignment;

    public PositionEvent(Phrase content, float wPct, float hPct, int alignment) {
        this.content = content;
        this.wPct = wPct;
        this.hPct = hPct;
        this.alignment = alignment;
    }

    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        PdfContentByte canvas = canvases[PdfPTable.TEXTCANVAS];
        float x = position.getLeft() + wPct * position.getWidth();
        float y = position.getBottom() + hPct * (position.getHeight() - content.getLeading());
        ColumnText.showTextAligned(canvas, alignment, content, x, y, 0);
    }
}

现在您可以像这样添加这些事件:

cell1.setCellEvent(new PositionEvent(new Phrase(14, "Top left"), 0, 1, Element.ALIGN_LEFT));
cell2.setCellEvent(new PositionEvent(new Phrase(14, "Top right"), 1, 1, Element.ALIGN_RIGHT));
cell3.setCellEvent(new PositionEvent(new Phrase(14, "Top center"), 0.5f, 1, Element.ALIGN_CENTER));
cell4.setCellEvent(new PositionEvent(new Phrase(14, "Bottom center"), 0.5f, 0, Element.ALIGN_CENTER));
cell5.setCellEvent(new PositionEvent(new Phrase(14, "Middle center"), 0.5f, 0.5f, Element.ALIGN_CENTER));
cell6.setCellEvent(new PositionEvent(new Phrase(14, "Middle center"), 0.5f, 0.5f, Element.ALIGN_CENTER));
cell7.setCellEvent(new PositionEvent(new Phrase(14, "Bottom left"), 0, 0, Element.ALIGN_LEFT));
cell8.setCellEvent(new PositionEvent(new Phrase(14, "Bottom right"), 1, 0, Element.ALIGN_RIGHT));

当然,如果您更喜欢传递 xy(毕竟:您确实知道高度,因为您定义了一个固定高度,所以代码可以变得更简单:您不要多个变量position.getWidthposition.getHeight()

【讨论】:

  • 非常感谢 .. 这正是我想要的 .. 再次抱歉让您对我的要求感到困惑
  • 一次这些问题太多了。将它们分成不同的问题。
  • 您希望我将此作为新问题发布?? ..对不起,我没明白你的意思
  • @lasheul 我认为那将是最好的。例如:你现在使用ScaleToFit,但你真正想要的是ScaleAbsolute。我不可能知道这一点,因为你的问题不清楚。如果您使用ScaleAbsolute,将图像定位为单元格的背景会更容易。您可以只使用img.setAbsolutePosition(position.getLeft(), position.getBottom());,因为图像将具有与单元格完全相同的尺寸,因此无需将其居中。您的附加问题中没有什么是用常识无法解决的。
  • 所以最后一个问题.. 是否可以将定位转换为更灵活的方式.. 例如,而不是使用 switch case 和“左下角”之类的短语.. 我可以使用数字吗? ,比如 (x=0 ,y=0) 表示左上角,如果我使用 (x=width ,y=height) 它将是右下角,中间中心表示 (x=width/2,y=height/2 ) .. 等
猜你喜欢
  • 2011-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多