使用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的情况,来提升和扩展应用程序的功能。另外,对于被访问的动态页面,建议使用访问控制,只有正常登录或提供访问令牌的用户才可以生成结果图片,以保证数据的安全性。
到此这篇关于使用C#实现网页内容保存为图片并生成压缩包的文章就介绍到这了,更多相关C#网页内容保存为图片内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!