C#实现网页页面截屏存储功能留档2025-08-13

曾经想要保存自己想要的存在的价值,用浏览器的功能,总是有一部分不尽如人意。
系统自带的打印,部分页面显示不全,感觉无法生成我想要的PDF或者PNG。

1、创建.Net Framework项目,选择版本4.7.2

1、创建窗体应用

2、使用Nuget安装CefSharp.WinForms(一个内置浏览器,来实现相应功能)

2、安装CefSharp.WinForms

3、窗体布局(注:Anchor参数可使WEB窗体大小自动,方便截图打印)

页面布局.png

4、代码编写(利用CefSharp.WinForms自带的CaptureScreenshotAsync功能实现)

using CefSharp.WinForms;
using CefSharp;
using System;
using System.Windows.Forms;
using System.IO;
using System.Collections.Generic;

namespace 火焰山网页打印
{
    public partial class Form1 : Form
    {

        private const string HistoryFilePath = "history.txt"; // 历史记录文件路径
        
        private const int MaxHistoryLines = 200; // 最大历史记录行数

        public Form1()
        {
            InitializeComponent();
            InitializeChromium();
        }

        private void InitializeChromium()
        {
            var settings = new CefSettings
            {
                CachePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "CefSharp\\Cache"), // 设置缓存路径
                Locale = "zh-CN" // 设置语言为中文
            };
            Cef.Initialize(settings);
            textBox1.Text = "https://www.bing.com"; // 修复URL

            this.FormClosing += new FormClosingEventHandler(Form1_FormClosing);
            chromiumWebBrowser1.AddressChanged += ChromiumWebBrowser1_AddressChanged;

            comboBox1.TextChanged += ComboBox1_TextChanged;

            // 设置 LifeSpanHandler
            chromiumWebBrowser1.LifeSpanHandler = new CustomLifeSpanHandler();

        }

        private void ComboBox1_TextChanged(object sender, EventArgs e)
        {
            try
            {
                chromiumWebBrowser1.Load(comboBox1.Text);
            }
            catch (Exception) { }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                chromiumWebBrowser1.Load(textBox1.Text);
            }
            catch (Exception) { }
        }



        public class CustomLifeSpanHandler : ILifeSpanHandler
        {
            public bool OnBeforePopup(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, string targetFrameName, WindowOpenDisposition targetDisposition, bool userGesture, IPopupFeatures popupFeatures, IWindowInfo windowInfo, IBrowserSettings browserSettings, ref bool noJavascriptAccess, out IWebBrowser newBrowser)
            {
                // 禁止新窗口的创建,强制在当前窗口中打开链接
                browser.MainFrame.LoadUrl(targetUrl);
                newBrowser = null;
                return true;
            }

            public void OnAfterCreated(IWebBrowser browserControl, IBrowser browser)
            {
            }

            public bool DoClose(IWebBrowser browserControl, IBrowser browser)
            {
                return false;
            }

            public void OnBeforeClose(IWebBrowser browserControl, IBrowser browser)
            {
            }
        }

        private void LoadHistory()
        {
            try
            {
                if (File.Exists(HistoryFilePath))
                {
                    string[] lines = File.ReadAllLines(HistoryFilePath);

                    // 确保在UI线程上操作
                    if (InvokeRequired)
                    {
                        Invoke(new Action(() =>
                        {
                            comboBox1.Items.Clear(); // 清空 ComboBox 中的现有条目
                            HashSet<string> uniqueUrls = new HashSet<string>(); // 创建一个 HashSet 用于存储唯一的 URL
                            foreach (string line in lines)
                            {
                                string[] parts = line.Split(new string[] { "<<->>" }, StringSplitOptions.None);
                                if (parts.Length > 1)
                                {
                                    string url = parts[1].Trim(); // 获取 URL 并去除首尾空格
                                    if (!uniqueUrls.Contains(url)) // 检查 URL 是否已经存在
                                    {
                                        comboBox1.Items.Add(url); // 将 URL 添加到 ComboBox 中
                                        uniqueUrls.Add(url); // 将 URL 添加到 HashSet 中,用于去重
                                    }
                                }
                            }
                        }));
                    }
                    else
                    {
                        comboBox1.Items.Clear(); // 清空 ComboBox 中的现有条目
                        foreach (string line in lines)
                        {
                            string[] parts = line.Split(new string[] { "<<->>" }, StringSplitOptions.None);
                            if (parts.Length > 1)
                            {
                                comboBox1.Items.Add(parts[1].Trim()); // 将 URL 添加到 ComboBox 中
                            }
                        }
                    }
                }
                else {
                    // 确保在UI线程上操作
                    if (InvokeRequired)
                    {
                        Invoke(new Action(() =>
                        {
                            comboBox1.Items.Clear(); // 清空 ComboBox 中的现有条目
                        }));
                    }
                    else
                    {
                        comboBox1.Items.Clear(); // 清空 ComboBox 中的现有条目
                    }
                }
            }
            catch (Exception) { }
        }

        private void DeleteHistory()
        {
            try
            {
                if (File.Exists(HistoryFilePath))
                {
                    File.Delete(HistoryFilePath);

                    // 确保在UI线程上操作
                    if (InvokeRequired)
                    {
                        Invoke(new Action(() =>
                        {
                            comboBox1.Items.Clear(); // 清空 ComboBox 中的现有条目
                        }));
                    }
                    else
                    {
                        comboBox1.Items.Clear(); // 清空 ComboBox 中的现有条目
                    }
                }
            }
            catch (Exception) { }
        }

        private void SaveHistory(string url)
        {
            try
            {
                string timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                string historyEntry = $"{timestamp} <<->> {url}";

                // 读取现有历史记录
                string[] lines = File.Exists(HistoryFilePath) ? File.ReadAllLines(HistoryFilePath) : new string[0];

                // 添加新的历史记录
                Array.Resize(ref lines, lines.Length + 1);
                lines[lines.Length - 1] = historyEntry;

                // 确保不超过最大行数
                if (lines.Length > MaxHistoryLines)
                {
                    Array.Resize(ref lines, MaxHistoryLines);
                }

                // 保存到文件
                File.WriteAllLines(HistoryFilePath, lines);
            }
            catch (Exception) { }
        }

        private void ChromiumWebBrowser1_AddressChanged(object sender, AddressChangedEventArgs e)
        {
            try
            {
                SaveHistory(e.Address);
                LoadHistory();
            }
            catch (Exception) { }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                string url = textBox1.Text;
                if (Uri.IsWellFormedUriString(url, UriKind.Absolute))
                {
                    try
                    {
                        chromiumWebBrowser1.Load(url);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show($"加载页面时发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
                else
                {
                    MessageBox.Show("请输入有效的URL地址!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            catch (Exception) { }
            
        }

        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                if (chromiumWebBrowser1.CanGoBack)
                {
                    chromiumWebBrowser1.Back();
                }
            }
            catch (Exception) { }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                // 关闭浏览器时释放资源
                Cef.Shutdown();
            }
            catch (Exception) { }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            try
            {
                string homePage = "https://nginx.mblue.ltd/navigation/my/link/myself/";
                chromiumWebBrowser1.Load(homePage);
                textBox1.Text = homePage;
            }
            catch (Exception) { }
        }

        private void button4_Click(object sender, EventArgs e)
        {
            try
            {
                if (chromiumWebBrowser1.CanGoForward)
                {
                    chromiumWebBrowser1.Forward();
                }
            }
            catch (Exception) { }
        }

        private void button5_Click(object sender, EventArgs e)
        {
            try
            {
                chromiumWebBrowser1.Reload();
            }
            catch (Exception) { }
        }

        private void button6_Click(object sender, EventArgs e)
        {
            try
            {
                chromiumWebBrowser1.Print();
            }
            catch (Exception) { }
        }

        private async void button8_Click(object sender, EventArgs e)
        {
            if (chromiumWebBrowser1.IsBrowserInitialized)
            {
                try
                {
                    // 捕获当前页面为字节数组
                    // byte[] screenshotData = await chromiumWebBrowser1.CaptureScreenshotAsync();
                    // 捕获整个页面的截图
                    byte[] screenshotData = await chromiumWebBrowser1.CaptureScreenshotAsync(captureBeyondViewport: true);

                    string screenshotDirectory = Path.Combine(Environment.CurrentDirectory, "screenshot");
                    if (!Directory.Exists(screenshotDirectory))
                    {
                        Directory.CreateDirectory(screenshotDirectory); // 如果目录不存在,则创建目录
                    }
                    string screenshotFileName = Guid.NewGuid().ToString() + ".png"; // 使用 UUID 生成文件名
                    string screenshotPath = Path.Combine(screenshotDirectory, screenshotFileName);

                    File.WriteAllBytes(screenshotPath, screenshotData);

                    MessageBox.Show($"截图已保存到: {screenshotPath}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"截图时发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("浏览器尚未初始化,请稍后再试!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        
        private async void button9_Click(object sender, EventArgs e)
        {
            if (chromiumWebBrowser1.IsBrowserInitialized)
            {
                try
                {
                    // 捕获整个页面的截图
                    byte[] screenshotData = await chromiumWebBrowser1.CaptureScreenshotAsync(captureBeyondViewport: true);
                    // 保存字节数组到文件
                    string screenshotPath = Path.Combine(Environment.CurrentDirectory, "screenshot.png");
                    File.WriteAllBytes(screenshotPath, screenshotData);

                    MessageBox.Show($"截图已保存到: {screenshotPath}", "成功", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"截图时发生错误: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            else
            {
                MessageBox.Show("浏览器尚未初始化,请稍后再试!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void button9_Click_1(object sender, EventArgs e)
        {
            try
            {
                DeleteHistory();
            }
            catch (Exception) { }
        }
    }
}

4、程序展示

窗体网页加载完成

4、结果展示

窗体网页加载完成,截屏打印结果示例
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容