【问题标题】:Using iTextSharp with knockout JavaScript or other MVC / MVVM framework?将 iTextSharp 与淘汰 JavaScript 或其他 MVC / MVVM 框架一起使用?
【发布时间】:2016-05-22 10:31:05
【问题描述】:

好的,因为我确实发现我可以使用 iTextSharp 生成 PDF,所以我选择了这条路线。

我已经把它保存到了它将带有基本格式的 HTML 保存为 PDF 的位置。这不是问题。

我现在需要做的是在其中使用 knockout 进行标记,并使用 resultant HTML(即 DOM)作为我的字符串传递到创建 PDF 的方法。

因此,例如,我有一个通过淘汰赛生成的表格。我需要将敲除生成的 DOM 作为字符串传递到我的 C# 控制器中,以便构建 PDF。

基本上,如果您查看此处生成的内容:

http://knockoutjs.com/documentation/foreach-binding.html

如果您通读示例 2(它生成三个要点),它说明了我正在谈论的一代。在我的情况下,我想获取生成的项目符号并将它们作为字符串传递到我的控制器(HTML 和所有内容)中,以便我可以保存它们。

有什么想法吗?老实说,我什至不知道从哪里开始

【问题讨论】:

  • self.addPerson: [1] 获取outerHTML of ul(不知道knockout.js,但是用jQuery很容易); [2] 向控制器发送 Ajax 请求。在控制器中:[1] 使用XMLWorkerHelper 解析 HTML 字符串; [2] 使用 PDF 流返回 ActionResult
  • 谢谢@kuujinbo。我会试一试,让你知道结果如何。这也会捕获任何内联样式吗?
  • 它应该至少捕获其中的一些。但要控制好你的期望。如果您使用Bootstrap 或类似名称,则输出看起来与浏览器中呈现的内容非常不同。 iText[Sharp] 的 CSS 解析器非常简单 - here's a list of supported styles。我将在今天晚些时候抛出一个快速而肮脏的我之前评论的样本作为答案。 :)

标签: c# pdf knockout.js itextsharp


【解决方案1】:

该问题适用于任何执行MVCMVVM 的JavaScript 框架。上面提到的:

我需要将敲除生成的 DOM 作为字符串传递, 到我的 C# 控制器中,这样我就可以构建 PDF。

所以我将使用一个简单的工作示例来在 ASP.NET MVC 中完成这项工作。以前从未使用过knockout.js,所以要获取DOM 元素并使用jQuery 发送Ajax 请求。

视图,基于您上面引用的示例:1. 获取outerHTML of ul2. 向控制器发送Ajax 请求:

<h4>People</h4>
<ul id='wanted' data-bind="foreach: people">
    <li>
        Name at position <span data-bind="text: $index"> </span>:
        <span data-bind="text: name"> </span>
        <a href="#" data-bind="click: $parent.removePerson">Remove</a>
    </li>
</ul>
<button data-bind="click: addPerson">Add</button>
<button data-bind="click: getPdf">Get PDF</button>

@section scripts
{
<script src="~/Scripts/libs/knockout-3.4.0.js"></script>
<script src="~/Scripts/ajax/FileSaver.js"></script>
<script src="~/Scripts/ajax/jquery.binarytransport.js"></script>
<script src="~/Scripts/ajax/jquery-binary.js"></script>
<script type="text/javascript">
    function AppViewModel() {
        var self = this;

        self.getPdf = function (data, event) {
            $(this).downloadFile(
                '@Url.Action("Index", "DomToPdf")',
                { xHtml: $('#wanted').prop('outerHTML') }
            );
        }

        self.people = ko.observableArray([
            { name: 'Bert' },
            { name: 'Charles' },
            { name: 'Denise' }
        ]);
        self.addPerson = function () {
            self.people.push({ name: "New at " + new Date() });
        };
        self.removePerson = function () {
            self.people.remove(this);
        }
    }
    ko.applyBindings(new AppViewModel());
</script>
}

注意事项:

  1. FileSaver.js 在技术上不是必需的,但可以节省大量时间,而不必处理不同的浏览器实现。参考Browser compatibility
  2. BinaryTransport is 如果使用 jQuery 是必需的 - 遗憾的是框架 doesn't support this feature 我上次检查时开箱即用。 AngularJS 等其他框架确实支持二进制。参考Sending and Receiving Binary Data

jquery-binary.js 是一个简单 jQuery 插件我为几个内部项目写的:

(function ($) {
    $.fn.downloadFile = function(url, data, requestType) {
        $.ajax({
            url: url,
            data: data,
            type: requestType || 'POST',
            dataType: 'binary'
        })
        .done(function(data, textStatus, jqXHR) {
            var type = jqXHR.getResponseHeader('Content-Type');
            var filename = jqXHR.getResponseHeader('Content-Disposition');
            filename = filename && filename.indexOf('attachment') > -1
                ? filename.replace(/(?:[^=])+=/, '')
                : 'file.bin';
            var blob = new Blob([data], { type: type });
            saveAs(blob, filename);
        })
        .fail(function(jqXHR, textStatus, errorThrown) {
            alert(errorThrown);
        })
        ;
        return false;
    };
}(jQuery));

和控制器:1.XMLWorkerHelper解析HTML字符串; 2. 返回 PDF。

[HttpPost]  // some browsers have URL length limits
[ValidateInput(false)] // or throws HttpRequestValidationException
public ActionResult Index(string xHtml)
{
    Response.ContentType = "application/pdf";
    Response.AppendHeader(
        "Content-Disposition", "attachment; filename=test.pdf"
    );
    using (var stringReader = new StringReader(xHtml))
    {
        using (Document document = new Document())
        {
            PdfWriter writer = PdfWriter.GetInstance(
                document, Response.OutputStream
            );
            document.Open();
            XMLWorkerHelper.GetInstance().ParseXHtml(
                writer, document, stringReader
            );
        }
    }

    return new EmptyResult();
}

会让你决定如何处理内联样式。 ;)

【讨论】:

  • 很酷的交易。再次感谢@kuujinbo。我会让你知道结果如何。
猜你喜欢
  • 2014-08-26
  • 2011-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-16
  • 2011-10-08
  • 2012-06-13
  • 2023-04-11
相关资源
最近更新 更多