使用C#實現(xiàn)網(wǎng)頁內(nèi)容保存為圖片并生成壓縮包
應(yīng)用場景
我們在一個求職簡歷打印的項目功能里,需要根據(jù)一定的查詢條件,得到結(jié)果并批量導出指定格式的文件。導出的格式可能有多種,比如WORD格式、EXCEL格式、PDF格式等,實現(xiàn)方式是通過設(shè)置對應(yīng)的模板進行輸出,實際情況是,簡歷的內(nèi)容是靈活設(shè)置的,沒有固定的格式,模板數(shù)量是不固定的。
通過動態(tài)頁面技術(shù),可以實現(xiàn)簡歷配置后的網(wǎng)頁內(nèi)容輸出,但制作對應(yīng)的各種模板會遇到開發(fā)效率和服務(wù)跟進的問題。為了保障原樣輸出,折中而簡單的方案就是將動態(tài)輸出的頁面轉(zhuǎn)化為圖片格式。
實現(xiàn)代碼
創(chuàng)建一個 UrlToImage 類,創(chuàng)建實例的時候傳遞指定的 URL, 并調(diào)用 SaveToImageFile(string outputFilename)方法,該方法傳遞要輸出的文件名參數(shù)即可即可。
調(diào)用示例代碼如下:
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();
}
類及實現(xiàn)代碼如下:
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,創(chuàng)建 ZipCompress 類的實例,ZipDirectory(zippath, zipfile, password) 方法,需要提供的參數(shù)包括,壓縮的目錄、生成的壓縮文件名,壓縮包的打開密碼。
示例代碼如下:
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);
類及實現(xiàn)代碼如下:
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(); //很重要,必須關(guān)閉,否則無法正確解壓
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;
}
}
}
}
}
}
}
}小結(jié)
對于生成的圖片文件,我們還可以結(jié)合其它的API應(yīng)用,來判斷圖片是否有被PS的情況,來提升和擴展應(yīng)用程序的功能。另外,對于被訪問的動態(tài)頁面,建議使用訪問控制,只有正常登錄或提供訪問令牌的用戶才可以生成結(jié)果圖片,以保證數(shù)據(jù)的安全性。
到此這篇關(guān)于使用C#實現(xiàn)網(wǎng)頁內(nèi)容保存為圖片并生成壓縮包的文章就介紹到這了,更多相關(guān)C#網(wǎng)頁內(nèi)容保存為圖片內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
DevExpress實現(xiàn)TreeList向上遞歸獲取符合條件的父節(jié)點
這篇文章主要介紹了DevExpress實現(xiàn)TreeList向上遞歸獲取符合條件的父節(jié)點,需要的朋友可以參考下2014-08-08
C#實現(xiàn)將字符串轉(zhuǎn)換成日期格式的方法
這篇文章主要介紹了C#實現(xiàn)將字符串轉(zhuǎn)換成日期格式的方法,涉及C#操作時間及字符串的相關(guān)技巧,非常簡單實用,需要的朋友可以參考下2015-05-05
C#實現(xiàn)通過程序自動抓取遠程Web網(wǎng)頁信息的代碼
C#實現(xiàn)通過程序自動抓取遠程Web網(wǎng)頁信息的代碼...2007-04-04
Unity?UGUI的StandaloneInputModule標準輸入模塊組件使用示例
這篇文章主要為大家介紹了Unity?UGUI的StandaloneInputModule標準輸入模塊組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08

