1. 程式人生 > WINDOWS開發 >hprose資料視覺化顯示,通過c#序列化,列表形式展示,匯出excel、csv

hprose資料視覺化顯示,通過c#序列化,列表形式展示,匯出excel、csv

<Window x:Class="WpfApp1.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local
="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Window.Resources> <local:MyColorConverter x:Key="cc"></local:MyColorConverter> </Window.Resources> <TabControl> <TabItem Header="
文字反序列化"> <Grid Margin="5"> <Grid.ColumnDefinitions> <ColumnDefinition></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition Width="
Auto"></ColumnDefinition> </Grid.ColumnDefinitions> <DockPanel> <TextBlock Text="原始文字:" DockPanel.Dock="Top"></TextBlock> <TextBox x:Name="tb1" Background="Transparent" Foreground="Gray" TextWrapping="Wrap" /> </DockPanel> <Button Content="->->" Margin="5" Grid.Column="1" Height="35" Click="ButtonBase_OnClick" /> <DockPanel Grid.Column="2"> <TextBox Text="解析後:" DockPanel.Dock="Top"></TextBox> <TreeView x:Name="tv" Background="Transparent" Grid.Column="2"> <TreeView.ItemContainerStyle> <Style TargetType="TreeViewItem"> <Setter Property="IsExpanded" Value="True"></Setter> </Style> </TreeView.ItemContainerStyle> <TreeView.ItemTemplate> <HierarchicalDataTemplate ItemsSource="{Binding Children}"> <StackPanel Orientation="Horizontal" Margin="0 2"> <TextBox Foreground="{Binding Level,Converter={StaticResource cc}}" Text="{Binding Key}" MinWidth="160"></TextBox> <TextBox Text="{Binding Value}" MinWidth="160" Foreground="Gray" Margin="5 0 0 0"></TextBox> </StackPanel> </HierarchicalDataTemplate> </TreeView.ItemTemplate> </TreeView> </DockPanel> <Button Content="匯出結果到csv" Grid.Column="3" Height="35" Click="exportClick"></Button> </Grid> </TabItem> </TabControl> </Window>
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Windows;
using Hprose.IO;
using Microsoft.Win32;

namespace WpfApp1
{
    /// <summary>
    ///     MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        private static Dictionary<string,string> s = new Dictionary<string,string>();

        private static string msg = "";

        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        ///     解析【類】
        /// </summary>
        /// <param name="str_obj_dict"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        private static List<SimpleKeyValuePair> ParseStringObjDict(Dictionary<string,object> str_obj_dict,int level)
        {
            var mm = new List<SimpleKeyValuePair>();
            foreach (var o in str_obj_dict)
                //【子序列】
                if (o.Value is IEnumerable<object> d)
                {
                    var sp = new SimpleKeyValuePair();
                    sp.Key = o.Key;
                    sp.Value = "【子集序列】" + "個數" + d.Count();
                    sp.Children = ParseObjectList(d,sp.Key,level);
                    sp.Level = level;
                    mm.Add(sp);
                }

                //【類】
                else if (o.Value is Dictionary<string,object> dict)
                {
                    var sp = new SimpleKeyValuePair();
                    sp.Key = o.Key;
                    sp.Value = "【類】";
                    sp.Children = ParseStringObjDict(dict,level);
                    sp.Level = level;
                    mm.Add(sp);
                }
                //【單個欄位】
                else
                {
                    var sp = new SimpleKeyValuePair();
                    sp.Key = o.Key;
                    sp.Value = o.Value?.ToString();
                    sp.Level = level;
                    mm.Add(sp);
                }

            return mm;
        }

        /// <summary>
        ///     解析【序列,子集】
        /// </summary>
        /// <param name="dd"></param>
        /// <param name="parentName"></param>
        /// <param name="level"></param>
        /// <returns></returns>
        private static List<SimpleKeyValuePair> ParseObjectList(IEnumerable<object> dd,string parentName,int level)
        {
            var childrenList = new List<SimpleKeyValuePair>();
            var i = 0;
            level++;
            foreach (var o in dd)
            {
                var tp = o.GetType();

                var child = new SimpleKeyValuePair {Key = parentName + "的【子集】" + i++,Value = "【新的類】",Level = level};
                if (o is Dictionary<string,object> d)
                {
                    childrenList.Add(child);
                    child.Children = ParseStringObjDict(d,level);
                }
            }

            return childrenList;
        }


        private void ButtonBase_OnClick(object sender,RoutedEventArgs e)
        {
            try
            {
                var bts = Encoding.UTF8.GetBytes(tb1.Text);
                var str_obj_dict = HproseFormatter.Unserialize<Dictionary<string,object>>(bts);

                var result = ParseStringObjDict(str_obj_dict,0);
                tv.ItemsSource = null;
                tv.ItemsSource = result;
            }
            catch (Exception exception)
            {
                MessageBox.Show(exception.Message);
            }
        }

        private void exportClick(object sender,RoutedEventArgs e)
        {
            var result = "key,value\r\n";
            if (tv.ItemsSource is List<SimpleKeyValuePair> li) result += MakeString(li,0);
            var sfd = new SaveFileDialog();
            sfd.Filter = ".csv|*.csv|.txt|*.txt";
            var ok = sfd.ShowDialog(this);
            if (ok == true)
                if (!string.IsNullOrEmpty(sfd.FileName))
                    SimpleLogger.Log(sfd.FileName,result);
        }

        private string MakeString(List<SimpleKeyValuePair> li,int quoteTimes)
        {
            var result = "";
            li.ForEach(x =>
                {
                    result = result + "\r\n" +
                             string.Join(",",Enumerable.Range(0,quoteTimes).Select(y => "").ToArray()) +
                             GetSafeStr(x.Key) + "," + GetSafeStr(x.Value);
                    if (x.Children != null && x.Children.Count > 0)
                    {
                        var newTime = quoteTimes + 2;
                        result = result + MakeString(x.Children,newTime);
                    }
                }
            );
            return result;
        }

        private string GetSafeStr(string x)
        {
            if (x == null) return "";
            return "\"" + x + "\"";
        }
    }

    public static class SimpleLogger
    {
        private static readonly object locker = new object();

        public static void Log(string file,string msg)
        {
            lock (locker)
            {
                var fs = new FileStream(file,FileMode.OpenOrCreate);
                var sw = new StreamWriter(fs,Encoding.Default);
                sw.WriteLine(msg);
                sw.Close();
            }
        }
    }

    public class SimpleKeyValuePair : INotifyPropertyChanged
    {
        public string Key { get; set; }

        public string Value { get; set; }

        public List<SimpleKeyValuePair> Children { get; set; } = new List<SimpleKeyValuePair>();

        public int Level { get; set; }
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this,new PropertyChangedEventArgs(propertyName));
        }
    }
}
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using System.Windows.Media;

namespace WpfApp1
{
    public class MyColorConverter : IValueConverter
    {
        static  List<SolidColorBrush> _solid=new List<SolidColorBrush>(){Brushes.Red,Brushes.Blue,Brushes.Green,Brushes.Brown,Brushes.Magenta,Brushes.Orange,Brushes.Cyan};
        public object Convert(object value,Type targetType,object parameter,CultureInfo culture)
        {
            if (value is int level)
            {
                return _solid[level];
                
            }

            return null;
        }

        public object ConvertBack(object value,CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

效果圖

技術分享圖片