8

如何从 Web 应用程序生成纸质打印件?

具体来说,我正在考虑更复杂的纸质文件,如文凭、发票和合同。带有框架、表格、徽标和页眉/页脚的可变页数。

今天我对某些事情使用自定义表单和 CSS,而对其他事情使用 iTextSharp(我使用 asp.net 和 MS-SQL),但我认为这两种方法都非常耗时,并且很难在不同的文档中保持一致。

有没有更好的方法来解决它?

4

4 回答 4

3

恕我直言,如果答案是固定格式打印 PDF

于 2009-01-12T09:44:04.680 回答
3

使用 iTextSharp 从头开始​​创建文档可能非常耗时。作为替代方案,您可以通过向它们添加表单域(如果需要)来创建(或重复使用)PDF“模板”文档。最简单的方法是使用完整版的 Adob​​e Acrobat,但您也可以只使用 iTextSharp 添加可填写的表单字段。

例如,对于奖励或文凭,您可以查找、创建或修改包含文档的所有文本、图形、精美边框和字体的 PDF,然后为收件人姓名添加表单域。您可以为日期、签名行、奖励类型等添加其他字段。

然后可以很容易地从您的 Web 应用程序中使用 iTextSharp 来填写表单、将其展平并将其流式传输回给用户。

这篇文章的最后是一个完整的 ASHX 处理程序代码示例。

还要记住,iTextSharp(或只是 iText)对于合并 PDF 文档或来自不同文档的页面也很有用。所以,对于封面或说明页设计固定但内容动态生成的年报,您可以打开封面页,打开报表的模板页面,将动态内容生成到模板的空白区域,打开背页“样板”,然后将它们全部组合成一个文档返回给用户。

using System;
using System.Data;
using System.Web;
using System.Collections;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Text;
using iTextSharp;
using iTextSharp.text;
using iTextSharp.text.pdf;

namespace iTextFormFillerDemo
{
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class DemoForm : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {

            context.Response.ContentType = "application/pdf";
            //This line will force the user to either open or save the 
            //file instead of it appearing on its own page - if you remove it, 
            //the page will appear in the browser in the same window.
            context.Response.AddHeader("Content-Disposition", 
                "attachment; filename=DemoForm_Filled.pdf");

            FillForm(context.Response.OutputStream);

            context.Response.End();
        }

        // Fills the form and pushes it out the output stream.
        private void FillForm(System.IO.Stream outputStream)
        {
            //Need to get the proper directory (dynamic path) for this file. 
            //This is a filesystem reference, not a web/URL reference...
            //The PDF reader reads in the fillable form
            PdfReader reader = new PdfReader("C:/DemoForm_Fillable.pdf");

            //The PDF stamper creates an editable working copy of the form from the reader 
            //and associates it with the response output stream
            PdfStamper stamper = new PdfStamper(reader, outputStream);

            //The PDF has a single "form" consisting of AcroFields
            //Note that this is shorthand for writing out 
            //stamper.AcroFields.SetField(...) for each set
            AcroFields form = stamper.AcroFields;

            //Set each of the text fields this way: SetField(name, value)
            form.SetField("txtFieldName", "Field Value");
            form.SetField("txtAnotherFieldName", "AnotherField Value");

            //Set the radio button fields using the names and string values:
            form.SetField("rbRadioButtons", "Yes"); //or "No"

            //Form flattening makes the form non-editable and saveable with the 
            //form data filled in
            stamper.FormFlattening = true;

            //Closing the stamper flushes it out the output stream
            stamper.Close();

            //We're done reading the file
            reader.Close();
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
于 2009-01-22T01:05:55.833 回答
2

尽管您已经声明您已经尝试过基于 CSS 的方法,但最好的方法是查看 @print 媒体类型 ( http://www.w3.org/TR/CSS2/media.html ) . 基本上允许您使用与屏幕或任何其他(许多)媒体类型不同的样式表进行打印。

然后,如果你想自动启动一个打印事件,你想使用这样的东西(JavaScript):

window.print();

当然,您必须检查浏览器实际上是否支持通过 JavaScript 进行打印,并采取相应措施:

function doPrint() {
    if(!window.print())
    {
        alert("Your browser does not support direct printing, please select 'Print' from the 'File' menu.");
    }
}

但是,如果您坚持 CSS 不能满足您的需求,那么您可能需要转向基于 PDF 的解决方案。不过,我没有“通过”PDF 制作网络打印输出的经验。

于 2009-01-12T09:50:00.597 回答
1

如果您使用的是 SQL Server,则可以使用报告服务创建报告。然后用户可以直接打印或将其导出为多种不同的格式(您可以控制哪些格式可供用户使用)。

我过去使用过这种方法,我发现它可以让我在打印或导出文档时更好地控制文档的外观。

于 2009-01-12T10:41:56.983 回答