将html表数据移植到可读文档的最简单方法

时间:2011-09-12 07:26:03

标签: asp.net-mvc pdf ms-word reporting

确定,

在过去的6个月里,我一直在努力构建一个允许用户以大性感textareas形式输入的系统(支持表格,列表等)。几乎可以让用户输入数据,就好像它是单词一样。但是,当想要导出所有这些数据时,我找不到工作解决方案......

我的第一步是尝试找到一个报告软件,它确实支持来自数据源的原始HTML并将其呈现为普通的html,完美地工作,除了保持在一起的功能很糟糕,数据被分成两半(表格,列表等)我不想要的。或者报告总是跳到下一页以避免这种情况,最终文档中有15个以上的空页。

所以我正在寻找某种方法/方向,以便将我的数据导出到可读文档(pdf或word pref)中。

我得到的是以下数据细分,其中数据通常是原始html。

-period

- 单元

---组

----问题

- - - - 数据

最佳选择是什么?试图将html渲染为pdf或rtf?我需要提示:(

有时,数据长度为2-3页,混合表格列表和纯文本。

4 个答案:

答案 0 :(得分:2)

我建议你尝试将其保留在浏览器中,然后在HTML中添加print stylesheet,使其在屏幕上以一种方式呈现another way on paper。在HTML中添加打印样式表就像这样简单:

<link rel="stylesheet" media="print" href="print.css">

您应该能够使用Html Agility Pack之类的内容解析输入并将其转换(即使用XSLT)到您想要的任何输出格式。

另一个选择是将HTML写入浏览器,但将Content-Type设置为Microsoft Word特定的变体(有几个可供选择,具体取决于您要定位的Word的版本)应该使浏览器询问用户是否要使用Microsoft Word打开页面。使用Word 2007及更新版本,您还可以直接编写Office Open XML Word,因为它是基于XML的。

您可以使用的内容类型是:

application/msword

对于二进制Microsoft Word文件,但也应该适用于HTML。

application/vnd.openxmlformats-officedocument.wordprocessingml.document

对于较新的“Office Open XML”格式的Word 2007及更新版本。

答案 1 :(得分:2)

您可以使用的解决方案是使用System.Diagnostics.Process在服务器上运行应用程序,该应用程序将转换网站并将其另存为PDF文档。

您可以使用wkhtmltopdf这是一个可以从HTML转换为PDF或图像的开源控制台程序。

Windows的安装程序可以从wkhtmltox-0.10.0_rc2 Windows Installer (i368)获得。

安装wkhtmltopdf后,您可以复制解决方案内安装文件夹中的文件。您可以在解决方案中使用这样的设置:

转换后的pdf将保存到pdf文件夹中。

以下是进行转换的代码:

var wkhtmltopdfLocation = Server.MapPath("~/wkhtmltopdf/") + "wkhtmltopdf.exe";
var htmlUrl = @"http://stackoverflow.com/q/7384558/750216";
var pdfSaveLocation = "\"" + Server.MapPath("~/wkhtmltopdf/pdf/") + "question.pdf\"";

var process = new Process();
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.FileName = wkhtmltopdfLocation;
process.StartInfo.Arguments = htmlUrl + " " + pdfSaveLocation;
process.Start();
process.WaitForExit();

htmlUrl是您需要转换为pdf的页面的位置。它被设置为此stackoverflow页面。 :)

答案 2 :(得分:1)

这是一个普遍的问题,但有两件事让人联想到访客模式和改变Mime类型。

访客模式 您可以使用两种单独的渲染技术。这取决于您的实施。

MIME类型 当请求在响应等

中写入日期时
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.Charset = "utf-16";
HttpContext.Current.Response.ContentEncoding = System.Text.Encoding.GetEncoding("windows-1250");
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename={0}.doc", filename));
HttpContext.Current.Response.ContentType = "application/msword";
HttpContext.Current.Response.Write("-Period");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("--Unit");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("---Group");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("----Question");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.Write("-----Data");
HttpContext.Current.Response.Write("/n");
HttpContext.Current.Response.End();

答案 3 :(得分:1)

这是另一个选项,使用打印屏幕(虽然它不会照顾滚动,但我认为你应该能够构建它)。这个例子可以扩展,以满足您的业务需求,虽然它是一种黑客。你传递一个它生成图像的URL。

像这样打电话

 protected void Page_Load(object sender, EventArgs e)
            {
                int screenWidth = Convert.ToInt32(Request["ScreenWidth"]);
                int screenHeight = Convert.ToInt32(Request["ScreenHeight"]);
                string url =        Request["Url"].ToString();
                string bitmapName = Request["BitmapName"].ToString();


            WebURLToImage webUrlToImage = new WebURLToImage()
            {
                Url = url,
                BrowserHeight = screenHeight,
                BrowserWidth = screenWidth,
                ImageHeight = 0,
                ImageWidth = 0
            };

        webUrlToImage.GenerateBitmapForUrl();
        webUrlToImage.GeneratedImage.Save(Server.MapPath("~") + @"Images\" +bitmapName + ".bmp");
    }

从网页生成图片。

using System;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.IO;

public class WebURLToImage
{
    public string Url { get; set; }
    public Bitmap GeneratedImage { get; private set; }
    public int ImageWidth { get; set; }
    public int ImageHeight { get; set; }
    public int BrowserWidth { get; set; }
    public int BrowserHeight { get; set; }

    public Bitmap GenerateBitmapForUrl()
    {
        ThreadStart threadStart = new ThreadStart(ImageGenerator);
        Thread thread = new Thread(threadStart);

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
        thread.Join();
        return GeneratedImage;
    }

    private void ImageGenerator()
    {
        WebBrowser webBrowser = new WebBrowser();
        webBrowser.ScrollBarsEnabled = false;
        webBrowser.Navigate(Url);

        webBrowser.DocumentCompleted += new
WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);

        while (webBrowser.ReadyState != WebBrowserReadyState.Complete)
            Application.DoEvents();
        webBrowser.Dispose();
    }

    void webBrowser_DocumentCompleted(object sender,
WebBrowserDocumentCompletedEventArgs e)
    {
        WebBrowser webBrowser = (WebBrowser)sender;
        webBrowser.ClientSize = new Size(BrowserWidth, this.BrowserHeight);
        webBrowser.ScrollBarsEnabled = false;
        GeneratedImage = new Bitmap(webBrowser.Bounds.Width, webBrowser.Bounds.Height);
        webBrowser.BringToFront();

        webBrowser.DrawToBitmap(GeneratedImage, webBrowser.Bounds);

        if (ImageHeight != 0 && ImageWidth != 0)
            GeneratedImage =
(Bitmap)GeneratedImage.GetThumbnailImage(ImageWidth, ImageHeight,
null, IntPtr.Zero);
    }
}