C#、WPF-批量生成QR二维码,TCP传输并打印日志

目录

一、需求

二、实现

简单做了一下,有些许小Bug,比较简单,自行解决。

1、TCP服务器

XAML代码

C#后台代码

ViewModel

QR生成

2、TCP客户端

XAML前台

C#后台代码

3、成果视频


一、需求

1、批量生成二维码;

2、实时打印日志;

3、实时监测生成进度;

4、可暂停、继续生成;

5、生成的二维码图片保存在本地,并把扫码数据打印在文本文件中;

6、日志与生成的二维码在客户端实时显示;

QR建议:使用ZXing斑马库,GitHub上开源;

二、实现

简单做了一下,有些许小Bug,比较简单,自行解决。

主要代码如下:

1、TCP服务器

XAML代码

<Window x:Class="QrCodeTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:hc="https://handyorg.github.io/handycontrol"
        xmlns:local="clr-namespace:QrCodeTest"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:model="clr-namespace:QrCodeTest.Models"
        xmlns:vm="clr-namespace:QrCodeTest.ViewModels"
        Title="MainWindow"
        Width="900"
        Height="800"
        WindowStartupLocation="CenterScreen"
        mc:Ignorable="d">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/SkinDefault.xaml" />
                <ResourceDictionary Source="pack://application:,,,/HandyControl;component/Themes/Theme.xaml" />
                <ResourceDictionary Source="/QrCodeTest;component/Genery.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Window.DataContext>
        <vm:MainWinViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <GroupBox Height="400"
                      Background="LightSeaGreen"
                      FontWeight="Black"
                      Header="二维码显示">
                <Grid Margin="3" Background="White">
                    <Image Source="{Binding ImgSource}" />
                </Grid>
            </GroupBox>
            <StackPanel Grid.Row="1">
                <StackPanel>
                    <ProgressBar Width="150"
                                 Height="150"
                                 Margin="5"
                                 Template="{StaticResource protemp}"
                                 Value="{Binding ProcessValue}" />
                    <TextBlock HorizontalAlignment="Center"
                               FontSize="20"
                               FontWeight="Bold"
                               Foreground="Black"
                               Text="生成进度" />
                    <TextBox Height="40"
                             Margin="5"
                             BorderBrush="LightSeaGreen"
                             BorderThickness="3"
                             FontSize="20"
                             FontWeight="Bold"
                             Text="{Binding Number}" />
                </StackPanel>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition/>
                    </Grid.ColumnDefinitions>
                    <Button Width="90"
                            Height="90"
                            Margin="5"
                            Background="LightGray"
                            BorderBrush="LightSeaGreen"
                            BorderThickness="3"
                            Command="{Binding GetQrCommand}"
                            Content="Start"
                            FontSize="25"
                            FontWeight="Bold"
                            Foreground="DarkGreen"
                            IsEnabled="{Binding StartEnable}" />
                    <Button Grid.Column="1"
                            Width="90"
                            Height="90"
                            Margin="5"
                            Background="LightGray"
                            BorderBrush="LightSeaGreen"
                            BorderThickness="3"
                            Command="{Binding StopCommand}"
                            Content="Stop"
                            FontSize="25"
                            FontWeight="Bold"
                            Foreground="Red" />
                    <Button Grid.Column="2"
                            Width="90"
                            Height="90"
                            Margin="5"
                            Background="LightGray"
                            BorderBrush="LightSeaGreen"
                            BorderThickness="3"
                            Command="{Binding ClearLogCommand}"
                            Content="清空日志"
                            FontSize="16"
                            FontWeight="Bold"
                            Foreground="Blue" />
                    <Button Grid.Column="3"
                            Width="90"
                            Height="90"
                            Margin="5"
                            Background="LightGray"
                            BorderBrush="LightSeaGreen"
                            BorderThickness="3"
                            Command="{Binding OpenServerCommand}"
                            Content="开启服务"
                            FontSize="16"
                            FontWeight="Bold"
                            Foreground="DarkMagenta" />
                </Grid>
            </StackPanel>
        </Grid>
        <GroupBox Grid.Column="1"
                  Background="LightGreen"
                  FontWeight="Black"
                  Header="日志">
            <ListView Margin="3"
                      d:ItemsSource="{d:SampleData ItemCount=3}"
                      ItemsSource="{Binding QrInfos}">
                <ListView.View>
                    <GridView>
                        <GridView.Columns>
                            <GridViewColumn>
                                <Border Width="NaN"
                                        BorderBrush="Black"
                                        BorderThickness="1">
                                    <TextBlock HorizontalAlignment="Center"
                                               FontSize="15"
                                               Text="Id" />
                                </Border>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate DataType="{x:Type model:QrInfo}">
                                        <Border BorderBrush="DarkGreen" BorderThickness="0">
                                            <TextBlock FontSize="15" Text="{Binding Id}" />
                                        </Border>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                            <GridViewColumn>
                                <Border Width="NaN"
                                        BorderBrush="Black"
                                        BorderThickness="1">
                                    <TextBlock HorizontalAlignment="Center"
                                               FontSize="15"
                                               Text="文件名" />
                                </Border>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate DataType="{x:Type model:QrInfo}">
                                        <Border BorderBrush="DarkGreen" BorderThickness="0">
                                            <TextBlock FontSize="15" Text="{Binding QrName}" />
                                        </Border>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                            <GridViewColumn>
                                <Border Width="NaN"
                                        BorderBrush="Black"
                                        BorderThickness="1">
                                    <TextBlock HorizontalAlignment="Center"
                                               FontSize="15"
                                               Text="大小(byte)" />
                                </Border>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate DataType="{x:Type model:QrInfo}">
                                        <Border BorderBrush="DarkGreen" BorderThickness="0">
                                            <TextBlock FontSize="15" Text="{Binding Size}" />
                                        </Border>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                            <GridViewColumn>
                                <Border Width="NaN"
                                        BorderBrush="Black"
                                        BorderThickness="1">
                                    <TextBlock HorizontalAlignment="Center"
                                               FontSize="15"
                                               Text="最后修改时间" />
                                </Border>
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate DataType="{x:Type model:QrInfo}">
                                        <Border BorderBrush="DarkGreen" BorderThickness="0">
                                            <TextBlock FontSize="15" Text="{Binding CreateTime}" />
                                        </Border>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                        </GridView.Columns>
                    </GridView>
                </ListView.View>
            </ListView>
        </GroupBox>
    </Grid>
</Window>

C#后台代码

ViewModel
namespace QrCodeTest.ViewModels
{
    internal class MainWinViewModel : BindableBase
    {
        private int flagNum;
        private CancellationTokenSource cts;
        private StringBuilder sb;
        private TcpListener tcpListener;
        private TcpClient tcpClient;
        private NetworkStream stream;
        private double _processValue;

        public double ProcessValue
        {
            get => _processValue;
            set => SetProperty(ref _processValue, value);
        }

        private int _number;

        public int Number
        {
            get => _number;
            set => SetProperty(ref _number, value);
        }

        private bool _startEnable;

        public bool StartEnable
            {
            get => _startEnable;
            set => SetProperty(ref _startEnable, value);
        }

        private ImageSource _imgSource;

        public ImageSource ImgSource
        {
            get => _imgSource;
            set => SetProperty(ref _imgSource, value);
        }

        private ObservableCollection<QrInfo> _qrInfos;

        public ObservableCollection<QrInfo> QrInfos
        {
            get => _qrInfos;
            set => SetProperty(ref _qrInfos, value);
        }

        /// <summary>
        /// 开始生成二维码
        /// </summary>
        public void GetQrCode()
        {
            if (Number > 0)
            {
                StartEnable = false;
                cts = new CancellationTokenSource();
                string savepath = Path.Combine(Directory.GetCurrentDirectory() + @"/MyQr");
                if (!Directory.Exists(savepath))
                {
                    Directory.CreateDirectory(savepath);
                }
                else if (flagNum == 0)
                {
                    Directory.Delete(savepath, true);
                    Directory.CreateDirectory(savepath);
                }
                Task.Factory.StartNew(() =>
                {
                    while (!cts.IsCancellationRequested)
                    {                       
                        string content = DateTime.Now.ToString();
                        Bitmap map = QrCodeServer.GetQrCode(300, 300, content);
                        sb.AppendLine(content);
                        File.WriteAllText(Path.Combine(savepath, "QrText"), sb.ToString());
                        //Bitmap map = QrCodeServer.GetQrCode(300, 300, $"二维码ID:{i}\t生成时间:"+ DateTime.Now.ToString());

                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            ImgSource = Imaging.CreateBitmapSourceFromHBitmap(map.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                            Image image = map;
                            image.Save(Path.Combine(savepath, $"Qr{flagNum + 1}"), ImageFormat.Gif);

                            FileInfo fileInfo = new FileInfo(Path.Combine(savepath, $"Qr{flagNum + 1}"));
                            QrInfos.Add(new QrInfo() { Id = flagNum + 1, QrName = fileInfo.Name, CreateTime = fileInfo.LastWriteTime.ToString(), Size = fileInfo.Length });
                            ProcessValue = (double)(flagNum + 1) / Number;
                        });

                        if (tcpListener.Pending() && tcpClient == null)
                        {
                            tcpClient = tcpListener.AcceptTcpClient();
                            stream = tcpClient.GetStream();
                        }
                        if (tcpClient != null)
                        {
                            byte[] buffer = new byte[1024*6];

                            int tmp = 0;
                            var size =Encoding.UTF8.GetBytes( QrInfos[flagNum].Size.ToString());
                            foreach (var s in size)
                            {
                                buffer[tmp] = s;
                                tmp++;
                            }
                            tmp = 5;
                            var name = Encoding.UTF8.GetBytes(QrInfos[flagNum].QrName);
                            foreach(var kvp in name ) 
                            {
                                buffer[tmp] = kvp;
                                tmp++;
                            }
                            tmp = 10;
                            var bytes = Encoding.UTF8.GetBytes( content);
                            foreach (var item in bytes)
                            {
                                buffer[tmp] = item;
                                tmp++;
                            }
                            tmp = 30;
                            byte[] bytes1=File.ReadAllBytes(Path.Combine(savepath, $"Qr{flagNum + 1}"));
                            foreach (var item in bytes1)
                            {
                                buffer[tmp++]=item;
                            }
                            //byte[] bytes1 = Encoding.Default.GetBytes(ImgSource.ToString());
                            //foreach (var item in bytes1)
                            //{
                            //    buffer[tmp++] = item;
                            //}
                            stream.Write(buffer, 0, buffer.Length);
                        }

                        flagNum++;
                        if (flagNum == Number)
                        {
                            StartEnable = true;
                            cts = null;
                            sb.Clear();
                            //File.WriteAllText(Path.Combine(savepath,"QrText"), sb.ToString());
                            //QrInfos.Clear();
                            flagNum = 0;
                            break;
                        }
                        Thread.Sleep(1000);
                    }
                }, cts.Token);

                /*********单个二维码生成测试
                Bitmap map = QrCodeServer.GetQrCode(300, 300, DateTime.Now.ToLongDateString());
                ImgSource = Imaging.CreateBitmapSourceFromHBitmap(map.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                Image image = map;
                image.Save(Path.Combine(savepath,"Qr1"), ImageFormat.Png);

                FileInfo fileInfo = new FileInfo(Path.Combine(savepath, "Qr1"));
                QrInfos.Add(new QrInfo() { Id = 1, QrName = fileInfo.Name, CreateTime = fileInfo.LastWriteTime.ToString(), Size =fileInfo.Length });
                ******************/
            }
        }

        /// <summary>
        /// 停止二维码生成
        /// </summary>
        public void Stop()
        {
            StartEnable = true;
            if (cts != null)
            {
                cts.Cancel();
                cts = null;
            }
        }

        /// <summary>
        /// 清空日志
        /// </summary>
        public void ClearLog()
        { 
            QrInfos.Clear();
        }

        /// <summary>
        /// 开启服务器
        /// </summary>
        public void OpenServer()
        {
            IPEndPoint iPEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8888);
            tcpListener = new TcpListener(iPEndPoint);
            tcpListener.Start();
            MessageBox.Show("服务器已开启!");
         
        }

        public DelegateCommand GetQrCommand { get; set; }
        public DelegateCommand StopCommand { get; set; }
        public DelegateCommand ClearLogCommand { get; set; }
        public DelegateCommand OpenServerCommand { get; set; }

        public MainWinViewModel()
        {
            QrInfos = new ObservableCollection<QrInfo>();
            sb= new StringBuilder();
            StartEnable = true;
            flagNum = 0;
            Number = 0;
            ProcessValue = 0;
            GetQrCommand = new DelegateCommand(GetQrCode);
            StopCommand = new DelegateCommand(Stop);
            ClearLogCommand = new DelegateCommand(ClearLog);
            OpenServerCommand = new DelegateCommand(OpenServer);
        }
    }
}
QR生成
 public static Bitmap GetQrCode(int width,int height,string content)
        {
            BarcodeWriter writer = new BarcodeWriter();
            writer.Format = BarcodeFormat.QR_CODE;
            QrCodeEncodingOptions options = new QrCodeEncodingOptions();
            options.DisableECI = true;
            options.CharacterSet = "UTF-8";//设置内容编码
            options.Width = width;//设置二维码长宽
            options.Height = height;
            options.Margin = 1;//设置二维码边距
            writer.Options = options;
            Bitmap bitmap = writer.Write(content);
            return bitmap;
        }

2、TCP客户端

XAML前台

<Window x:Class="QrCodeClient.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:local="clr-namespace:QrCodeClient"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:vm="clr-namespace:QrCodeClient.ViewModels"
        Title="MainWindow"
        Width="800"
        Height="450"
        mc:Ignorable="d">
    <Window.DataContext>
        <vm:MainWinViewModel />
    </Window.DataContext>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
            <GroupBox Height="300"
                      Background="Gray"
                      FontSize="20"
                      FontWeight="Black"
                      Header="Qr显示">
                <Grid Margin="10" Background="White">
                    <Image Source="{Binding ImgSource}" />
                </Grid>
            </GroupBox>
            <Button Grid.Row="1"
                    Width="150"
                    Height="80"
                    BorderBrush="LightSeaGreen"
                    BorderThickness="5"
                    Command="{Binding ConnectCommand}"
                    Content="连接服务器"
                    FontSize="20"
                    FontWeight="Black" />
        </Grid>
        <GroupBox Grid.Column="1"
                  Background="LightGreen"
                  FontSize="20"
                  FontWeight="Black"
                  Header="Qr日志">
            <ListView Margin="10"
                      d:ItemsSource="{d:SampleData}"
                      FontSize="15"
                      ItemsSource="{Binding QrInfos}">
                <ListView.View>
                    <GridView>
                        <GridView.ColumnHeaderContainerStyle>
                            <Style TargetType="GridViewColumnHeader">
                                <Setter Property="Background" Value="LightSeaGreen" />
                                <Setter Property="FontSize" Value="20" />
                            </Style>
                        </GridView.ColumnHeaderContainerStyle>
                        <GridViewColumn Width="70" Header="Qr">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate DataType="{x:Type local:QrInfo}">
                                    <TextBlock Text="{Binding QrName}" />
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Size">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate DataType="{x:Type local:QrInfo}">
                                    <TextBlock Text="{Binding Size}" />
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Width="250" Header="扫码内容">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate DataType="{x:Type local:QrInfo}">
                                    <TextBlock Text="{Binding Content}" />
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <!--<GridViewColumn Header="Qr" DisplayMemberBinding="{Binding QrInfo.QrName}"/>
                        <GridViewColumn Header="大小(byte)" DisplayMemberBinding="{Binding QrInfo.Size}"/>
                        <GridViewColumn Header="内容" DisplayMemberBinding="{Binding QrInfo.Content}"/>-->
                    </GridView>
                </ListView.View>
            </ListView>
        </GroupBox>
    </Grid>
</Window>

C#后台代码

namespace QrCodeClient.ViewModels
{
    internal class MainWinViewModel : BindableBase
    {
        private TcpClient tcpClient;
        private NetworkStream stream;
        public ObservableCollection<QrInfo> QrInfos { get; set; }

        private ImageSource _imgSource;

        public ImageSource ImgSource
        {
            get => _imgSource;
            set => SetProperty(ref _imgSource, value);
        }
        public DelegateCommand ConnectCommand { get; set; }

        public void ConnectServer()
        {
            try
            {
                tcpClient = new TcpClient();
                tcpClient.Connect(IPAddress.Parse("127.0.0.1"), 8888);
                stream = tcpClient.GetStream();
            }
            catch (Exception)
            {
                MessageBox.Show("连接失败,请重新尝试。。。", "提示", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            MessageBox.Show("连接成功,开始接受数据。。。", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
            byte[] buffer = new byte[1024 * 6];

            Task.Run(() =>
            {
                while (true)
                {
                    if (stream.DataAvailable)
                    {
                        Array.Clear(buffer, 0, buffer.Length);
                        stream.Read(buffer, 0, buffer.Length);
                        QrInfo info = new QrInfo();
                        byte[] bytes1 = buffer.Take(5).ToArray();
                        var size = Encoding.UTF8.GetString(bytes1);
                        info.Size = Convert.ToInt32(size);

                        byte[] bytes2 = buffer.Skip(5).Take(5).ToArray();
                        var qrname = Encoding.Default.GetString(bytes2);
                        info.QrName = qrname;

                        byte[] bytes3 = buffer.Skip(10).Take(20).ToArray();
                        var qrcontent = Encoding.Default.GetString(bytes3);
                        info.Content = qrcontent;

                        byte[] bytes4 = buffer.Skip(30).ToArray();
                        MemoryStream memoryStream = new MemoryStream(bytes4);
                        var bitmap = new Bitmap(memoryStream);
                        //var img = System.Drawing.Image.FromStream(memoryStream);                       

                        Application.Current.Dispatcher.Invoke(() =>
                        {
                            ImgSource = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                            QrInfos.Add(info);
                        });
                    }
                    Thread.Sleep(1000);
                }
            });
        }

        public MainWinViewModel()
        {
            QrInfos = new ObservableCollection<QrInfo>();
            ConnectCommand = new DelegateCommand(ConnectServer);
        }
    }
}

3、成果视频

QRCodeTest

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值