iTextSharp xmlworker - 如何从html

时间:2017-10-19 17:06:02

标签: c# html css itext xmlworker

大家都知道StackOverflow的聪明人。

我昨天获得了一项任务,将this扫描图像转换为PDF文档。 由于我没有时间学习iText的所有提示和技巧,我决定使用xmlWorker并创建文档本身的HTML模板。 我很成功,结果是:

Converted PDF file

无论其!

并非一切顺利。如果仔细查看扫描的文档,您可能会注意到文档中间有一个带有虚线边框的表格。这就是我头痛的开始。 我一直在谷歌搜索过去15小时试图找到解决方案,但没有成功。我尝试过各种各样的CSS边界定义,如:

  • border-left-style:虚线;
  • border-style:dashed;
  • border:dashed;

似乎只是忽略了这些CSS定义。

所以我的问题是,有没有一种正确的方法来定义带有虚线边框的HTML表格,以便它可以正确转换为PDF文档?

我正在使用Nuget的最新iTextSharp(v.5.5.12)。

提前谢谢。

修改

好的,所以24小时后,我想我有一个答案。 它是这两个例子的组合:

http://codejaxy.com/q/395523/c-23-html-asp-net-itextsharp-xmlworker-using-itextsharp-xmlworker-to-convert-html-to-pdf-and-write-text-vertically

One cell with different border types

基本上我实现了IPdfPCellEvent接口,所以我可以在PdfCell上使用CellEvent:

public class DottedCell : IPdfPCellEvent
{
    private readonly int _border = 0;

    public DottedCell(int border)
    {
        _border = border;
    }

    public void CellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
    {
        var canvas = canvases[PdfPTable.LINECANVAS];
        canvas.SaveState();
        canvas.SetLineDash(0, 2, 2);

        cell.Border = Rectangle.NO_BORDER;

        if ((_border & Rectangle.TOP_BORDER) == Rectangle.TOP_BORDER)
        {
            canvas.MoveTo(position.GetRight(1), position.GetTop(1));
            canvas.LineTo(position.GetLeft(1), position.GetTop(1));
        }
        if ((_border & Rectangle.BOTTOM_BORDER) == Rectangle.BOTTOM_BORDER)
        {
            canvas.MoveTo(position.GetRight(1), position.GetBottom(1));
            canvas.LineTo(position.GetLeft(1), position.GetBottom(1));
        }
        if ((_border & Rectangle.RIGHT_BORDER) == Rectangle.RIGHT_BORDER)
        {
            canvas.MoveTo(position.GetRight(1), position.GetTop(1));
            canvas.LineTo(position.GetRight(1), position.GetBottom(1));
        }
        if ((_border & Rectangle.LEFT_BORDER) == Rectangle.LEFT_BORDER)
        {
            canvas.MoveTo(position.GetLeft(1), position.GetTop(1));
            canvas.LineTo(position.GetLeft(1), position.GetBottom(1));
        }
        canvas.Stroke();
        canvas.RestoreState();
    }
}

之后我覆盖了iTextSharp.tool.xml.html.table.TableData类:

public class TableDataProcessor : TableData
{
    bool HasBorderStyle(IDictionary<string, string> attributeMap, string borderPosition, string borderStyle)
    {
        var hasStyle = attributeMap.ContainsKey("style");

        if (!hasStyle)
        {
            return false;
        }

        var borderLeft = attributeMap["style"]
            .Split(';')
            .FirstOrDefault(o => o.Trim().StartsWith("border-style-" + borderPosition + ":"));

        if (borderLeft != null)
        {
            return borderLeft.Split(':').Any(o => o.Trim().ToLower() == borderStyle);
        }

        return false;
    }



    public override IList<IElement> End(IWorkerContext ctx, Tag tag, IList<IElement> currentContent)
    {
        var cells = base.End(ctx, tag, currentContent);

        var attributeMap = tag.Attributes;
        if (HasBorderStyle(attributeMap, "left", "dotted"))
        {
            var pdfPCell = (PdfPCell) cells[0];
            pdfPCell.CellEvent = null;
            pdfPCell.CellEvent = new DottedCell(Rectangle.LEFT_BORDER);
        }

        return cells;
    }
}

最后一步是将该类添加到标记处理器以获取TD元素:

var tagProcessorFactory = Tags.GetHtmlTagProcessorFactory();
tagProcessorFactory.AddProcessor(
     new TableDataProcessor(),
     new[] {HTML.Tag.TD}
);

htmlContext.SetTagFactory(tagProcessorFactory);

它有效: enter image description here

HTML标记:

<table class="content-wrapper">
    <tbody>
        <tr>
            <td class="pcnt_60 content-left top" valign="top">
                <table>
                  <tr>
                    <td style='border-left: 0.5px; border-style-left: dotted;'>content goes here</td>
                  </tr>
                </table>
            </td>
        </tr>
    </tbody>
</table>

0 个答案:

没有答案