码迷,mamicode.com
首页 > 数据库 > 详细

【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇三:批量处理后的txt文件入库处理

时间:2014-07-28 11:20:30      阅读:381      评论:0      收藏:0      [点我收藏+]

标签:des   winform   style   blog   http   color   使用   os   

篇一:WPF常用知识以及本项目设计总结:http://www.cnblogs.com/baiboy/p/wpf.html

篇二:基于OneNote难点突破和批量识别:http://www.cnblogs.com/baiboy/p/wpf1.html

篇三:批量处理后的txt文件入库处理:http://www.cnblogs.com/baiboy/p/wpf2.html

篇四:关于OneNote入库处理以及审核:http://www.cnblogs.com/baiboy/p/wpf3.html


【小记】:大胆尝试才能突破,某个中医药大学有一批图片需要处理(ORC),然后进行数据挖掘。之前没有接触过ORC这个东西,但是还是应允了。在网上搜索一番,关于中文图片识别,最终敲定为基于微软的OneNote,其识别率相对较高。网上这个技术点的资料真心不多,后来于博客园找到一篇博文,但是那个程序还是bug百出,而且只是单处理。后来经过一番摸索逐个突破,批处理完成。然后进行界面设计,这些零碎工作完成后,便是入库处理。由于OneNote生成的xml文件封装好的,即不可视的。便将其代码处理生成txt文件,再进行Oracle入库处理。入库前需要文件内容审核,并且在WPF开发中数据绑定和分页中做了独特处理。现在经过半个月的工作,本项目做个阶段总结。一则知识总结便于二次开发,尽量保持程序流畅性,核心知识做以梳理;另外,相关WPFOneNote常用技术共享,便于部分园友所需。本人技术有限,欢迎交流。项目还未结束,暂作阶段文章发布,随后相继发布。


篇三:批量处理后的txt文件入库处理

【开篇概述】:本文继上述文章再做深度剖析,本篇主要介绍txt入库(oracle)和wpf分页,在此篇涉及的页面设计前篇已经细述不再概说。里面涉及到oracle 64位系统安装处理问题,以前oracle的表,序列,触发器,自增种子等基本操作。外加文件操作和利用用户控件分页等技术。大致效果图如下,其次粘贴完整代码,其后就一一概说本文核心要点和难点突破,最后梳理技术知识点,使其一则保持完整性,二则梳理整理知识点便于随时取用。(本篇暂做效果图如下,至于最终效果图和审核界面,待终篇。)

效果图:

 bubuko.com,布布扣

完整代码:

bubuko.com,布布扣
namespace OnenoteOCRDemo
{
    /// <summary>
    /// TextData.xaml 的交互逻辑
    /// </summary>
    public partial class TextData : Window
    {
        public TextData()
        {
            InitializeComponent();
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
        }
        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            this.Loaded += delegate
            {
                InitData();
            };
            dataGrid1.LoadingRow += new EventHandler<DataGridRowEventArgs>(dataGrid1_LoadingRow);
        }
        void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.Header = e.Row.GetIndex() + 1;    //设置行表头的内容值   
        }
        //查询
        private void InitData()
        {
            string sql = "select * from T_TCM_THESIS  order by ID desc";
            DataSet ds = MYHelper.SQLHelper.GetOrlData(sql);
            if (ds.Tables[0].Rows.Count > 0)
            {
                page1.ShowPages(this.dataGrid1, ds, 10);
            }
            else
            {
                System.Windows.Forms.MessageBox.Show("Erroy");
            }
        }
      
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            InitData();
        }
       //批量删除
        List<int> selectFID = new List<int>();  

        private void CheckBox_Click(object sender, RoutedEventArgs e)
        {
            System.Windows.Controls.CheckBox dg = sender as System.Windows.Controls.CheckBox;
            int FID = int.Parse(dg.Tag.ToString());   //获取该行的FID   
            var bl = dg.IsChecked;
            if (bl == true)
            {
                selectFID.Add(FID);         //如果选中就保存FID   
            }
            else
            {
                selectFID.Remove(FID);  //如果选中取消就删除里面的FID   
            }  
           
        }

        private void btnDelete_Click(object sender, RoutedEventArgs e)
        {
            foreach (int FID in selectFID)
            {
                string sql = "delete  T_TCM_THESIS where id=" + FID;
                int i = SQLHelper.OrlExecuteQuery(sql);
                if (i > 0)
                {
                    System.Windows.Forms.MessageBox.Show("success!!!");
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("Erroy!!!");
                }
                InitData();
            }  
        }
        public void TextIsNull()
        {
            txtdocname.Text = "";
            txtyears.Text = "";
            txtdoctype.Text = "";
            txtsummary.Text = "";
            txtauthor.Text = "";
            txtsource.Text = "";
            txtsourcetype.Text = "";
            txtmemo.Text = "";
            txttitle.Text = "";
            txtenglishtitle.Text = "";
            txtcompany.Text = "";
            txtkeyword.Text = "";
            txtcontent.Text = "";
            txtdigest.Text = "";
            txtpath.Text = "";
            txtdisease.Text = "";
        }
        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            string docname = txtdocname.Text.ToString();
            string years = txtyears.Text.ToString();
            string doctype = txtdoctype.Text.ToString();
            string summary = txtsummary.Text.ToString();
            string author = txtauthor.Text.ToString();
            string source = txtsource.Text.ToString();
            string sourcetype = txtsourcetype.Text.ToString();
            string memo = txtmemo.Text.ToString();
            string title = txttitle.Text.ToString();
            string englishtitle = txtenglishtitle.Text.ToString();
            string authorcompany = txtcompany.Text.ToString();
            string keyword = txtkeyword.Text.ToString();
            string content = txtcontent.Text.ToString().Trim();
            string digest = txtdigest.Text.ToString();
            string path = txtpath.Text.ToString();
            string disease = txtdisease.Text.ToString();
            int auditflag = 1;
            try
            {
                string sql = "INSERT INTO T_TCM_THESIS(docname,years,doctype,summary,author,source,sourcetype,memo,title,englishtitle,";
                sql += "authorcompany,keyword,content,digest,path,disease,auditflag) Values(‘" + docname + "‘,‘" + years + "‘,‘" + doctype + "‘,‘" + summary + "‘,";
                sql += "" + author + "‘,‘" + source + "‘,‘" + sourcetype + "‘,‘" + memo + "‘,‘" + title + "‘,‘" + englishtitle + "‘,‘" + authorcompany + "‘,‘" + keyword + "‘,";
                sql += "" + content + "‘,‘" + digest + "‘,‘" + path + "‘,‘" + disease + "‘," + auditflag + ")";
                int i = SQLHelper.OrlExecuteQuery(sql);
                if (i > 0)
                {
                    System.Windows.Forms.MessageBox.Show("success!!!");
                    TextIsNull();
                }
                else
                {
                    System.Windows.Forms.MessageBox.Show("Erroy!!!");
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
            }
            InitData();
        }
        //选择入库文本
        private void bnt_Click(object sender, RoutedEventArgs e)
        {
            txtcontent.Text = "";
            openData1();
        }
        //入库文本操作
    }
}
View Code

 


【功能以及操作描述】

  1. 首先要安装oracle数据库,当然安装过后可以跳过第一步,没有的话,我重点介绍下64位oracle安装情况,因为中间有一些问题需要解决。64位系统中PL/SQL不能连接数据库,解决的文章偏多,建议参看此篇博文:http://blog.sina.com.cn/s/blog_475839a50101hoyg.html。在完成oracle安装后可以做具体表的设计等,后面展开。  
  2. 在本页面,用户选择浏览选择对应的文件,通过流读取,利用正则表达式截取核心字段数据。因为文本中包含书名/作者/题目等信息,为了体现用户友好性,则做如下操作:(由于截取时的标准不一,可能有所错误,故另加审核页面。 )
    bubuko.com,布布扣
                        StreamReader sr = new StreamReader(ofd.FileName, System.Text.Encoding.Default);
                        txtcontent.Text += sr.ReadToEnd();
                        sr.Close();
                        //指定截取书名
                        string str_start = @"书名:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex = new Regex(str_start, RegexOptions.Multiline);
                        string a = txtcontent.Text;
                        Match MyMatch = MyRegex.Match(a);
                        txttitle.Text=txtdocname.Text = MyMatch.Groups["info"].Value.ToString();
                        //指定截取作者
                        string str_start1 = @"作者:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex1 = new Regex(str_start1, RegexOptions.Multiline);
                        string b = txtcontent.Text;
                        Match MyMatch1 = MyRegex1.Match(b);
                        txtauthor.Text = MyMatch1.Groups["info"].Value.ToString();
                        //指定截取朝代
                        string str_start2 = @"朝代:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex2 = new Regex(str_start2, RegexOptions.Multiline);
                        string c = txtcontent.Text;
                        Match MyMatch2 = MyRegex2.Match(c);
                        txtyears.Text = MyMatch2.Groups["info"].Value.ToString();
    View Code
  3. 通过点击添加按钮,进行入库,入库后通过审核再做修改。
    bubuko.com,布布扣
    private void btnAdd_Click(object sender, RoutedEventArgs e)
            {
                string docname = txtdocname.Text.ToString();
                string years = txtyears.Text.ToString();
                string doctype = txtdoctype.Text.ToString();
                string summary = txtsummary.Text.ToString();
                string author = txtauthor.Text.ToString();
                string source = txtsource.Text.ToString();
                string sourcetype = txtsourcetype.Text.ToString();
                string memo = txtmemo.Text.ToString();
                string title = txttitle.Text.ToString();
                string englishtitle = txtenglishtitle.Text.ToString();
                string authorcompany = txtcompany.Text.ToString();
                string keyword = txtkeyword.Text.ToString();
                string content = txtcontent.Text.ToString().Trim();
                string digest = txtdigest.Text.ToString();
                string path = txtpath.Text.ToString();
                string disease = txtdisease.Text.ToString();
                int auditflag = 1;
                try
                {
                    string sql = "INSERT INTO T_TCM_THESIS(docname,years,doctype,summary,author,source,sourcetype,memo,title,englishtitle,";
                    sql += "authorcompany,keyword,content,digest,path,disease,auditflag) Values(‘" + docname + "‘,‘" + years + "‘,‘" + doctype + "‘,‘" + summary + "‘,";
                    sql += "" + author + "‘,‘" + source + "‘,‘" + sourcetype + "‘,‘" + memo + "‘,‘" + title + "‘,‘" + englishtitle + "‘,‘" + authorcompany + "‘,‘" + keyword + "‘,";
                    sql += "" + content + "‘,‘" + digest + "‘,‘" + path + "‘,‘" + disease + "‘," + auditflag + ")";
                    int i = SQLHelper.OrlExecuteQuery(sql);
                    if (i > 0)
                    {
                        System.Windows.Forms.MessageBox.Show("success!!!");
                        TextIsNull();
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("Erroy!!!");
                    }
                }
                catch (Exception ex)
                {
                    System.Windows.Forms.MessageBox.Show(ex.Message);
                }
                InitData();
            }
    View Code
  4. 在DataGrid中复选框中绑定主建,进行批量删除操作等。(样式设计不同winform或web中涉及,需要样式绑定,参照篇一)
    bubuko.com,布布扣
    //批量删除
            List<int> selectFID = new List<int>();  
    
            private void CheckBox_Click(object sender, RoutedEventArgs e)
            {
                System.Windows.Controls.CheckBox dg = sender as System.Windows.Controls.CheckBox;
                int FID = int.Parse(dg.Tag.ToString());   //获取该行的FID   
                var bl = dg.IsChecked;
                if (bl == true)
                {
                    selectFID.Add(FID);         //如果选中就保存FID   
                }
                else
                {
                    selectFID.Remove(FID);  //如果选中取消就删除里面的FID   
                }  
               
            }
    
            private void btnDelete_Click(object sender, RoutedEventArgs e)
            {
                foreach (int FID in selectFID)
                {
                    string sql = "delete  T_TCM_THESIS where id=" + FID;
                    int i = SQLHelper.OrlExecuteQuery(sql);
                    if (i > 0)
                    {
                        System.Windows.Forms.MessageBox.Show("success!!!");
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("Erroy!!!");
                    }
                    InitData();
                }  
            }
    View Code
  5. 最后完成分页,数据分页在list列表存储时,通过集合的方法传参容易解决,网上相关分页较多,但是连接数据库分页,比较麻烦。本人查找很多资料,最后选择用户控件分页处理(page.xaml)。(用户控件分页已是完整操作,需要直接引用即可,随后粘贴完整代码。)
  • 用户控件前台设计:
    bubuko.com,布布扣
    <UserControl x:Class="OnenoteOCRDemo.page"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 mc:Ignorable="d" >
           <UserControl.Resources>
        <!--每页{0}/共{0}条-->
        <Style x:Key="PageTextBlock1" TargetType="{x:Type TextBlock}">
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="FontSize" Value="13" />
            <Setter Property="FontWeight" Value="Bold" />
            <Setter Property="Foreground" Value="White" />
        </Style>
        <!--首页上一页等-->
        <Style x:Key="PageTextBlock2" TargetType="{x:Type TextBlock}">
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Margin" Value="0,10,0,0" />
            <Setter Property="Width" Value="40" />
            <Setter Property="Height" Value="23" />
            <Setter Property="FontSize" Value="13" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="Foreground" Value="White" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="#FF000000" />
                    <Setter Property="FontWeight" Value="Bold" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <!--中间页数-->
        <Style x:Key="PageTextBlock3" TargetType="{x:Type TextBlock}">
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="Margin" Value="0,10,0,0" />
            <Setter Property="Height" Value="23" />
            <Setter Property="Width" Value="30" />
            <Setter Property="FontSize" Value="10" />
            <Setter Property="Cursor" Value="Hand" />
            <Setter Property="Foreground" Value="White" />
            <Style.Triggers>
                <Trigger Property="IsMouseOver" Value="True">
                    <Setter Property="Foreground" Value="#FF000000" />
                    <Setter Property="FontWeight" Value="Bold" />
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Foreground" Value="#FF000000" />
                    <Setter Property="FontWeight" Value="Bold" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style x:Key="PageTextBox" TargetType="{x:Type TextBox}">
            <Setter Property="Height" Value="25" />
            <Setter Property="Width" Value="40" />
            <Setter Property="BorderBrush" Value="{x:Null}" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="VerticalAlignment" Value="Bottom" />
            <Setter Property="Background">
                <Setter.Value>
                        <ImageBrush ImageSource="/OnenoteOCRDemo;component/Images/Page_TextBack.png" ></ImageBrush>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <Trigger Property="IsReadOnly" Value="True">
                    <Setter Property="Background" Value="White" />
                </Trigger>
            </Style.Triggers>
        </Style>
        <Style x:Key="PageButton" TargetType="{x:Type Button}">
            <Setter Property="Height" Value="25" />
            <Setter Property="Width" Value="30" />
            <Setter Property="Foreground" Value="White" />
            <Setter Property="HorizontalAlignment" Value="Left" />
            <Setter Property="VerticalAlignment" Value="Bottom" />
        </Style>
        </UserControl.Resources>
        <Grid HorizontalAlignment="Left" Height="30" Width="1024">
            <Grid.Background>
                <ImageBrush ImageSource="style\b2.png" Stretch="Fill"/>
            </Grid.Background>
            <Border CornerRadius="3"   BorderBrush="{x:Null}">
              
                <Grid HorizontalAlignment="Stretch" Margin="5 0 5 0"  VerticalAlignment="Top" Width="Auto" Height="30">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="150"/>
                        <ColumnDefinition Width="600*" MinWidth="600"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Name="tbkRecords" Grid.Column="0" Style="{StaticResource PageTextBlock1}" />
                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Column="1">
                        <Grid>
                            <Grid.RowDefinitions >
                                <RowDefinition Height="30"></RowDefinition>
                            </Grid.RowDefinitions>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="50"/>
                                <ColumnDefinition Width="50"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="50"/>
                                <ColumnDefinition Width="50"/>
                                <ColumnDefinition Width="50"/>
                                <ColumnDefinition Width="30"/>
                            </Grid.ColumnDefinitions>
                            <TextBlock Grid.Column="0" Name="btnFirst" Text="首页" IsEnabled="False" Style="{StaticResource PageTextBlock2}" />
                            <TextBlock Grid.Column="1" Name="btnPrev" Text="上一页" IsEnabled="False" Style="{StaticResource PageTextBlock2}" />
                            <Grid Grid.Column="2" Name="grid" >
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="30" ></RowDefinition>
                                </Grid.RowDefinitions>
                            </Grid>
                            <TextBlock Foreground="White" Grid.Column="3" Name="btnNext" Text="下一页" IsEnabled="False" Style="{StaticResource PageTextBlock2}" />
                            <TextBlock Grid.Column="4" Name="btnLast" Text="未页" IsEnabled="False" Style="{StaticResource PageTextBlock2}"/>
                            <TextBox Grid.Column="5" Name="pageGo" MaxLength="6" IsReadOnly="True" Style="{StaticResource PageTextBox}" />
                            <Button Grid.Column="6" Name="btnGo" Content="GO" IsEnabled="False" Style="{StaticResource PageButton}" />
                        </Grid>
                    </StackPanel>
                </Grid>
            </Border>
        </Grid>
    </UserControl>
    View Code

     

  • 用户空间后台源码:
    bubuko.com,布布扣
    namespace OnenoteOCRDemo
    {
        /// <summary>
        /// page.xaml 的交互逻辑
        /// </summary>
        public partial class page : UserControl
        {
            public page()
            {
                InitializeComponent();
                this.Loaded += delegate
                {
                    this.btnFirst.MouseLeftButtonUp += new MouseButtonEventHandler(btnFirst_Click);
                    this.btnPrev.MouseLeftButtonUp += new MouseButtonEventHandler(btnPrev_Click);
                    this.btnNext.MouseLeftButtonUp += new MouseButtonEventHandler(btnNext_Click);
                    this.btnLast.MouseLeftButtonUp += new MouseButtonEventHandler(btnLast_Click);
                    this.btnGo.Click += new RoutedEventHandler(btnGo_Click);
                };
            }
            private DataTable _dt = new DataTable();
            //每页显示多少条
            private int pageNum = 10;
            //当前是第几页
            private int pIndex = 1;
            //对象
            private DataGrid grdList;
            //最大页数
            private int MaxIndex = 1;
            //一共多少条
            private int allNum = 0;
    
            #region 初始化数据
            /// <summary>
            /// 初始化数据
            /// </summary>
            /// <param name="grd"></param>
            /// <param name="dtt"></param>
            /// <param name="Num"></param>
            public void ShowPages(DataGrid grd, DataSet ds, int Num)
            {
                if (ds == null || ds.Tables.Count == 0)
                    return;
                if (ds.Tables[0].Rows.Count == 0)
                    return;
                DataTable dt = ds.Tables[0];
                this._dt = dt.Clone();
                this.grdList = grd;
                this.pageNum = Num;
                this.pIndex = 1;
                foreach (DataRow r in dt.Rows)
                    this._dt.ImportRow(r);
                SetMaxIndex();
                ReadDataTable();
                if (this.MaxIndex > 1)
                {
                    this.pageGo.IsReadOnly = false;
                    this.btnGo.IsEnabled = true;
                }
            }
            #endregion
    
            #region 画数据
            /// <summary>
            /// 画数据
            /// </summary>
            private void ReadDataTable()
            {
                try
                {
                    DataTable tmpTable = new DataTable();
                    tmpTable = this._dt.Clone();
                    int first = this.pageNum * (this.pIndex - 1);
                    first = (first > 0) ? first : 0;
                    //如何总数量大于每页显示数量
                    if (this._dt.Rows.Count >= this.pageNum * this.pIndex)
                    {
                        for (int i = first; i < pageNum * this.pIndex; i++)
                            tmpTable.ImportRow(this._dt.Rows[i]);
                    }
                    else
                    {
                        for (int i = first; i < this._dt.Rows.Count; i++)
                            tmpTable.ImportRow(this._dt.Rows[i]);
                    }
                    this.grdList.ItemsSource = tmpTable.DefaultView;
                    tmpTable.Dispose();
                }
                catch
                {
                    MessageBox.Show("错误");
                }
                finally
                {
                    DisplayPagingInfo();
                }
    
            }
            #endregion
    
            #region 画每页显示等数据
            /// <summary>
            /// 画每页显示等数据
            /// </summary>
            private void DisplayPagingInfo()
            {
                if (this.pIndex == 1)
                {
                    this.btnPrev.IsEnabled = false;
                    this.btnFirst.IsEnabled = false;
                }
                else
                {
                    this.btnPrev.IsEnabled = true;
                    this.btnFirst.IsEnabled = true;
                }
                if (this.pIndex == this.MaxIndex)
                {
                    this.btnNext.IsEnabled = false;
                    this.btnLast.IsEnabled = false;
                }
                else
                {
                    this.btnNext.IsEnabled = true;
                    this.btnLast.IsEnabled = true;
                }
                this.tbkRecords.Text = string.Format("每页{0}条/共{1}条", this.pageNum, this.allNum);
                int first = (this.pIndex - 4) > 0 ? (this.pIndex - 4) : 1;
                int last = (first + 9) > this.MaxIndex ? this.MaxIndex : (first + 9);
                this.grid.Children.Clear();
                for (int i = first; i <= last; i++)
                {
                    ColumnDefinition cdf = new ColumnDefinition();
                    this.grid.ColumnDefinitions.Add(cdf);
                    TextBlock tbl = new TextBlock();
                    tbl.Text = i.ToString();
                    tbl.Style = FindResource("PageTextBlock3") as Style;
                    tbl.MouseLeftButtonUp += new MouseButtonEventHandler(tbl_MouseLeftButtonUp);
                    if (i == this.pIndex)
                        tbl.IsEnabled = false;
                    Grid.SetColumn(tbl, this.grid.ColumnDefinitions.Count - 1);
                    Grid.SetRow(tbl, 0);
                    this.grid.Children.Add(tbl);
                }
            }
            #endregion
    
            #region 首页
            /// <summary>
            /// 首页
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnFirst_Click(object sender, System.EventArgs e)
            {
                this.pIndex = 1;
                ReadDataTable();
            }
            #endregion
    
            #region 上一页
            /// <summary>
            /// 上一页
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnPrev_Click(object sender, System.EventArgs e)
            {
                if (this.pIndex <= 1)
                    return;
                this.pIndex--;
                ReadDataTable();
            }
            #endregion
    
            #region 下一页
            /// <summary>
            /// 下一页
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnNext_Click(object sender, System.EventArgs e)
            {
                if (this.pIndex >= this.MaxIndex)
                    return;
                this.pIndex++;
                ReadDataTable();
            }
            #endregion
    
            #region 未页
            /// <summary>
            /// 未页
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnLast_Click(object sender, System.EventArgs e)
            {
                this.pIndex = this.MaxIndex;
                ReadDataTable();
            }
            #endregion
    
            #region 设置最多大页面
            /// <summary>
            /// 设置最多大页面
            /// </summary>
            private void SetMaxIndex()
            {
                //多少页
                int Pages = this._dt.Rows.Count / pageNum;
                if (this._dt.Rows.Count != (Pages * pageNum))
                {
                    if (_dt.Rows.Count < (Pages * pageNum))
                        Pages--;
                    else
                        Pages++;
                }
                this.MaxIndex = Pages;
                this.allNum = this._dt.Rows.Count;
            }
            #endregion
    
            #region 跳转到多少页
            /// <summary>
            /// 跳转到多少页
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnGo_Click(object sender, RoutedEventArgs e)
            {
                if (IsNumber(this.pageGo.Text))
                {
                    int pageNum = int.Parse(this.pageGo.Text);
                    if (pageNum > 0 && pageNum <= this.MaxIndex)
                    {
                        this.pIndex = pageNum;
                        ReadDataTable();
                    }
                    else if (pageNum > this.MaxIndex)
                    {
                        this.pIndex = this.MaxIndex;
                        ReadDataTable();
                    }
                }
                this.pageGo.Text = "";
            }
            #endregion
    
            private void tbl_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
                TextBlock tbl = sender as TextBlock;
                if (tbl == null)
                    return;
                int index = int.Parse(tbl.Text.ToString());
                this.pIndex = index;
                if (index > this.MaxIndex)
                    this.pIndex = this.MaxIndex;
                if (index < 1)
                    this.pIndex = 1;
                ReadDataTable();
            }
    
            private static Regex RegNumber = new Regex("^[0-9]+$");
    
    
            #region 判断是否是数字
            /// <summary>
            /// 判断是否是数字
            /// </summary>
            /// <param name="valString"></param>
            /// <returns></returns>
            public static bool IsNumber(string valString)
            {
                Match m = RegNumber.Match(valString);
                return m.Success;
            }
            #endregion
        }
    }
    View Code

    完成以上操作,然后再mian.xaml需要引用用户页面添加如下代码:在window中xmlns:my="clr-namespace:OnenoteOCRDemo"和在grid中<my:page  x:Name="page1" Height="30" VerticalAlignment="Top"></my:page>


【所遇问题以及瓶颈突破】

  1. 使用 64位 win8 /win7系统+64位 oracle+PL/SQL处理,如果是32位较流畅,只是64位系统中不支持64位PL/SQL,需要下载32位PL/SQL做置。 
    注:问题详解参照http://blog.sina.com.cn/s/blog_475839a50101hoyg.html即可。

     

  2. oracle设计表时候如何才能像sql server那样直接配置主键种子自增?其通过创建序列,然后通过触发器实现。                                                                      
    bubuko.com,布布扣
    /*创建数据库表*/
    create table T_TCM_THESIS  (
       ID                   NUMBER                          not null,
       DOCNAME              VARCHAR2(512),
       YEARS                VARCHAR2(128),
       DOCTYPE              VARCHAR2(128),
       SUMMARY              VARCHAR2(4000),
       AUTHOR               VARCHAR2(128),
       SOURCE               VARCHAR2(2048),
       SOURCETYPE           VARCHAR2(128),
       MEMO                 VARCHAR2(1024),
       TITLE                VARCHAR2(512),
       ENGLISHTITLE         VARCHAR2(512),
       AUTHORCOMPANY        VARCHAR2(512),
       KEYWORD              VARCHAR2(512),
       CONTENT              CLOB,
       DIGEST               VARCHAR2(4000),
       PATH                 VARCHAR2(256),
       DISEASE              VARCHAR2(256),
       AUDITFLAG            NUMBER(1),
       constraint PK_TZJ_PINTOOL_THESIS primary key (ID)
    );
    /*字段的注解*/
    comment on table T_TCM_THESIS is
    中医文献表;
    
    comment on column T_TCM_THESIS.ID is
    编号;
    
    comment on column T_TCM_THESIS.DOCNAME is
    文献名;
    
    comment on column T_TCM_THESIS.YEARS is
    年代;
    
    comment on column T_TCM_THESIS.DOCTYPE is
    文献类型;
    
    comment on column T_TCM_THESIS.SUMMARY is
    内容提要;
    
    comment on column T_TCM_THESIS.AUTHOR is
    作者;
    
    comment on column T_TCM_THESIS.SOURCE is
    文献出处;
    
    comment on column T_TCM_THESIS.SOURCETYPE is
    文献出处类型;
    
    comment on column T_TCM_THESIS.MEMO is
    备注;
    
    comment on column T_TCM_THESIS.TITLE is
    标题;
    
    comment on column T_TCM_THESIS.ENGLISHTITLE is
    英文标题;
    
    comment on column T_TCM_THESIS.AUTHORCOMPANY is
    著者单位;
    
    comment on column T_TCM_THESIS.KEYWORD is
    关键词;
    
    comment on column T_TCM_THESIS.CONTENT is
    文献内容;
    
    comment on column T_TCM_THESIS.DIGEST is
    摘要;
    
    comment on column T_TCM_THESIS.PATH is
    文献内容文本文件;
    
    comment on column T_TCM_THESIS.DISEASE is
    相关病名;
    
    
    comment on column T_TCM_THESIS.AUDITFLAG is
    是否审核;
    select * from T_TCM_THESIS;
    --------------------------------------------------------------------------------------------------------
    /*以下代码完成自增*/
    ---------------------------------------------------------------------------------------------------------
    /*创建序列*/
    
    CREATE SEQUENCE EMP_SEQUENCE
      INCREMENT BY 1               -- 每次加几个
      START WITH 1                 -- 从1开始计数
      NOMAXVALUE                   -- 不设置最大值
      NOCYCLE                      -- 一直累加,不循环
      NOCACHE                      -- 不建缓冲区
    /*创建触发器*/
     create or replace trigger   TR_EXA  
     before insert on  T_TCM_THESIS for each row             
     begin   
      select   to_char(EMP_SEQUENCE.nextval)   into   :new.id  from   dual;   
     end   TR_EXA;  
    
    /*插入数据,表中18字段,插入时只需填写17字段。主键ID自增*/
    INSERT INTO T_TCM_THESIS(docname,years,doctype,summary,author,source,sourcetype,memo,title,englishtitle,authorcompany,keyword,content,digest,path,disease,auditflag) 
    Values(aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,1);
    /*查询*/
    select * from T_TCM_THESIS;
    View Code

     

  3. 在VS中完成数据库连接时候,需要引用oracle的dll组件(32/64)。

      

    注:首先下载System.Data.OracleClient.zip,解压后有X64/X86文件夹区别,针对自己情况不同做以选择。然后打开X64/X86文件夹选择对应的dll组件放在C盘window下,
    然后打开项目-〉引用->浏览->选择确定即可。

                                                                                                              

  4. 如何使用分页操作?
    注:wpf之前所做小程序,数据大多放在xml等小型数据库,通过操作list集合调用其方面传参(每页显示,总条数)等完成分页,这样方案网上很多。但是通过连接数据库去处理较为麻烦
    ,我找了很多资料,比较分析后发现利用用户控件完成分页,一则调用方面不用任何修改,二则便于操作,功能完善。(代码参照上面功能以及操作描述)

                                                                                                                                                                          


【核心功能梳理和总结】

  • 用户控件的创建与使用?
  • 注:1,打开项目-〉添加-〉新建项-〉用户控件-〉引用页面中添加xmlns:my="clr-namespace:新建项项目名称"-〉在grid中<my:新建项名称  x:Name="page1" Height="30" VerticalAlignment="Top"></my:page>
  • 如何设置表头内容值?
  • 注:
            void MainWindow_Loaded(object sender, RoutedEventArgs e)
            {
                this.Loaded += delegate
                {
                    InitData();
                };
                dataGrid1.LoadingRow += new EventHandler<DataGridRowEventArgs>(dataGrid1_LoadingRow);
            }
            void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e)
            {
                e.Row.Header = e.Row.GetIndex() + 1;    //设置行表头的内容值   
            }

     

  • SQLHelper类的使用,以及完整代码?
  • 注:这个类可以实现oracle数据库连接和server数据库连接,也可以完成参数化sql文本或者存储过程。很好用,平常自己做项目大多使用此类。
    bubuko.com,布布扣
    namespace MYHelper
    {
        //不加public,只有dal私有引用;
        //封装执行sql server增删改查辅助类,提供相应执行sql语句和存储过程的方法
        static class SQLHelper
        {
            //读取配置文件中的连接字符串
           // static string connstr = ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
            static string connstr = "data source=ORCL;User Id=system;Password=orcl";
            public static DataSet GetOrlData(string sql)
            {
                DataSet ds = new DataSet();
                using (OracleConnection conn = new OracleConnection(connstr))
                {
                    using (OracleCommand cmd = new OracleCommand(sql, conn))
                    {
                        //根据传来的参数。决定是sql语句还是存储过程
                        //cmd.CommandType = CommandType.StoredProcedure;
                        conn.Open();
                        using (OracleDataAdapter sda = new OracleDataAdapter(cmd))
                        {
                            sda.Fill(ds);
                        }
                    }
                }
                return ds;
            }
    
            public static int OrlExecuteQuery(string sql)
            {
                int res = -1;
                using (OracleConnection conn = new OracleConnection(connstr))
                {
                    using (OracleCommand cmd = new OracleCommand(sql, conn))
                    {
                        conn.Open();
                        res = cmd.ExecuteNonQuery();
                    }
                }
                return res;
            }
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
            /// <summary>
            /// 执行非查询sql语句,返回受影响行数,如果执行非增删改则返回-1
            /// </summary>
            /// <param name="sql">sql语句</param>
            /// <param name="paras">参数数组</param>
            /// <returns>影响行数res</returns>
            public static int ExecuteNonQuery(string sql, params SqlParameter[] paras)
            {
                int res = -1;
                using (SqlConnection conn = new SqlConnection(connstr))
                {
                    using (SqlCommand cmd = new SqlCommand(sql, conn))
                    {
                        cmd.CommandType = CommandType.StoredProcedure;
                        if (paras != null || paras.Length > 0)
                        {
                            cmd.Parameters.AddRange(paras);
                        }
                        conn.Open();
                        res = cmd.ExecuteNonQuery();
                    }
                }
                return res;
            }
    
             public static int ExecuteNonParaQuery(string sql)
             {
                 int res = -1;
                 using (SqlConnection conn = new SqlConnection(connstr))
                 {
                     using (SqlCommand cmd = new SqlCommand(sql, conn))
                     {
                         conn.Open();
                         res = cmd.ExecuteNonQuery();
                     }
                 }
                 return res;
             }
             /// <summary>
             /// 执行读取数据,返回一个对象
             /// </summary>
             /// <param name="sql">sql语句</param>
             /// <param name="paras">参数数组</param>
             /// <returns>返回一个对象o</returns>
             public static object ExecuteScalar(string sql, params SqlParameter[] paras)
             {
                 object  o = null;
                 using (SqlConnection conn = new SqlConnection(connstr))
                 {
                     using (SqlCommand cmd = new SqlCommand(sql, conn))
                     {
                         cmd.CommandType = CommandType.StoredProcedure;
                         if (paras != null)
                         {
                             cmd.Parameters.AddRange(paras);
                         }
                         conn.Open();
                         o = cmd.ExecuteScalar();
                     }
                 }
                 return o;
             }
             /// <summary>
             /// 执行查询sql语句,返回一个对象
             /// </summary>
             /// <param name="sql">sql语句</param>
             /// <param name="paras">查询参数</param>
             /// <returns>返回DataReader对象</returns>
             public static SqlDataReader ExecuteReader(string sql, params SqlParameter[] paras)
             {
                 SqlConnection conn = new SqlConnection(connstr);
                 using (SqlCommand cmd = new SqlCommand(sql, conn))
                 {
                     cmd.CommandType = CommandType.StoredProcedure;
                     if (paras != null)
                     {
                         cmd.Parameters.AddRange(paras);
                     }
                     conn.Open();
                     try
                     {
                         return cmd.ExecuteReader(CommandBehavior.CloseConnection);
                     }
                     catch (Exception ex)
                     {
                         cmd.Dispose();
                         throw ex;
                     }
                 }
             }
    
             /// <summary>
             /// 执行查询sql语句,返回一个无参数dataset对象
             /// </summary>
             /// <param name="sql">sql语句</param>
             /// <param name="paras"></param>
             /// <returns>返回dataset 对象</returns>
             public static DataSet GetDataSetNotPara(string sql)
             {
                 DataSet ds = new DataSet();
                 using (SqlConnection conn = new SqlConnection(connstr))
                 {
                     using (SqlCommand cmd = new SqlCommand(sql, conn))
                     {
                         //根据传来的参数。决定是sql语句还是存储过程
                         cmd.CommandType = CommandType.StoredProcedure;
                         conn.Open();
                         using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                         {
                             sda.Fill(ds);
                         }
                     }
                 }
                 return ds;
             }
             /// <summary>
             /// 执行查询sql语句,返回一个无参数dataset对象
             /// </summary>
             /// <param name="sql">sql语句</param>
             /// <param name="paras"></param>
             /// <returns>返回dataset 对象</returns>
             public static DataTable  GetDataTableNotPara(string sql)
             {
                 DataTable dt = new DataTable();
                 using (SqlConnection conn = new SqlConnection(connstr))
                 {
                     using (SqlCommand cmd = new SqlCommand(sql, conn))
                     {
                         //根据传来的参数。决定是sql语句还是存储过程
                      
                         conn.Open();
                         using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                         {
                             sda.Fill(dt);
                         }
                     }
                 }
                 return dt;
             }
    
             /// <summary>
             /// 执行查询sql语句,返回一个dataset对象
             /// </summary>
             /// <param name="sql">sql语句</param>
             /// <param name="paras">查询参数</param>
             /// <returns>返回dataset 对象</returns>
             public static DataSet GetDataSet(string sql, params SqlParameter[] paras)
             {
                 DataSet  ds = new DataSet();
                 using (SqlConnection conn = new SqlConnection(connstr))
                 {
                     using (SqlCommand cmd = new SqlCommand(sql, conn))
                     {
                         //根据传来的参数。决定是sql语句还是存储过程
                         cmd.CommandType = CommandType.StoredProcedure;
                         //添加参数
                         cmd.Parameters.AddRange(paras);
                         conn.Open();
                         using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                         {
                             sda.Fill(ds);
                         }
                     }
                 }
                 return ds;
             }
             /// <summary>
             /// 可以执行sql语句或存储过程
             /// </summary>
             /// <param name="text"></param>
             /// <param name="ct"></param>
             /// <param name="param"></param>
             /// <returns></returns>
             public static DataTable ProcGetTable(string sql, params SqlParameter[] param)
             {
                 DataTable dt = new DataTable();
    
                 using (SqlConnection conn = new SqlConnection(connstr))
                 {
                     using (SqlCommand cmd = new SqlCommand(sql, conn))
                     {
                         //根据传来的参数。决定是sql语句还是存储过程
                         
                         cmd.CommandType = CommandType.StoredProcedure;
                         //添加参数
                         cmd.Parameters.AddRange(param);
                         //cmd.Parameters.Add("@name", SqlDbType.NVarChar, 20).Value = param[0];
                         //cmd.Parameters.Add("@pwd", SqlDbType.NVarChar, 20).Value = param[1];
                         conn.Open();
                         using (SqlDataAdapter sda = new SqlDataAdapter(cmd))
                         {
                             sda.Fill(dt);
                         }
                     }
                 }
                 return dt;
             }
            
             /// <summary>
             /// 实现分页功能
             /// </summary>
             /// <param name="sql">sql语句</param>
             /// <param name="paras">参数数组(显示index页和每页显示条数size)</param>
             /// <returns>查询结果</returns>
             public static DataTable GetParaTable(string sql, params SqlParameter[] paras)
             {
                 DataSet ds = new DataSet();
                 using (SqlConnection conn = new SqlConnection(connstr))
                 {
                     using (SqlDataAdapter da = new SqlDataAdapter(sql, conn))
                     {
                         if (paras != null)
                         {
                             da.SelectCommand.Parameters.AddRange(paras);
                         }
                         da.SelectCommand.CommandType = CommandType.StoredProcedure;
                         da.Fill(ds);
                     }
                 }
                 return ds.Tables[0];
             }
        }
    }
    View Code

     

  • 如何选择文本入库?
  • 注:通过操作文件,浏览文件选择目标文件,确定后通过流写入文本框中,另外对目标流文件进行正则表达式处理,自动筛选出需要数据
    bubuko.com,布布扣
            //选择入库文本
            private void bnt_Click(object sender, RoutedEventArgs e)
            {
                txtcontent.Text = "";
                openData1();
            }
            //入库文本操作
            public void openData1()
            {
                OpenFileDialog ofd = new OpenFileDialog();
                ofd.Title = "打开(Open)";
                ofd.FileName = "";
                //为了获取特定的系统文件夹,可以使用System.Environment类的静态方法GetFolderPath()。
                //该方法接受一个Environment.SpecialFolder枚举,其中可以定义要返回路径的哪个系统目录
                ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
                ofd.Filter = "文本文件(*.txt)|*.txt";
                ofd.ValidateNames = true;     //文件有效性验证ValidateNames,验证用户输入是否是一个有效的Windows文件名
                ofd.CheckFileExists = true;  //验证路径有效性
                ofd.CheckPathExists = true; //验证文件有效性
                try
                {
                    if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                    {
                        StreamReader sr = new StreamReader(ofd.FileName, System.Text.Encoding.Default);
                        txtcontent.Text += sr.ReadToEnd();
                        sr.Close();
                        //指定截取书名
                        string str_start = @"书名:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex = new Regex(str_start, RegexOptions.Multiline);
                        string a = txtcontent.Text;
                        Match MyMatch = MyRegex.Match(a);
                        txttitle.Text=txtdocname.Text = MyMatch.Groups["info"].Value.ToString();
                        //指定截取作者
                        string str_start1 = @"作者:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex1 = new Regex(str_start1, RegexOptions.Multiline);
                        string b = txtcontent.Text;
                        Match MyMatch1 = MyRegex1.Match(b);
                        txtauthor.Text = MyMatch1.Groups["info"].Value.ToString();
                        //指定截取朝代
                        string str_start2 = @"朝代:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex2 = new Regex(str_start2, RegexOptions.Multiline);
                        string c = txtcontent.Text;
                        Match MyMatch2 = MyRegex2.Match(c);
                        txtyears.Text = MyMatch2.Groups["info"].Value.ToString();
                    }
                }
                catch (Exception)
                {
                    System.Windows.Forms.MessageBox.Show("读取文件失败,请检查文件格式!");
                }
            }
    View Code

     

  • 如何截取指定文本中的字段?
  •  注:
    bubuko.com,布布扣
                        StreamReader sr = new StreamReader(ofd.FileName, System.Text.Encoding.Default);
                        txtcontent.Text += sr.ReadToEnd();
                        sr.Close();
                        //指定截取书名
                        string str_start = @"书名:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex = new Regex(str_start, RegexOptions.Multiline);
                        string a = txtcontent.Text;
                        Match MyMatch = MyRegex.Match(a);
                        txttitle.Text=txtdocname.Text = MyMatch.Groups["info"].Value.ToString();
                        //指定截取作者
                        string str_start1 = @"作者:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex1 = new Regex(str_start1, RegexOptions.Multiline);
                        string b = txtcontent.Text;
                        Match MyMatch1 = MyRegex1.Match(b);
                        txtauthor.Text = MyMatch1.Groups["info"].Value.ToString();
                        //指定截取朝代
                        string str_start2 = @"朝代:(?<info>\w[^。|,^.|^,|^:|^:]+)";//可剔除后边的中英文逗号,句号等
                        Regex MyRegex2 = new Regex(str_start2, RegexOptions.Multiline);
                        string c = txtcontent.Text;
                        Match MyMatch2 = MyRegex2.Match(c);
                        txtyears.Text = MyMatch2.Groups["info"].Value.ToString();
    View Code

     

  • 如何实现批量删除?
  •  注:利用CheckBox绑定主键,操作其遍历是否被选中,然后通过删除按钮进行批量删除。
    bubuko.com,布布扣
           //批量删除
            List<int> selectFID = new List<int>();  
    
            private void CheckBox_Click(object sender, RoutedEventArgs e)
            {
                System.Windows.Controls.CheckBox dg = sender as System.Windows.Controls.CheckBox;
                int FID = int.Parse(dg.Tag.ToString());   //获取该行的FID   
                var bl = dg.IsChecked;
                if (bl == true)
                {
                    selectFID.Add(FID);         //如果选中就保存FID   
                }
                else
                {
                    selectFID.Remove(FID);  //如果选中取消就删除里面的FID   
                }  
               
            }
    
            private void btnDelete_Click(object sender, RoutedEventArgs e)
            {
                foreach (int FID in selectFID)
                {
                    string sql = "delete  T_TCM_THESIS where id=" + FID;
                    int i = SQLHelper.OrlExecuteQuery(sql);
                    if (i > 0)
                    {
                        System.Windows.Forms.MessageBox.Show("success!!!");
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("Erroy!!!");
                    }
                    InitData();
                }  
            }
    View Code

     


 【篇末】:程序中使用oracle数据库的设计,序列创建,触发器创建,对目标文件处理,正则表达式运用,wpf分页,以及DataGrid数据绑定,批量删除,模版使用等技术,整合完成文件入库操作。后面对此功能所用核心知识点做以梳理总结。下面最后环节,就是对整个项目测试和页面最终修订,然后对审核页面设计和性能提升。最后会附近本项目完整源码。

 

 

 

注:项目完整结束,测试无误,源程序再做上传!!!

 

【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇三:批量处理后的txt文件入库处理,布布扣,bubuko.com

【基于WPF+OneNote+Oracle的中文图片识别系统阶段总结】之篇三:批量处理后的txt文件入库处理

标签:des   winform   style   blog   http   color   使用   os   

原文地址:http://www.cnblogs.com/baiboy/p/wpf2.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!