C# Excel处理工具

需求:选择一个Excel文件,然后对该Excel文件进行处理,再导出一个处理后的Excel文件。

效果图

 

声明:我对winform开发不熟,但是我看到许多开发人员做东西只管交差,从不考虑用户体验,也不考虑容错处理,我就在想,难道就不能做得专业一点吗?当你用别人做的东西,满口吐槽的时候有没有想过别人用你做的东西的时候,会不会一样的狂喷呢?

这里对Excel的操作使用了NPOI.dll组件,可自行去网上现在或者使用NuGet下载。

界面皮肤

IrisSkin4.dll包括(73皮肤+vs2012兼容) 绿色版下载地址:http://pan.baidu.com/s/1eQ1sAUA

这里使用到了IrisSkin4.dll皮肤控件

使用方法:

1、添加IrisSkin4.dll引用

1、工具箱,添加此程序集

 

 

2、复制皮肤文件

 

设置皮肤文件的属性

3、代码调用

        public frmMain(){InitializeComponent();//加载皮肤              skinEngine1.SkinFile ="Skins/Warm.ssk";skinEngine1.Active = true;skinEngine1.SkinDialogs = false;
  //如果要让某个控件不使用皮肤,则设置此属性,这样,就可以单独为此控件设置属性了,否则为此控件设置的属性将会被皮肤属性覆盖lblShow.Tag
= skinEngine1.DisableTag;lblMsg.Tag = skinEngine1.DisableTag;this.lblShow.ForeColor = Color.Red;this.lblMsg.ForeColor = Color.Green;}

关于excel的操作,这里还是使用NPOI.dll,可以自己从网上下载,也可以直接从vsNuGet中下载。

需要注意的是,对于一些比较耗时的界面操作,建议使用一个进度条,然后以异步调用的形式进行操作。异步调用可以开启一个线程,如果在线程调用的代码中需要修改窗体控件,也就是要修改主线程的内容,可以使用如下代码:

  Invoke(new MethodInvoker(delegate { progressBar.Maximum = sheet.LastRowNum; }));}

代码很简单,这里我不做过多的说明,详情请参见代码。

using Dapper;
using NExtensions;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.ComponentModel;
using System.Configuration;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Drawing;
using System.Collections.Generic;
using NPOI.HSSF.Util;namespace uuch.CustomsCheckPrint
{//modify by:Zouqj  2015/4/9public partial class frmMain : Form{public frmMain(){InitializeComponent();//加载皮肤              skinEngine1.SkinFile ="Skins/"+ConfigurationManager.AppSettings["themeName"];skinEngine1.Active = true;skinEngine1.SkinDialogs = false;lblShow.Tag = skinEngine1.DisableTag;lblMsg.Tag = skinEngine1.DisableTag;this.lblShow.ForeColor = Color.Red;this.lblMsg.ForeColor = Color.Green;}public bool IsCalculating { get; set; }/// <summary>/// 设置单元格样式/// </summary>/// <param name="workbook"></param>/// <param name="cell"></param>private void setCellStyle(IWorkbook workbook, ICell cell){HSSFCellStyle fCellStyle = (HSSFCellStyle)workbook.CreateCellStyle();HSSFFont ffont = (HSSFFont)workbook.CreateFont();//ffont.FontHeight = 20 * 20;//ffont.FontName = "宋体";ffont.Color = HSSFColor.Red.Index;fCellStyle.SetFont(ffont);//fCellStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center;//垂直对齐//fCellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;//水平对齐cell.CellStyle = fCellStyle;}public void EditAndSave(string filePath, ProgressBar progressBar, Label label){// 0       ,    1 ,     2 , 3,    4,    5,   6// 收寄日期, 邮件号, 寄达地, 类, 重量, 邮费, 省份//序号    提单号    快件单号    发件人    收件人    收件人地址    内件名称    数量    价值(USD)    重量(KG)    省份    首重费用    续重费用    OVS运费    操作费    OVS税费var sc = new SqlConnection(ConfigurationManager.AppSettings["connectionString"]);sc.Open();IWorkbook workbook = null;var fileExten = Path.GetExtension(filePath);var fsRead = File.OpenRead(filePath);if (fileExten == ".xls"||fileExten == ".xlsx"){workbook = new HSSFWorkbook(fsRead);}else{MessageBox.Show("文件不是有效的Excel文件!");return;}string proviceNameA = ConfigurationManager.AppSettings["proviceNameA"];string proviceNameB = ConfigurationManager.AppSettings["proviceNameB"];string[] economicProvince =null;string channelE = string.Empty; //经济渠道string channelS = string.Empty; //标准渠道if (rbtnA.Checked){channelE = ConfigurationManager.AppSettings["channelAE"];channelS = ConfigurationManager.AppSettings["channelAS"];economicProvince = string.IsNullOrEmpty(proviceNameA) ? null : proviceNameA.Split(',');}else if (rbtnB.Checked){channelE = ConfigurationManager.AppSettings["channelBE"];channelS = ConfigurationManager.AppSettings["channelBS"];economicProvince = string.IsNullOrEmpty(proviceNameB) ? null : proviceNameB.Split(',');}string pWeighFee = string.Empty; //首重费string yWeighFee = string.Empty; //续重费用string orderFee = string.Empty; //订单费 操作费
fsRead.Close();//ISheet sheet = workbook.GetSheetAt(0);var lackProvinceCount = 1;var sheetCount = workbook.NumberOfSheets;int successCounts = 0;for (int sheetIndex = 0; sheetIndex < sheetCount; sheetIndex++){var sheetIndexShow = sheetIndex + 1;var sheet = workbook.GetSheetAt(sheetIndex);//progressBar.Maximum = sheet.LastRowNum;if (sheetIndex == 0){Invoke(new MethodInvoker(delegate { progressBar.Maximum = sheet.LastRowNum; }));}IsCalculating = true;for (int i = 1; i <= sheet.LastRowNum; i++){var row = sheet.GetRow(i);var weight = row.GetCell(9) == null ? 0D : row.GetCell(9).NumericCellValue; //重量var targetProvince = row.GetCell(10) == null ? "" : row.GetCell(10).StringCellValue.ToString().Trim(); //省份if (targetProvince.IsNullOrEmpty()){Invoke(new MethodInvoker(delegate { lblShow.Text += String.Format("{0}  邮件号: {1} 缺少目标地省份!\r\n", lackProvinceCount.ToString("00000"), row.GetCell(1).StringCellValue); }));lackProvinceCount++;continue;}if (targetProvince.Contains("")){targetProvince = targetProvince.Replace("", "");}var channelCode = economicProvince.Contains(targetProvince) == true ? channelE : channelS; //根据省份获取渠道代码var sSelectProvince = String.Format("SELECT Base_PlaceID FROM Base_Place WHERE CnName LIKE '%{0}%' ", targetProvince);var resultContry = sc.Query(sSelectProvince, null).FirstOrDefault();if (resultContry == null){setCellStyle(workbook, row.GetCell(10));continue;}var countryID = resultContry["Base_PlaceID"].ToString();var sSelectChannel = String.Format("SELECT Base_ChannelInfoID FROM Base_ChannelInfo WHERE ChannelCode = '{0}' ", channelCode);var resultChannel= sc.Query(sSelectChannel, null).FirstOrDefault();if (resultChannel == null){setCellStyle(workbook, row.GetCell(10));continue;}var channelID = resultChannel["Base_ChannelInfoID"].ToString();string sql = string.Format(@"select SalesPrice, CalStyle  from v_Price_PriceInfo where SubChannelCode='{0}' and charindex ('{1}',AreaCountry)>0", channelCode, countryID);// 销售价 计算方式 P:首重 Y:续重var result = sc.Query(sql, null).ToList();if (result != null && result.Count() > 0){foreach (var v in result){if (v["CalStyle"].ToString() == "Y"){yWeighFee = v["SalesPrice"].ToString();}else if (v["CalStyle"].ToString() == "P"){pWeighFee = result[0]["SalesPrice"].ToString();}}}else{setCellStyle(workbook, row.GetCell(10));continue;}successCounts++;// 执行运费计算 " EXEC p_CalculatePriceByCH CountryID, Weight, ChannelID, CalFlag ";var sExecProc = String.Format(" EXEC p_CalculatePriceByCH {0}, {1}, {2}, {3} ", countryID, weight, channelID, 1);var query = sc.Query(sExecProc, null).FirstOrDefault();var shipFeeRs = query["BaseFee"].ToString();orderFee = query["OrderFee"].ToString();//Trace.WriteLine(String.Format("{0} - {1}, {2} - {3}, {4} ", targetProvince, countryID, channelCode, channelID, sExecProc));//首重费用 11var cellpWeighFee = row.GetCell(11);cellpWeighFee.SetCellType(CellType.Numeric);cellpWeighFee.SetCellValue(pWeighFee.ToDouble());//续重费用 12var cellyWeighFee = row.GetCell(12);cellyWeighFee.SetCellType(CellType.Numeric);cellyWeighFee.SetCellValue(yWeighFee.ToDouble());//OVS运费 13var cellShipFee = row.GetCell(13);cellShipFee.SetCellType(CellType.Numeric);cellShipFee.SetCellValue(shipFeeRs.ToDouble());//操作费 14var cellOrderFee = row.GetCell(14);cellOrderFee.SetCellType(CellType.Numeric);cellOrderFee.SetCellValue(orderFee.ToDouble());//progressBar.Value = i;Invoke(new MethodInvoker(delegate { lblMsg.Text = String.Format("工作表: {0}/{1} | 行: {2}/{3}", sheetIndexShow, sheetCount, i, sheet.LastRowNum); progressBar1.Value = i; }));  //异步显示进度条
                    System.Windows.Forms.Application.DoEvents();}Invoke(new MethodInvoker(delegate { lblShow.Text = string.Format("计算成功!成功数:{0}", successCounts); }));if (sheet.LastRowNum != successCounts){Invoke(new MethodInvoker(delegate { lblShow.Text += string.Format(" 有计算不出的数据{0}条,请核对数据或格式是否有误!", sheet.LastRowNum - successCounts); }));}}var fsSave = File.Create(textBoxOutputPath.Text);workbook.Write(fsSave);fsSave.Close();sc.Close();IsCalculating = false;}protected override void OnClosing(CancelEventArgs e){if (IsCalculating){var rs = MessageBox.Show("计算还没结束, 确定退出?", "确定退出?", MessageBoxButtons.YesNoCancel);if (rs == DialogResult.Yes){this.Dispose();this.Close();Environment.Exit(0);}else{e.Cancel = true;}}}private void btnSave_Click(object sender, EventArgs e){if (string.IsNullOrEmpty(textBoxInputFilePath.Text)){lblShow.Text = "请先选择要计算的文件!\r\n";return;}if (string.IsNullOrEmpty(textBoxOutputPath.Text)){lblShow.Text = "必须制定输出文件路径和名称!\r\n";return;}lblShow.Text = "";//两种结算方式try{Thread t = new Thread(new ThreadStart(Single));t.IsBackground = true;t.Start();  }catch (Exception ex){LogAPI.WriteLog(ex.Message);lblShow.Text=ex.Message;//"计算错误,详情请查看日志!"return;}Trace.WriteLine("OK");}//适配器void Single(){EditAndSave(textBoxInputFilePath.Text, progressBar1, lblMsg);}private void buttonChooseInputFile_Click(object sender, EventArgs e){var fileDialog = new OpenFileDialog();fileDialog.Multiselect = true;fileDialog.Title = "选择文件";fileDialog.Filter = "Excel files|*.xls; *.xlsx";if (fileDialog.ShowDialog() == DialogResult.OK){textBoxInputFilePath.Text = fileDialog.FileName;}}private void buttonChooseOutputFolder_Click(object sender, EventArgs e){var saveFileDialog = new SaveFileDialog();saveFileDialog.Title = "保存文件";saveFileDialog.Filter = "Excel files|*.xls; *.xlsx";if (saveFileDialog.ShowDialog() == DialogResult.OK){textBoxOutputPath.Text = saveFileDialog.FileName;}}}
}
View Code

App.config

<?xml version="1.0"?>
<configuration><appSettings><add key="connectionString" value="Data Source=192.xx.2.xxx;Initial Catalog=xxx;Persist Security Info=True;User ID=xx;Password=xxxx"/><add key="EnbleLog" value="false"/><!--是否开启日志:true,false--><add key="LogUrl" value="D:/"/><add key="LogName" value="计费日志.txt"/><add key="themeName" value="Warm.ssk"/><!--结算方式A一--><!--渠道--><add key="proviceNameA" value="上海,江苏,浙江,北京,安徽"/><!--这些省走经济快递渠道--><add key="channelAE" value="GZExpress_E"/> <!--经济快递渠道代码--><add key="channelAS" value="GZExpress_S"/> <!--标准快递渠道代码--><!--结算方式B 帝途一--><add key="proviceNameB" value="北京,上海,江苏,浙江,天津"/><!--这些省走经济快递渠道--><add key="channelBE" value="GZExpress_E1"/><!--经济快递渠道代码--><add key="channelBS" value="GZExpress_S1"/><!--标准快递渠道代码--></appSettings><startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup><runtime><assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"><dependentAssembly><assemblyIdentity name="NPOI" publicKeyToken="0df73ec7942b34e1" culture="neutral"/><bindingRedirect oldVersion="0.0.0.0-2.1.3.1" newVersion="2.1.3.1"/></dependentAssembly><dependentAssembly><assemblyIdentity name="NPOI.OOXML" publicKeyToken="0df73ec7942b34e1" culture="neutral"/><bindingRedirect oldVersion="0.0.0.0-2.1.3.1" newVersion="2.1.3.1"/></dependentAssembly></assemblyBinding></runtime>
</configuration>
View Code

转载于:https://www.cnblogs.com/jiekzou/p/4425642.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/472104.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql 坚向变横向_(排班表一)使用SQL语句使数据从坚向排列转化成横向排列

知识重点&#xff1a;1.extract(day from schedule01::timestamp)13Extract 属于 SQL 的 DML(即数据库管理语言)函数&#xff0c;同样&#xff0c;InterBase 也支持 Extract&#xff0c;它主要用于从一个日期或时间型的字段内抽取年、月、日、时、分、秒数据&#xff0c;因此&a…

LeetCode 1897. 重新分配字符使所有字符串都相等

文章目录1. 题目2. 解题1. 题目 给你一个字符串数组 words&#xff08;下标 从 0 开始 计数&#xff09;。 在一步操作中&#xff0c;需先选出两个 不同 下标 i 和 j&#xff0c;其中 words[i] 是一个非空字符串&#xff0c;接着将 words[i] 中的 任一 字符移动到 words[j] 中…

2015/4/14课堂练习

1.设计题目 书店针对《哈利波特》系列书籍进行促销活动&#xff0c;一共5卷&#xff0c;用编号0、1、2、3、4表示&#xff0c;单独一卷售价8元&#xff0c; 具体折扣如下所示&#xff1a; 本     数量 折扣 …

python 图片背景前景分离_【绝了】用 Python 把朋友头像变表情包!

正文在日常生活中&#xff0c;我们经常会存取一些朋友们的丑照&#xff0c;在这个项目中&#xff0c;我们以萌萌哒的熊猫头作为背景&#xff0c;然后试着在背景图上加入朋友们的照片&#xff0c;效果如下图所示。实现步骤导入朋友的照片(前景照片)&#xff1b;处理前景照片(缩放…

LeetCode 1899. 合并若干三元组以形成目标三元组

文章目录1. 题目2. 解题1. 题目 三元组 是一个由三个整数组成的数组。 给你一个二维整数数组 triplets &#xff0c;其中 triplets[i] [ai, bi, ci] 表示第 i 个 三元组 。 同时&#xff0c;给你一个整数数组 target [x, y, z] &#xff0c;表示你想要得到的 三元组 。 为了…

openpyxl 读写 excel

import openpyxl book openpyxl.load_workbook(b.xlsx) # 读取 # sheet book["name_tab"] sheet book.active # rowsheet.max_row # 行数 columnsheet.max_column # 列数 print(row) print(column) for r in range(2, row1): # 跳过表头&#xff0c;行号是从1开…

opengl计算帧率_或许是迄今为止第一篇讲解 fps 计算原理的文章吧

前言fps&#xff0c;是 frames per second 的简称&#xff0c;也就是我们常说的“帧率”。在游戏领域中&#xff0c;fps 作为衡量游戏性能的基础指标&#xff0c;对于游戏开发和手机 vendor 厂商都是非常重要的数据&#xff0c;而计算游戏的 fps 也成为日常测试的基本需求。目前…

041、基于CNN的样式迁移

之——基于CNN的滤镜 目录 之——基于CNN的滤镜 杂谈 正文 1.基于CNN的样式迁移 2.实现 杂谈 通过CNN的特征提取&#xff0c;可以实现将一个图片的样式模式特征迁移到另一张图像上。 正文 1.基于CNN的样式迁移 就是在某些层的输出上用其他的图片进行监督。 2.实现 一般来…

LeetCode 483. 最小好进制(二分查找)

文章目录1. 题目2. 解题1. 题目 对于给定的整数 n, 如果 n 的 k&#xff08;k>2&#xff09;进制数的所有数位全为1&#xff0c;则称 k&#xff08;k>2&#xff09;是 n 的一个好进制。 以字符串的形式给出 n, 以字符串的形式返回 n 的 最小 好进制。 示例 1&#xff…

LeetCode LCS 01. 下载插件

文章目录1. 题目2. 解题1. 题目 小扣打算给自己的 VS code 安装使用插件&#xff0c;初始状态下带宽每分钟可以完成 1 个插件的下载。 假定每分钟选择以下两种策略之一: 使用当前带宽下载插件将带宽加倍&#xff08;下载插件数量随之加倍&#xff09; 请返回小扣完成下载 n …

LeetCode LCS 02. 完成一半题目(计数+排序)

文章目录1. 题目2. 解题1. 题目 有 N 位扣友参加了微软与力扣举办了「以扣会友」线下活动。 主办方提供了 2*N 道题目&#xff0c;整型数组 questions 中每个数字对应了每道题目所涉及的知识点类型。 若每位扣友选择不同的一题&#xff0c;请返回被选的 N 道题目至少包含多少种…

摄像头图像分析目标物体大小位置_单个运动摄像头估计运动物体深度,谷歌挑战新难题...

雷锋网 AI 科技评论按&#xff1a;人类视觉系统有一个我们习以为然但其实极其强大的功能&#xff0c;那就是可以从平面图像反推出对应的三维世界的样子。即便在有多个物体同时移动的复杂环境中&#xff0c;人类也能够对这些物体的几何形状、深度关系做出合理的推测。然而类似的…

LeetCode LCS 03. 主题空间(广度优先搜索BFS)

文章目录1. 题目2. 解题1. 题目 「以扣会友」线下活动所在场地由若干主题空间与走廊组成&#xff0c;场地的地图记作由一维字符串型数组 grid&#xff0c;字符串中仅包含 “0"&#xff5e;"5” 这 6 个字符。 地图上每一个字符代表面积为 1 的区域&#xff0c;其中 …

SQL SERVER PIVOT 行转列、列传行

在数据库操作中&#xff0c;有些时候我们遇到需要实现“行转列”的需求&#xff0c;例如一下的表为某店铺的一周收入情况表&#xff1a; WEEK_INCOME(WEEK VARCHAR(10),INCOME DECIMAL) 我们先插入一些模拟数据&#xff1a; INSERT INTO WEEK_INCOME SELECT 星期一,1000 UNION…

mysql cluster 查看数据库表名称_MySQL Cluster如何创建磁盘表方法解读

MySQL Cluster采用一系列的Disk Data objects来实现磁盘表;接下来为您详细介绍一、概念MySQL Cluster采用一系列的Disk Data objects来实现磁盘表。Tablespaces&#xff1a;作用是作为其他Disk Data objects的容器。Undo log files&#xff1a;存储事务进行回滚需要的信息&…

(运算符) 运算符

& 运算符既可作为一元运算符也可作为二元运算符。 备注 一元 & 运算符返回操作数的地址&#xff08;要求 unsafe 上下文&#xff09;。 为整型和 bool 类型预定义了二进制 & 运算符。 对于整型&#xff0c;& 计算操作数的逻辑按位“与”。 对于 bool 操作数&am…

LeetCode 1903. 字符串中的最大奇数

文章目录1. 题目2. 解题1. 题目 给你一个字符串 num &#xff0c;表示一个大整数。 请你在字符串 num 的所有 非空子字符串 中找出 值最大的奇数 &#xff0c;并以字符串形式返回。如果不存在奇数&#xff0c;则返回一个空字符串 “” 。 子字符串 是字符串中的一个连续的字符…

mysql分页插件springboot_SpringBoot--使用Mybatis分页插件

1、导入分页插件包和jpa包org.springframework.bootspring-boot-starter-data-jpacom.github.pagehelperpagehelper-spring-boot-starter1.2.52、增加分页配置# 主键自增回写方法,默认值MYSQL,详细说明请看文档mapper:identity: MYSQL# 设置 insert 和 update 中&#xff0c;是…

LeetCode 1904. 你完成的完整对局数

文章目录1. 题目2. 解题1. 题目 一款新的在线电子游戏在近期发布&#xff0c;在该电子游戏中&#xff0c;以 刻钟 为周期规划若干时长为 15 分钟 的游戏对局。 这意味着&#xff0c;在 HH:00、HH:15、HH:30 和 HH:45 &#xff0c;将会开始一个新的对局&#xff0c;其中 HH 用一…

LeetCode 1905. 统计子岛屿(BFS)

文章目录1. 题目2. 解题1. 题目 给你两个 m x n 的二进制矩阵 grid1 和 grid2 &#xff0c;它们只包含 0 &#xff08;表示水域&#xff09;和 1 &#xff08;表示陆地&#xff09;。 一个 岛屿 是由 四个方向 &#xff08;水平或者竖直&#xff09;上相邻的 1 组成的区域。 任…