2

我正在使用 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 横向宽度”单元格,里面有我的 280 毫米红色边框表格,但宽度通常错误(纵向 A4 文档的最大值)
  • 我尝试在执行 ParseXHtml 之前插入 document.NewPage(),因为我在不同的帖子中发现,由于让文档具有正确的尺寸,因此需要调用“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)
      }
   }
}

正如我在第一个问题中提到的那样,我不知道是否有更简单的方法可以做到这一点。老实说,即使它有效,我也不知道这种解决方法是否好...

4

2 回答 2

0

这对我有用

<style>
table,th,td{
width:100%; //your width here
}
</style>
于 2015-02-19T22:55:08.517 回答
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 结果。

于 2017-05-02T01:22:13.560 回答