C# 从HTML代码生成PDF文件的 免费解决方案

       最近在开发一个项目中需要从HTML代码生成PDF文件,为此我在网上搜了好几天,解决方案的一个个否决,最终自己摸索出了一个免费的解决方案。

       jiangsq12345 口米巴  原创,转载请标明出处http://blog.csdn.net/jiangsq12345/article/details/7615974,谢谢!

准备工作

  • 安装Office2007以上版本
  • 安装2007 Microsoft Office 加载项:Microsoft Save as PDF 或 XPS,下载地址


该方案的思路是很简单,分为两步 (调用的是Office Word2007控件)

  1. 先将HTML代码保存为html文件
  2. 打开html文件,并另存为PDF文件即可

首先是库的导入


以下将主要的源代码跟大家分享一下,希望对面临该难题的同胞有些帮助

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.IO;
using Microsoft.Office.Interop.Word;

namespace 文件收发系统
{
    public  class PDFFactory
    {
        private  String dateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").Replace(":","");
        private  HttpServerUtility server = null;
        private  String path_pdf = null;
        private  String path_html = null;
        private  String html_content = null;
        private  String pdf_name = null;
        private  String path_word = null;

        Microsoft.Office.Interop.Word.Application myWordApp = 
            new Microsoft.Office.Interop.Word.ApplicationClass(); 
     
        /// <summary>
        /// 将HTML代码转化为PDF格式文件保存
        /// </summary>
        /// <param name="server"> Server </param>
        /// <param name="content"> HTML代码 </param>
        /// <param name="name"> pdf文件名称</param>
        public PDFFactory (HttpServerUtility s, String content, String name)
        {
            server = s;
            pdf_name = name;
            path_pdf = server.MapPath(SiteConf.PATH_PDFS + "\\" + pdf_name + ".pdf");
            path_html = server.MapPath(SiteConf.PATH_TMP_HTML + "\\" + dateTime + ".html");
            html_content = content;          
 
            //检查并创建系统文件夹
            CreateDirectory(SiteConf.PATH_PDFS);
            CreateDirectory(SiteConf.PATH_TMP_HTML);
            CreateDirectory(SiteConf.PATH_TMP_WORD);
        }


        public PDFFactory(HttpServerUtility s, String word_name)
        {
            server = s;           
            path_word = server.MapPath(SiteConf.PATH_TMP_WORD + "\\" + word_name + ".doc");
            path_pdf = server.MapPath(SiteConf.PATH_PDFS + "\\" + word_name + ".pdf");

            //检查并创建系统文件夹
            CreateDirectory(SiteConf.PATH_PDFS);
            CreateDirectory(SiteConf.PATH_TMP_HTML);
            CreateDirectory(SiteConf.PATH_TMP_WORD);
        }

        /// <summary>
        /// 开始转换
        /// </summary>
        /// <param name="type"> 被转换的原文件类型:html/word </param>
        /// <param name="type"> 如果是word类型,则要指定路径 </param>
        public void Start(SiteConf.DOCTYPE type, String word_path)
        {
            switch (type)
            {
                case SiteConf.DOCTYPE.HTML:                   
                    CreateHtml((String)path_html,html_content);
                    Convert2PDF(path_html);
                    break;
                case SiteConf.DOCTYPE.WORD:                    
                    ConvertWord2PDF(path_word,path_pdf);
                    break;
                default:
                    if (SiteConf.DEBUG)
                        Console.Write("【注意】文件类型错误!");
                    break;
            }
        }
              
        /// <summary>
        /// 将HTML代码保存到html文件    
        /// </summary>
        /// <param name="fileName">要保存的html文件路径</param>
        /// <param name="content"> 要写入html文件的内容串 </param>
        public void CreateHtml(String fileName, String content)
        {            
            //读html模板页面到stringbuilder对象里
            //string[] format = new string[4];//定义和htmlyem标记数目一致的数组
            try
            {
                StringBuilder htmltext = new StringBuilder();           
                htmltext.Append(html_content);                   
                using (StreamWriter sw =
                    new StreamWriter(fileName, false, System.Text.Encoding.GetEncoding("GB2312"))) //保存地址
                {
                    sw.WriteLine(htmltext);
                    sw.Flush();
                    sw.Close();
                }

                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
            catch (Exception excep)
            {
                if (SiteConf.DEBUG)
                    Console.Write(excep.Message);
            }
        }

        /// <summary>
        /// 将Html文件内容转化成word保存(去HMTL标签)
        /// </summary>
        private void ConvertHtml2Word(object fileName)
        {
            try
            {
                object nothing = System.Reflection.Missing.Value;
                object missing = System.Type.Missing;
              
                Object ConfirmConversions = false;
                Object ReadOnly = true;
                Object AddToRecentFiles = false;

                Object PasswordDocument = missing;
                Object PasswordTemplate = missing;
                Object Revert = missing;
                Object WritePasswordDocument = missing;
                Object WritePasswordTemplate = missing;
                Object Format = missing;//
                Object Encoding = missing;
                Object Visible = missing;
                Object OpenAndRepair = missing;
                Object DocumentDirection = missing;
                Object NoEncodingDialog = missing;
                Object XMLTransform = missing;

                object FileFormat = Microsoft.Office.Interop.Word.WdSaveFormat.wdFormatDocument;
                object SaveNativePictureFormat = false;
                object LineEnding = Microsoft.Office.Interop.Word.WdLineEndingType.wdCRLF;//Word.WdLineEndingType.wdLSPS;

                Microsoft.Office.Interop.Word.ApplicationClass oWordApp = new ApplicationClass();
                Microsoft.Office.Interop.Word.Document oWordDoc = oWordApp.Documents.Add(ref nothing, ref nothing, ref nothing, ref nothing);

                oWordDoc = oWordApp.Documents.Open(ref fileName, ref ConfirmConversions,
                    ref ReadOnly, ref AddToRecentFiles, ref PasswordDocument, ref PasswordTemplate,
                    ref Revert, ref WritePasswordDocument, ref WritePasswordTemplate, ref Format,
                    ref Encoding, ref Visible, ref OpenAndRepair, ref DocumentDirection,
                    ref NoEncodingDialog, ref XMLTransform);
              
                //将WordDoc文档对象的内容保存为doc文档
                oWordDoc.SaveAs(ref fileName, ref FileFormat, ref nothing, ref nothing, ref AddToRecentFiles, ref nothing, ref nothing, ref nothing, ref SaveNativePictureFormat, ref nothing, ref nothing, ref nothing, ref nothing, ref nothing, ref LineEnding, ref nothing);
                //关闭WordDoc文档对象
                oWordDoc.Close(ref nothing, ref nothing, ref nothing);
                //关闭WordApp组件对象
                oWordApp.Quit(ref nothing, ref nothing, ref nothing);
            }
            catch (Exception excep)
            {
                if (SiteConf.DEBUG)
                    Console.Write(excep.Message);
            }

        }
     
        /// <summary>  
        /// 转换html为pdf  
        /// </summary>  
        /// <param name="fileName"> 被读取文件的路径及名称 </param>
        private void Convert2PDF(object fileName)
        {
            ApplicationClass wordApplication = new ApplicationClass();
            wordApplication.Visible = false;
            Document wordDocument = null;
            object paramMissing = Type.Missing;

            WdExportFormat paramExportFormat = WdExportFormat.wdExportFormatPDF;
            bool paramOpenAfterExport = false;
            WdExportOptimizeFor paramExportOptimizeFor =
                WdExportOptimizeFor.wdExportOptimizeForPrint;
            WdExportRange paramExportRange = WdExportRange.wdExportAllDocument;
            int paramStartPage = 0;
            int paramEndPage = 0;
            WdExportItem paramExportItem = WdExportItem.wdExportDocumentContent;
            bool paramIncludeDocProps = true;
            bool paramKeepIRM = true;
            WdExportCreateBookmarks paramCreateBookmarks =
                WdExportCreateBookmarks.wdExportCreateWordBookmarks;
            bool paramDocStructureTags = true;
            bool paramBitmapMissingFonts = true;
            bool paramUseISO19005_1 = false;

            try
            {
                // Open the source document.
                wordDocument = wordApplication.Documents.Open(
                    ref fileName, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing);

                // Export it in the specified format.
                if (wordDocument != null)
                    wordDocument.ExportAsFixedFormat(path_pdf,
                        paramExportFormat, paramOpenAfterExport,
                        paramExportOptimizeFor, paramExportRange, paramStartPage,
                        paramEndPage, paramExportItem, paramIncludeDocProps,
                        paramKeepIRM, paramCreateBookmarks, paramDocStructureTags,
                        paramBitmapMissingFonts, paramUseISO19005_1,
                        ref paramMissing);
            }
            catch (Exception excep)
            {
                if (SiteConf.DEBUG)
                    Console.Write(excep.Message);
            }
            finally
            {
                // Close and release the Document object.
                if (wordDocument != null)
                {
                    wordDocument.Close(ref paramMissing, ref paramMissing,
                        ref paramMissing);
                    wordDocument = null;
                }

                // Quit Word and release the ApplicationClass object.
                if (wordApplication != null)
                {
                    wordApplication.Quit(ref paramMissing, ref paramMissing,
                        ref paramMissing);
                    wordApplication = null;
                }

                if(!SiteConf.DEBUG)
                //    DeleteFile((String)fileName);

                GC.Collect();
                GC.WaitForPendingFinalizers();
               
            }
        }

        /// <summary>  
        /// 转换word为pdf  
        /// </summary>  
        /// <param name="word_filename">doc文件路径</param>  
        /// <param name="pdf_filename">pdf保存路径</param>  
        private void ConvertWord2PDF(object word_filename, object pdf_filename)
        {
            ApplicationClass wordApplication = new ApplicationClass();
            wordApplication.Visible = false;
            Document wordDocument = null;            
            object paramMissing = Type.Missing;
            WdExportFormat paramExportFormat = WdExportFormat.wdExportFormatPDF;
            bool paramOpenAfterExport = false;
            WdExportOptimizeFor paramExportOptimizeFor =
                WdExportOptimizeFor.wdExportOptimizeForPrint;
            WdExportRange paramExportRange = WdExportRange.wdExportAllDocument;
            int paramStartPage = 0;
            int paramEndPage = 0;
            WdExportItem paramExportItem = WdExportItem.wdExportDocumentContent;
            bool paramIncludeDocProps = true;
            bool paramKeepIRM = true;
            WdExportCreateBookmarks paramCreateBookmarks =
                WdExportCreateBookmarks.wdExportCreateWordBookmarks;
            bool paramDocStructureTags = true;
            bool paramBitmapMissingFonts = true;
            bool paramUseISO19005_1 = false;

            try
            {
                // Open the source document.

                wordDocument = wordApplication.Documents.Open(
                    ref word_filename, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing, ref paramMissing, ref paramMissing,
                    ref paramMissing);

                // Export it in the specified format.
                if (wordDocument != null)
                    wordDocument.ExportAsFixedFormat((String)pdf_filename,
                        paramExportFormat, paramOpenAfterExport,
                        paramExportOptimizeFor, paramExportRange, paramStartPage,
                        paramEndPage, paramExportItem, paramIncludeDocProps,
                        paramKeepIRM, paramCreateBookmarks, paramDocStructureTags,
                        paramBitmapMissingFonts, paramUseISO19005_1,
                        ref paramMissing);
            }
            catch (Exception excep)
            {
                if (SiteConf.DEBUG)
                    Console.Write(excep.Message);
            }
            finally
            {
                // Close and release the Document object.
                if (wordDocument != null)
                {
                    wordDocument.Close(ref paramMissing, ref paramMissing,
                        ref paramMissing);
                    wordDocument = null;
                }

                // Quit Word and release the ApplicationClass object.
                if (wordApplication != null)
                {
                    wordApplication.Quit(ref paramMissing, ref paramMissing,
                        ref paramMissing);
                    wordApplication = null;
                }

                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }
        }


        /// <summary>
        ///  删除指定文件
        /// </summary>
        /// <param name="fileName"> 指定文件物理路径及名称 </param>
        private void DeleteFile(String fileName)
        {           
            if (File.Exists(server.MapPath((String)fileName)))
                File.Delete(server.MapPath((String)fileName)); 
            else
                if (SiteConf.DEBUG)
                    Console.Write("文件【"+fileName+"】不存在");
        }

        /// <summary>
        /// 检查并创建指定文件夹
        /// </summary>
        /// <param name="path"> 文件夹虚拟路径 </param>
        private void CreateDirectory(String path)
        {
            if (!Directory.Exists(server.MapPath(path)))
            {
                Directory.CreateDirectory(server.MapPath(path));
            }
        }
    }
}

该解决方案最大的优点是: 免费且支持任何语言
缺点是:服务器端每次PDF文件的创建都需要调用word控件(特别是对文件的读写操作),所以耗费的系统资源比较多,因此对大型网站并不适合。还是乖乖花个几千块去买个支持中文的吧。


欢迎拍砖、指教


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值