使用PDFsharp定位数据

时间:2016-11-15 17:39:40

标签: c# pdfsharp

我正在使用PDFsharp为我的模型中的每个项目生成多个页面文档。

我已经对最终PDF需要的内容进行了粗略的模拟:

enter image description here

简而言之,我必须制作两种不同类型的PDF,我需要遵循模板的是多页PDF,因此下面的代码片段中的变量为_numberOfPages。< / p>

我实际上为多页PDF版本的每个单独项目生成信息。根据请求中的项目数量,我添加一个新页面,然后获取当前页面的items items数组的索引,并附加这样的行。

PdfDocument Class

    public PdfDocument BuildPdfDocument()
    {
       if (_numberOfPages > 1)
       {
          PdfDocument pdfDocument = new PdfDocument();
          for (int i = 0; i < _numberOfPages; i++)
             {
               PdfPage page = pdfDocument.AddPage();
               page.Orientation = PageOrientation.Landscape;
               XGraphics gfx = XGraphics.FromPdfPage(page);
               XFont font = new XFont("Arial", 30, XFontStyle.Regular);
               XTextFormatter tf = new XTextFormatter(gfx);
               XRect rect = new XRect(0, (page.Height / 4), page.Width, page.Height);
               gfx.DrawRectangle(XBrushes.White, rect);
               tf.Alignment = XParagraphAlignment.Left;
               tf.DrawString(_request.GetText(i), font, XBrushes.Black, rect);
             }

                return pdfDocument;
        }

        else
         {
           // stuff relating to the other pdfDocument that is OK
         }
  }

FileRequest类包含一个名为GetText的方法

public string GetText(int pageNo)
{
    int[] fileRequestItems = this.FileRequestItems.Select(x => x.Id).ToArray();
    var currentFileRequestItem = fileRequestItems[pageNo];
    var items = FileRequestItems;

    FileRequestItem item = items.FirstOrDefault(s => s.Id == currentFileRequestItem);

    StringBuilder sb = new StringBuilder();

    if (item.ObjectContextGetType() == typeof(FileRequestDocument)) // its a document so provide text for the PDF like this 
    {
        var fileRequestDocument = item as FileRequestDocument;

        sb.AppendLine("Date Requested: " + this.DateOfRequest.ToString("D"));
        if (fileRequestDocument != null) sb.AppendLine("Box No: " + fileRequestDocument.Record.Box.BoxNumber);
        sb.AppendLine("Location: " + this.Location.LocationName);
        if (fileRequestDocument != null) sb.AppendLine("Description: " + fileRequestDocument.Record.Description);
        sb.AppendLine("Requested By: " + this.Name);
        sb.AppendLine("Tel: " + this.TelephoneNumber);
        sb.AppendLine("Department: " + this.Department);
    }

    if (item.ObjectContextGetType() == typeof(FileRequestBox)) // its a box so provide text for the PDF like this
    {
        var fileRequestBox = item as FileRequestBox;

        sb.AppendLine("Date Requested: " + this.DateOfRequest.ToString("D"));
        if (fileRequestBox != null) sb.AppendLine("Box No: " + fileRequestBox.Box.BoxNumber);
        sb.AppendLine("Location: " + this.Location.LocationName);
        if (fileRequestBox != null) sb.AppendLine("Description: " + $"Entire Contents of Box Number {fileRequestBox.Box.BoxNumber}");
        sb.AppendLine("Requested By: " + this.Name);
        sb.AppendLine("Tel: " + this.TelephoneNumber);
        sb.AppendLine("Department: " + this.Department);
    }

    return sb.ToString();
}

所有这些的结果是以下PDF,包含5个项目的文件请求将超过5页,重复名称/日期等内容,但该FileRequestItem或页面的描述是唯一的。< / p>

enter image description here

如您所见,尽管信息全部存在,但定位与所需模板不匹配。

如何为每个页面创建指定的模板或类似内容,然后相应地定位我的数据?

2 个答案:

答案 0 :(得分:1)

很好尝试将长多行字符串传递给XTextFormatter。如果你需要控制位置,那就错误了。

要完全控制定位,请为各个项目调用DrawString

我会使用MigraDoc:MigraDoc允许您创建一个表并将信息放在单个表格单元格中。

MigraDoc使用PDFsharp创建PDF文件,但提供更高的API级别 http://www.pdfsharp.net/wiki/Invoice-sample.ashx

答案 1 :(得分:-1)

这是一个古老的问题,但是尝试提供一种不同的方法,您可以尝试在HTML表字符串中构建布局,并在单独的文件中创建其CSS样式,然后执行以下操作:

string stylesUrl = Server.MapPath("pathToPdfStyle");
CssData css = PdfGenerator.ParseStyleSheet(File.ReadAllText(stylesUrl));
PdfDocument pdfTemp = PdfGenerator.GeneratePdf({HTMLString}, PageSize.A4, 20, css);

当您在浏览器中查看html文档和pdf阅读器中的html内容时,视大小和格式而定,会有很小的视觉差异,但是它们非常相似。