DB数据导出工具分享
一个根据数据库链接字符串,sql语句 即可将结果集导出到Excel的工具 分享,支持sqlserver,mysql。
前因
一个月前朋友找到我,让我帮忙做一个根据sql导出查询结果到Excel的工具(之前帮他一个导入Excel然后按其规则统计数据的工具)。
然后扔了我一个SQL语句,瞬间懵比。卧槽。这么多列,我特么得定义这么属性,改了还得重新改程序(一直用EF)。
于是思考如何忽略列名,进而如何做到通用,做到于我有益,而不是简单的帮个忙。
如何完成这个需求
Q:程序中根据SQL查询出数据而不需要关注有哪些列?
A:将查询结果保存到DataTable中然后遍历
Q:如何将DataTable转换Excel?
A:一搜,一试,可用之
Q:如何保存到本地?
A:待我改改写日志的方法
使用SqlSugar 4.x 进行数据操作
SqlSugar 4.x是一款高性能(达到ADO.NET最高性能水平)、轻量级、支持多库和人性化语法的ORM,语法方便,入门简单,功能强大。
对数据库结构没太多要求,支持多主键,多自增列
SqlSugar支持sqlserver,mysql故此工具适用于此两者数据库
0. 创建项目-预览

1. 到github仓库clone了源码至本地生成需要的dll,然后在项目中添加了引用


2. 使用SqlSugar获取结果到DataTable中(不知道是不是最近帮朋友写ado.net的代码写多了,感觉挺好)

3. DataTable转Excel
public class DataTableToExcel
{
    private DataTableToExcel()
    { }
    private static DataTableToExcel _instance = null;
    public static DataTableToExcel Instance
    {
        get
        {
            if (_instance == null) _instance = new DataTableToExcel();
            return _instance;
        }
    }
    /// <summary>
    /// DataTable通过流导出Excel
    /// </summary>
    /// <param name="ds">数据源DataSet</param>
    /// <param name="columns">DataTable中列对应的列名(可以是中文),若为null则取DataTable中的字段名</param>
    /// <param name="fileName">保存文件名(例如:a.xls)</param>
    /// <returns></returns>
    public string StreamExport(DataTable dt, string[] columns = null,string savePath="")
    {
        //if (dt.Rows.Count > 65535) //总行数大于Excel的行数
        //{
        //    throw new Exception("预导出的数据总行数大于excel的行数");
        //}
        StringBuilder content = new StringBuilder();
        content.Append("<html xmlns:o='urn:schemas-microsoft-com:office:office' xmlns:x='urn:schemas-microsoft-com:office:excel' xmlns='http://www.w3.org/TR/REC-html40'>");
        content.Append("<head><title></title><meta http-equiv='Content-Type' content=\"text/html; charset=gb2312\">");
        //注意:[if gte mso 9]到[endif]之间的代码,用于显示Excel的网格线,若不想显示Excel的网格线,可以去掉此代码
        content.Append("<!--[if gte mso 9]>");
        content.Append("<xml>");
        content.Append(" <x:ExcelWorkbook>");
        content.Append("  <x:ExcelWorksheets>");
        content.Append("   <x:ExcelWorksheet>");
        content.Append("    <x:Name>Sheet1</x:Name>");
        content.Append("    <x:WorksheetOptions>");
        content.Append("      <x:Print>");
        content.Append("       <x:ValidPrinterInfo />");
        content.Append("      </x:Print>");
        content.Append("    </x:WorksheetOptions>");
        content.Append("   </x:ExcelWorksheet>");
        content.Append("  </x:ExcelWorksheets>");
        content.Append("</x:ExcelWorkbook>");
        content.Append("</xml>");
        content.Append("<![endif]-->");
        content.Append("</head><body><table style='border-collapse:collapse;table-layout:fixed;'><tr>");
        if (columns != null)
        {
            for (int i = 0; i < columns.Length; i++)
            {
                if (columns[i] != null && columns[i] != "")
                {
                    content.Append("<td><b>" + columns[i] + "</b></td>");
                }
                else
                {
                    content.Append("<td><b>" + dt.Columns[i].ColumnName + "</b></td>");
                }
            }
        }
        else
        {
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                content.Append("<td><b>" + dt.Columns[j].ColumnName + "</b></td>");
            }
        }
        content.Append("</tr>\n");
        for (int j = 0; j < dt.Rows.Count; j++)
        {
            content.Append("<tr>");
            for (int k = 0; k < dt.Columns.Count; k++)
            {
                object obj = dt.Rows[j][k];
                Type type = obj.GetType();
                if (type.Name == "Int32" || type.Name == "Single" || type.Name == "Double" || type.Name == "Decimal")
                {
                    double d = obj == DBNull.Value ? 0.0d : Convert.ToDouble(obj);
                    if (type.Name == "Int32" || (d - Math.Truncate(d) == 0))
                        content.AppendFormat("<td style='vnd.ms-excel.numberformat:#,##0'>{0}</td>", obj);
                    else
                        content.AppendFormat("<td style='vnd.ms-excel.numberformat:#,##0.00'>{0}</td>", obj);
                }
                else
                    content.AppendFormat("<td style='vnd.ms-excel.numberformat:@'>{0}</td>", obj);
            }
            content.Append("</tr>\n");
        }
        content.Append("</table></body></html>");
        content.Replace(" ", "");
        using (var w = new StreamWriter(savePath, false, Encoding.UTF8))
        {
            w.WriteLine(content);
        }
        return savePath;
    }
}
4. 使用Ini文件保存输入
public class IniHelper
{
    // 声明INI文件的写操作函数 WritePrivateProfileString()
    [System.Runtime.InteropServices.DllImport("kernel32")]
    private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);
    // 声明INI文件的读操作函数 GetPrivateProfileString()
    [System.Runtime.InteropServices.DllImport("kernel32")]
    private static extern int GetPrivateProfileString(string section, string key, string def, System.Text.StringBuilder retVal, int size, string filePath);
    private int retLength = 500;
    private string sPath = null;
    public IniHelper(string path, int rl = 500)
    {
        this.sPath = path;
        if (rl > 0)
        {
            this.retLength = rl;
        }
    }
    public void WriteValue(string key, string value, string section = "Setting")
    {
        // section=配置节,key=键名,value=键值,path=路径
        WritePrivateProfileString(section, key, value, sPath);
    }
    public string ReadValue(string key, string section = "Setting")
    {
        // 每次从ini中读取多少字节
        System.Text.StringBuilder temp = new System.Text.StringBuilder(retLength);
        // section=配置节,key=键名,temp=上面,path=路径
        GetPrivateProfileString(section, key, "", temp, retLength, sPath);
        return temp.ToString();
    }
}
5. 文本框全选功能
    public frmMain()
    {
        this.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded); //注册全选功能
        InitializeComponent();
    }
    #region 文本框能够使用Ctrl+A 全选功能
    private void Control_ControlAdded(object sender, ControlEventArgs e)
    {
        //使“未来”生效
        e.Control.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.Control_ControlAdded);
        //使“子孙”生效
        foreach (Control c in e.Control.Controls)
        {
            Control_ControlAdded(sender, new ControlEventArgs(c));
        }
        //使“过去”生效
        TextBox textBox = e.Control as TextBox;
        if (textBox != null)
        {
            textBox.KeyPress += TextBox_KeyPress;
        }
    }
    private void TextBox_KeyPress(object sender, KeyPressEventArgs e)
    {
        TextBox textBox = sender as TextBox;
        if (textBox == null)
            return;
        if (e.KeyChar == (char)1)
        {
            textBox.SelectAll();
            e.Handled = true;
        }
    }
    #endregion
6. 打开保存的excel
    private void btnOpenDir_Click(object sender, EventArgs e)
    {
        var txtFileName = this.txtFileName.Text;
        var txtExportDir = this.txtExportDir.Text;
        var openPath = Path.Combine(txtExportDir, txtFileName);
        if (File.Exists(openPath))
        {
            System.Diagnostics.Process.Start(openPath, "c:\\windows");
        }
        else
        {
            AppendTipMsg("文件" + openPath + "不存在");
        }
    }
7. 页面主要功能代码

winform中使用多线程时给ui控件赋值
var txtThread = new Thread(() => txtMsg.BeginInvoke(new Action(() => txtMsg.AppendText("向文本框中追加内容"))));
txtThread.Start();
8. 一些记录
winform中使用多线程时给ui控件赋值
var txtThread = new Thread(() => txtMsg.BeginInvoke(new Action(() => txtMsg.AppendText("向文本框中追加内容"))));
txtThread.Start();
源码中的NopI组件可移除,此工具实际未用到
开启线程执行导出的时候使用的是Task.Run(() =>{});若将框架版本改为4.0则需要将此处修改为new Thread(() =>{}).Start();
整个过程解决了一下问题
- 数据库查询(SqlSugar支持sqlserver,mysql)
 - datatable转excel文本
 - ini存取文件
 - winform文本框全选功能
 - winform中使用多线程时给ui控件赋值
 
源码
下载使用:http://files.cnblogs.com/files/morang/DB数据导出工具.rar
源码下载:http://files.cnblogs.com/files/morang/DB数据导出工具_源码.rar
Coding地址:https://coding.net/u/yimocoding/p/WeDemo/git/tree/NopiExcelDemo
git克隆:git clone https://git.coding.net/yimocoding/WeDemo.git -b NopiExcelDemo
使用说明


DB数据导出工具分享的更多相关文章
- oracle数据导出工具sqluldr2
		
oracle数据导出工具sqluldr2可以将数据以csv.txt等格式导出,适用于大批量数据的导出,导出速度非常快.导出后可以使用oracle loader工具将数据导入.下载完sqluldr2,工 ...
 - python打造漏洞数据导出工具
		
功能 [x] 支持导出的数据:IP地址.漏洞名称.风险等级.整改建议.漏洞描述.漏洞CVE编号.漏洞对应端口.漏洞对应协议.漏洞对应服务等. [x] 导出不同端口的同一个漏洞,也就是一个端口对应一个漏 ...
 - Mongodb数据导出工具mongoexport和导入工具mongoimport介绍
		
一.导出工具mongoexport Mongodb中的mongoexport工具可以把一个collection导出成JSON格式或CSV格式的文件.可以通过参数指定导出的数据项,也可以根据指定的条件导 ...
 - Mongodb数据导出工具mongoexport和导入工具mongoimport介绍(转)
		
原文地址:http://chenzhou123520.iteye.com/blog/1641319 一.导出工具mongoexport Mongodb中的mongoexport工具可以把一个colle ...
 - Mongodb数据导出工具mongoexport和导入工具mongoimport使用
		
如图所示,两个工具位于mongodb安装目录的bin目录下 下面介绍一下两者的使用方法: 一.导出工具mongoexport Mongodb中的mongoexport工具可以把一个collection ...
 - 很多人都没用过的轻量级Oracle数据库数据导出工具SQLLDR2——性能超赞
		
SQLLDR2 介绍 每周发表一篇数据库或大数据相关的帖子,敬请关注 1. 工具介绍 Sqluldr2(SQL * UnLoader 第二版)是灵活与强大的 Oracle 文本导出程序,已被大众使 用 ...
 - MySQL--mysqldump(数据导出工具)
		
mysqldump 客户端工具用来备份数据库或在不同数据库之间进行数据迁移.备份内容包含创建表或装载表的 SQL 语句.mysqldump 目前是 MySQL 中最常用的备份工具. 有 3 种方式来调 ...
 - mysql 开发进阶篇系列 35 工具篇 mysqldump(数据导出工具)
		
一.概述 mysqldump客户端工具是用来备份数据库或在不同数据库之间进行数据迁移.备份内容包含创建表或装载表的sql语句.mysqldump目前是mysql中最常用的备份工具. 三种方式来调用my ...
 - SequoiaDB版本升级及导入导出工具说明
		
升级SequoiaDB数据库指导 SequoiaDB安装路径:SDB_HOME=/opt/sequoiadb 数据存储路径:DATABASE=/ opt/sequoiadb/database 一.导出 ...
 
随机推荐
- C语言之强化,弱化符号weak
			
一.概述 在C语言中,函数和初始化的全局变量(包括显示初始化为0)是强符号,未初始化的全局变量是弱符号. 对于它们,下列三条规则使用: ① 同名的强符号只能有一个,否则编译器报"重复定义&q ...
 - 读《Java并发编程的艺术》(二)
			
上篇博客开始,我们接触了一些有关Java多线程的基本概念.这篇博客开始,我们就正式的进入了Java多线程的实战演练了.实战演练不仅仅是贴代码,也会涉及到相关概念和术语的讲解. 线程的状态 程的状态分为 ...
 - 关于ubuntu的图标创建以及快捷方式打开
			
//这里个人要添加的的为微信小程序开发工具 1:终端命令: sudo gedit /usr/share/applications/MyChat.desktop 2:修改启动器配置如下: [Deskto ...
 - linux下mysql修改root密码
			
方法一:用set password命令 首先,登陆mysql mysql -u root -p 然后执行set password命令 set password for root@localhost = ...
 - 开涛spring3(9.1) - Spring的事务 之 9.1 数据库事务概述
			
9.1 数据库事务概述 事务首先是一系列操作组成的工作单元,该工作单元内的操作是不可分割的,即要么所有操作都做,要么所有操作都不做,这就是事务. 事务必需满足ACID(原子性.一致性.隔离性和持久性 ...
 - Swoole笔记(二)
			
本文示例代码详见:https://github.com/52fhy/swoole_demo. Task 我们可以在worker进程中投递一个异步任务到task_worker池中.此函数是非阻塞的,执行 ...
 - Wampserver红色橙色解决思路----端口冲突是关键
			
Wampserver不是绿色:wampserver下载安装不需要配置环境,在这之前需要下载tomcat,并确保启动,不然会是红色.安装好wampserver(就是在安装过程不会弹出缺少什么文件,我的就 ...
 - Go从入门到精通(一)go语言初始
			
一.第一个go程序 package main import ( "fmt" ) func main(){ fmt.Println("hello world") ...
 - cpp(第十七章)
			
1.baseic_ostream<charT,traits>& write(const char_type *s,streamsize n),cout.write()第一个参数提供 ...
 - DDD理论学习系列(5)-- 统一建模语言
			
DDD理论学习系列--案例及目录 1.引言 上一节讲解了领域模型,领域模型主要是将业务中涉及到的概念以面向对象的思想进行抽象,抽象出实体对象,确定实体所对应的方法和属性,以及实体之间的关系.然后将这些 ...