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

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

应用场景

我们在一个求职简历打印的项目功能里,需要根据一定的查询条件,得到结果并批量导出指定格式的文件。导出的格式可能有多种,比如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的情况,来提升和扩展应用程序的功能。另外,对于被访问的动态页面,建议使用访问控制,只有正常登录或提供访问令牌的用户才可以生成结果图片,以保证数据的安全性。

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


相关文章
|
6月前
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
选中项目,点击右上角的显示全部文件按钮,会将默认隐藏的文件显示出来,选中所需图片,右键,添加到项目,然后选择图片查看属性,生成操作选择resource。完毕。本人目前的解决方案。
260 41
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
|
4月前
|
API C#
C# 调用系统“API“设置图片为“桌面壁纸“
C# 调用系统“API“设置图片为“桌面壁纸“
|
6月前
|
C#
C# 图片RGB处理判断
C# 图片RGB处理判断 需要:根据一张原始图的RGB平均值和新的图片的RGB平均值的差距,来判断图中是否出现除原图中物体外的其他物体 前提:.Net framework 4.8 及以上 示例代码: 程序集:using System;using System.Drawing;using System.Drawing.Drawing2D;using System.Drawing.Imagin...
22 0
|
9月前
|
人工智能 文字识别 API
C# 10分钟完成百度图片提取文字(文字识别)——入门篇
C# 10分钟完成百度图片提取文字(文字识别)——入门篇
|
10月前
|
数据采集 C#
使用c#和selenium获取网页
selenium 和 c# 的应用之一是创建一个网络爬虫,它可以从网页中抓取数据进行分析。网络爬虫是一种访问网页并从中提取信息的程序。 Selenium 是一个框架,它允许我们自动执行浏览器操作,例如单击、键入或导航。 C# 是一种编程语言,可用于编写网络爬虫的逻辑和功能。
107 0
|
11月前
|
开发框架 移动开发 前端开发
如何使用C#和HTMLAgilityPack抓取网页
HTMLAgilityPack是一款备受欢迎的用于解析和操作HTML文档的库。在使用之前,开发者需要考虑一些优缺点。下面是一些值得注意的优点: 1. 强大的错误容忍性 2. 灵活的API 3. 广泛的应用场景 然而,也有一些缺点需要考虑: 1. 性能问题 2. 对最新HTML特性的支持限制 3. 可能存在依赖和冲突
|
算法 定位技术 C#
C#开发:不规则裁切图片
C#开发:不规则裁切图片
121 0
|
区块链 C#
C#实现把图片转换为ico格式
C#实现把图片转换为ico格式
597 0
|
C# 图形学
C#裁剪图片的方法
C#裁剪图片的方法
256 0
|
1月前
|
C#
24. C# 编程:用户设定敌人初始血值的实现
24. C# 编程:用户设定敌人初始血值的实现
22 0