当前位置:首页 » 《随便一记》 » 正文

C# 实现网页内容保存为图片并生成压缩包

12 人参与  2024年02月26日 18:26  分类 : 《随便一记》  评论

点击全文阅读


目录

应用场景

实现代码

扩展功能(生成压缩包)

小结 


应用场景

我们在一个求职简历打印的项目功能里,需要根据一定的查询条件,得到结果并批量导出指定格式的文件。导出的格式可能有多种,比如WORD格式、EXCEL格式、PDF格式等,实现方式是通过设置对应的模板进行输出,实际情况是,简历的内容是灵活设置的,没有固定的格式,模板数量是不固定的。

通过动态页面技术,可以实现简历配置后的网页内容输出,但制作对应的各种模板会遇到开发效率和服务跟进的问题。为了保障原样输出,折中而简单的方案就是将动态输出的页面转化为图片格式。

实现代码

创建一个 UrlToImage 类,创建实例的时候传递指定的 URL, 并调用 SaveToImageFile(string outputFilename)方法,该方法传递要输出的文件名参数即可即可。

调用示例代码如下:

string url = "https://" + Request.Url.Host + "/printResume.aspx";UrlToImage uti = new UrlToImage(url);bool irv = uti.SaveToImageFile(Request.PhysicalApplicationPath + "\\test.jpg");if(bool==false){    Response.Write("save failed.");    Response.End();}

类及实现代码如下:

    public class UrlToImage    {        private  Bitmap m_Bitmap;        private string m_Url;        private string m_FileName = string.Empty;        int initheight = 0;        public UrlToImage(string url)        {            // Without file            m_Url = url;        }        public UrlToImage(string url, string fileName)        {            // With file            m_Url = url;            m_FileName = fileName;        }        public Bitmap Generate()        {            // Thread            var m_thread = new Thread(_Generate);            m_thread.SetApartmentState(ApartmentState.STA);            m_thread.Start();            m_thread.Join();            return m_Bitmap;        }        public bool SaveToImageFile(string filename)        {            Bitmap bt=Generate();            if (bt == null)            {                return false;            }            bt.Save(filename);            return File.Exists(filename);        }        private void _Generate()        {            var browser = new WebBrowser { ScrollBarsEnabled = false };            browser.ScriptErrorsSuppressed = true;            initheight = 0;            browser.Navigate(m_Url);            browser.DocumentCompleted += WebBrowser_DocumentCompleted;            while (browser.ReadyState != WebBrowserReadyState.Complete)            {                Application.DoEvents();            }            browser.Dispose();        }        private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)        {            // Capture            var browser = (WebBrowser)sender;            browser.ClientSize = new Size(browser.Document.Body.ScrollRectangle.Width, browser.Document.Body.ScrollRectangle.Bottom);            browser.ScrollBarsEnabled = false;            m_Bitmap = new Bitmap(browser.Document.Body.ScrollRectangle.Width, browser.Document.Body.ScrollRectangle.Bottom);            browser.BringToFront();            browser.DrawToBitmap(m_Bitmap, browser.Bounds);            // Save as file?            if (m_FileName.Length > 0)            {                // Save                m_Bitmap.SaveJPG100(m_FileName);            }            if (initheight == browser.Document.Body.ScrollRectangle.Bottom)            {                browser.DocumentCompleted -= new WebBrowserDocumentCompletedEventHandler(WebBrowser_DocumentCompleted);            }            initheight = browser.Document.Body.ScrollRectangle.Bottom;        }    }

生成压缩包

 对于批量生成的图片文件,我们可以生成压缩包为客户提供下载功能,压缩功能引用的是ICSharpCode.SharpZipLib.dll,创建 ZipCompress 类的实例,ZipDirectory(zippath, zipfile, password) 方法,需要提供的参数包括,压缩的目录、生成的压缩文件名,压缩包的打开密码。

示例代码如下:

    string zippath = Request.PhysicalApplicationPath + "\\des\\" ;    if (!Directory.Exists(zippath))    {        Directory.CreateDirectory(zippath);    }    string zipfile = Request.PhysicalApplicationPath + "\\des\\test.zip";    ZipCompress allgzip = new ZipCompress();    System.IO.DirectoryInfo alldi = new System.IO.DirectoryInfo(zippath);    string password = "123456";    allgzip.ZipDirectory(zippath, zipfile, password);    //以下是生成完压缩包后,清除目录及文件    string[] allfs = Directory.GetFiles(zippath);    for (int i = 0; i < allfs.Length; i++)    {        File.Delete(allfs[i]);    }    Directory.Delete(zippath);  

类及实现代码如下:

 public class ZipCompress    {                public  byte[] Compress(byte[] inputBytes)        {            using (MemoryStream outStream = new MemoryStream())            {                using (GZipStream zipStream = new GZipStream(outStream, CompressionMode.Compress, true))                {                    zipStream.Write(inputBytes, 0, inputBytes.Length);                    zipStream.Close(); //很重要,必须关闭,否则无法正确解压                    return outStream.ToArray();                }            }        }        public  byte[] Decompress(byte[] inputBytes)        {            using (MemoryStream inputStream = new MemoryStream(inputBytes))            {                using (MemoryStream outStream = new MemoryStream())                {                    using (GZipStream zipStream = new GZipStream(inputStream, CompressionMode.Decompress))                    {                        zipStream.CopyTo(outStream);                        zipStream.Close();                        return outStream.ToArray();                    }                }            }        }        public  string Compress(string input)        {            byte[] inputBytes = Encoding.Default.GetBytes(input);            byte[] result = Compress(inputBytes);            return Convert.ToBase64String(result);        }        public  string Decompress(string input)        {            byte[] inputBytes = Convert.FromBase64String(input);            byte[] depressBytes = Decompress(inputBytes);            return Encoding.Default.GetString(depressBytes);        }        public  void Compress(DirectoryInfo dir)        {            foreach (FileInfo fileToCompress in dir.GetFiles())            {                Compress(fileToCompress);            }        }        public  void Decompress(DirectoryInfo dir)        {            foreach (FileInfo fileToCompress in dir.GetFiles())            {                Decompress(fileToCompress);            }        }        public  void Compress(FileInfo fileToCompress)        {            using (FileStream originalFileStream = fileToCompress.OpenRead())            {                if ((File.GetAttributes(fileToCompress.FullName) & FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")                {                    using (FileStream compressedFileStream = File.Create(fileToCompress.FullName + ".gz"))                    {                        using (GZipStream compressionStream = new GZipStream(compressedFileStream, CompressionMode.Compress))                        {                            originalFileStream.CopyTo(compressionStream);                        }                    }                }            }        }        public  void Decompress(FileInfo fileToDecompress,string desfilename="")        {            using (FileStream originalFileStream = fileToDecompress.OpenRead())            {                string currentFileName = fileToDecompress.FullName;                string newFileName = currentFileName.Remove(currentFileName.Length - fileToDecompress.Extension.Length);                if (desfilename != "")                {                    newFileName = desfilename;                }                using (FileStream decompressedFileStream = File.Create(newFileName))                {                    using (GZipStream decompressionStream = new GZipStream(originalFileStream, CompressionMode.Decompress))                    {                        decompressionStream.CopyTo(decompressedFileStream);                    }                }            }        }                public  void ZipDirectory(string folderToZip, string zipedFileName,string password)        {            ZipDirectory(folderToZip, zipedFileName,(password==""?string.Empty:password), true, string.Empty, string.Empty, true);        }          public  void ZipDirectory(string folderToZip, string zipedFileName, string password, bool isRecurse, string fileRegexFilter, string directoryRegexFilter, bool isCreateEmptyDirectories)        {             FastZip fastZip = new FastZip();            fastZip.CreateEmptyDirectories = isCreateEmptyDirectories;            fastZip.Password = password;            fastZip.CreateZip(zipedFileName, folderToZip, isRecurse, fileRegexFilter, directoryRegexFilter);               }        public void UnZipDirectory(string zipedFileName, string targetDirectory, string password,string fileFilter=null)        {            FastZip fastZip = new FastZip();            fastZip.Password = password;            fastZip.ExtractZip(zipedFileName, targetDirectory,fileFilter);        }        public void UnZip(string zipFilePath, string unZipDir)        {                       if (zipFilePath == string.Empty)            {                throw new Exception("压缩文件不能为空!");            }            if (!File.Exists(zipFilePath))            {                throw new FileNotFoundException("压缩文件不存在!");            }            //解压文件夹为空时默认与压缩文件同一级目录下,跟压缩文件同名的文件夹              if (unZipDir == string.Empty)                unZipDir = zipFilePath.Replace(Path.GetFileName(zipFilePath), Path.GetFileNameWithoutExtension(zipFilePath));            if (!unZipDir.EndsWith("/"))                unZipDir += "/";            if (!Directory.Exists(unZipDir))                Directory.CreateDirectory(unZipDir);             using (var s = new ZipInputStream(File.OpenRead(zipFilePath)))            {                 ZipEntry theEntry;                while ((theEntry = s.GetNextEntry()) != null)                {                    string directoryName = Path.GetDirectoryName(theEntry.Name);                    string fileName = Path.GetFileName(theEntry.Name);                    if (!string.IsNullOrEmpty(directoryName))                    {                        Directory.CreateDirectory(unZipDir + directoryName);                    }                    if (directoryName != null && !directoryName.EndsWith("/"))                    {                    }                    if (fileName != String.Empty)                    {                        using (FileStream streamWriter = File.Create(unZipDir + theEntry.Name))                        {                             int size;                            byte[] data = new byte[2048];                            while (true)                            {                                size = s.Read(data, 0, data.Length);                                if (size > 0)                                {                                    streamWriter.Write(data, 0, size);                                }                                else                                {                                    break;                                }                            }                        }                    }                }            }        }    }

小结 

对于生成的图片文件,我们还可以结合其它的API应用,来判断图片是否有被PS的情况,来提升和扩展应用程序的功能。另外,对于被访问的动态页面,建议使用访问控制,只有正常登录或提供访问令牌的用户才可以生成结果图片,以保证数据的安全性。

以上代码仅供参考,欢迎大家指正,再次感谢您的阅读!

 


点击全文阅读


本文链接:http://zhangshiyu.com/post/70125.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1