如何使用iTextSharp XMLWorkerHelper.GetInstance()在横向文档上设置全表宽度。在C#ASP.NET MVC中使用ParseXHtml?

时间:2014-03-11 09:09:42

标签: itextsharp landscape xmlworker

我正在使用ASP.NET MVC,我正在使用iTextSharp将HTML页面呈现为PDF,详细介绍了iTextSharp XMLWorkerHelper工具。 它适用于我必须解析的所有页面,并且当它们具有纵向方向时呈现为PDF,但当它们具有横向时会失败。

以下是我想要在横向渲染的HTML的一个非常简单的示例:

<table style="border:1px solid red; width:280mm;">
    <tr>
        <td>
            In this cell there is a content that can be very large...
        </td>
    </tr>
</table>

请注意,桌面宽度应为280毫米(略小于横向模式下的整个A4宽度)。

这是HTML到PDF转换的核心:

public override void ExecuteResult(ControllerContext context)
{
    IView viewEngineResult;
    ViewContext viewContext;

    if (string.IsNullOrEmpty(ViewName))
        ViewName = context.RouteData.GetRequiredString("action");

    context.Controller.ViewData.Model = Model;

    var workStream = new MemoryStream();
    var sb = new StringBuilder();
    Document document = new Document(new Rectangle(842f, 595f));
    document.SetPageSize(PageSize.A4.Rotate());

    TextWriter tr = new StringWriter(sb);
    viewEngineResult = ViewEngines.Engines.FindView(context, ViewName, null).View;
    viewContext = new ViewContext(context, viewEngineResult,       context.Controller.ViewData,
    context.Controller.TempData, tr);
    viewEngineResult.Render(viewContext, tr);

    Stream stream = new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString()));
    PdfWriter pdfWriter = PdfWriter.GetInstance(document, workStream);
    pdfWriter.CloseStream = false; 

    document.Open();    
    XMLWorkerHelper.GetInstance().ParseXHtml(pdfWriter, document, stream, (Stream)null);
    document.Close();

    new FileContentResult(workStream.ToArray(), "application/pdf").ExecuteResult(context);
}

结果是横向文档,表格带有红色边框,但宽度错误。很容易理解,渲染宽度,在PDF上, 不是280mm,而是表格可能在纵向A4文档上的最大宽度

我尝试了不同的方法:

  • 我创建了一个PdfPTable,设置宽度为100%。然后我在表格中创建了一个PdfPCell。最后我把ParseXHtml结果放在那个单元格中。结果是一个完整的“A4横向宽度”单元格,里面有我的280mm红色边框表,但通常有错误的宽度(纵向A4文档的最大值)
  • 我之前尝试插入document.NewPage()来执行ParseXHtml,因为我在不同的帖子上发现需要“NewPage”调用,因为让文档具有正确的尺寸......但是这个操作也没有好的结果

也许我试图按照错误的方式,有一种非常简单和愚蠢的方法来解决这个问题?

提前感谢您的建议。

修订版

我尝试用解决方法解决这个问题。 在document.Open()document.Close()方法之间我替换了: XMLWorkerHelper.GetInstance().ParseXHtml(pdfWriter, document, stream, (Stream)null);

使用以下内容:

var handler = new SampleHandler();
using (TextReader sr = new StringReader(sb.ToString()))
{
   //Parse
   XMLWorkerHelper.GetInstance().ParseXHtml(handler , sr);
}
foreach (var element in handler.elements)
{
   document.Add(element);
}

我创建了一个新类:

public class SampleHandler : IElementHandler
{
   public List<IElement> elements = new List<IElement>();

   public void Add(IWritable w)
   {
      if (w is WritableElement)
      {
         // Here all the logic useful to catch the PDFPTable and redefine
         // its width or other tricks (such as nested tables redefining)
      }
   }
}

正如我在第一期中提到的那样,我不知道是否有更简单的方法可以做到这一点。说实话,前夕如果它有效,我不知道这个解决方法是否合适......

2 个答案:

答案 0 :(得分:0)

这对我有用

<style>
table,th,td{
width:100%; //your width here
}
</style>

答案 1 :(得分:0)

您是否使用您在UPDATE中建议的代码获得了功能性解决方案?

我有同样的问题,我做了一些测试,发现sb.ToString()的结果是一个Html,它包含了使用横向全宽正确表格形成的所有必要标签。

public string RenderRazorView(ControllerContext context, string viewName)
    {
        IView viewEngineResult = ViewEngines.Engines.FindView(context, viewName, null).View;
        var sb = new StringBuilder();


        using (TextWriter tr = new StringWriter(sb))
        {
            var viewContext = new ViewContext(context, viewEngineResult, context.Controller.ViewData,
                context.Controller.TempData, tr);
            viewEngineResult.Render(viewContext, tr);
        }
        return sb.ToString();
    }

所以我理解所有不需要的更改都发生在XMLWorkerHelper.GetInstance()中。 ParseXHtml 因此,您的代码旨在进行已经进行的更改,并且不会更改Parser结果。