C#带格式复制excel(需要安装office)(这就很舒服)

非常舒服的操作,唯一令人讨厌的问题是目标文件的行列长宽不能修改,希望有大神帮忙修改代码(已经可以更改了)

更新:如果要把它部署到服务器上一定要注意蛋疼的几点。

首先要注意,服务器上必须装有excel,而且excel版本最好与测试环境下的一样,否则鬼才知道会出什么bug(不过我的测试环境是2010,服务器上是2013倒是没出错,但还是要注意一下版本的问题);

其次,要在组件服务(dcomcnfg.exe)里面进行设置,否则会报没有权限禁止访问的问题。找到excel的组件服务,我这里是Microsoft Excel Application,选择属性,点击“安全”选项卡,把启动和激活权限设为自定义,然后选择编辑,选择添加,因为我手里用的是IIS服务器,所以我这边需要加入IIS_IUSRS用户,网上说是要加入NETWORK SERVICE用户,但是我这边是要加入IIS_IUSRS用户,初步推测是使用的服务器不同,但鬼知道是什么情况呢,在IIS_IUSRS的权限下加入本地启动和本地激活,如果需要NETWORK SERVICE的话也一样,然后在访问权限下也做类似的设置,把上述用户添加进去,并添加本地访问的权限;

再次,我这边尝试连接服务器调用带格式复制的方法时出现了“

 

因为配置标识不正确,系统无法开始服务器进程。请检查用户名和密码

”的问题,我的解决方法是在excel的组件服务里选择标识选项卡,勾选为下列用户(网上一般说配置的时候要选择交互式用户,我这边是失败的),然后把当前登录到服务器的用户名和密码输入保存即可;

 

还有 ,有时候可能会出现excel程序无法正常退出的情况,强烈建议在调用完方法之后进行一次GC.Collect()。

更新:在把本程序部署到服务器上后,出现了无法复制的情况,原因是程序创建的xls文件为只读的xls文件,所以无法写入,解决方法是将网站所在的文件夹增加一个IIS_IUSRS用户

//引入Microsoft.Office.Interop.Excel.dll(找不到Microsoft.Office.Interop.Excel.dll的话可以参考我的另一篇文章解决无法找到Microsoft.Office.Interop.Excel并将其分离的方法)也可以直接引用excel.exe

using Microsoft.Office.Interop.Excel;

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


namespace ConsoleApp2
{
    class ExcelCopy
    {
        /// <summary>
        /// 将源excel复制到目标excel
        /// </summary>
        /// <param name="copyfilePosition">需复制文件的路径以及文件名</param>
        /// <param name="targetPosition">目标文件路径以及文件名</param>
        public void fakCopy(string copyfilePosition, string targetPosition)
        {

            Application app = new Application();
            //app.Visible = false;更新:这一条数据不要加上,会出现无法复制的问题,奇怪的是如果我加上了这句话,我在上一句设断点然后执行就会报错,直接运行却不一定会有问题,把这条注释掉就可以解决这个问题,搞不懂微软在干什么
            app.DisplayAlerts = false;

            object missing = System.Reflection.Missing.Value;

            Workbook tarFileWk;
            Worksheet cpFileSh;

            try
            {
                Workbook cpFileWk = app.Workbooks.Open(copyfilePosition);//需复制文件位置
                tarFileWk = app.Workbooks.Open(targetPosition);//目标文件位置
                //Console.WriteLine(copyfilePosition);
                Worksheet sheets = (Worksheet)cpFileWk.Sheets[1];
                string sheetName = sheets.Name; //Sheet名
                cpFileSh = (Worksheet)cpFileWk.Worksheets[sheetName];
                int row = cpFileSh.UsedRange.Cells.Rows.Count;//获取最大行数
                int column = cpFileSh.UsedRange.Cells.Columns.Count;//获取最大列数
                string letterCol = ExcelCopy.ToNumberSystem26(column);//把最大列数转换为26进制
                string lastCell = "A1:" + letterCol + row;
                Range rng1;
                rng1 = cpFileSh.get_Range(lastCell, Type.Missing);
                Worksheet newsh = (Worksheet)tarFileWk.Sheets.Add(missing, missing, missing, missing);
                Range rng2;
                rng2 = newsh.get_Range(lastCell, Type.Missing);
                rng1.Copy();
                rng2.PasteSpecial(Microsoft.Office.Interop.Excel.XlPasteType.xlPasteAll, Microsoft.Office.Interop.Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, System.Type.Missing, System.Type.Missing);
                rng2.EntireColumn.AutoFit();//自适应列宽,但是据说会降低运行效率╮(╯▽╰)╭如果不加这一行的话会按照源EXCEL的格式复制过来
                ((Range)newsh.Columns["A:B", System.Type.Missing]).ColumnWidth = 3;//将A,B两列的列宽修改为3(不是像素),如果只打算改A列的话把A:B改成A:A即可

                ((Range)newsh.Rows["1:2", System.Type.Missing]).RowHeight = 100;//将A.B两行的高度改为100

                cpFileWk.Save();
                cpFileWk.Close();


                tarFileWk.Save();
                tarFileWk.Close();
                app.Quit();
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                //try { cpFileWk.Save(); } catch (Exception e) { Console.WriteLine(e); }
                //try { cpFileWk.Close(); } catch (Exception e) { Console.WriteLine(e); }
                //try { tarFileWk.Save(); } catch (Exception e) { Console.WriteLine(e); }
                //try { tarFileWk.Close(); } catch (Exception e) { Console.WriteLine(e); }
                try { app.Quit(); } catch (Exception e) { Console.WriteLine(e); }


            }


        }
        /// <summary>
        /// 将获取到的列数转换为二十六进制以便于匹配excel中的列名
        /// </summary>
        /// <param name="n">获取的列数</param>
        /// <returns></returns>
        public static string ToNumberSystem26(int n)
        {
            string s = string.Empty;
            while (n > 0)
            {
                int m = n % 26;
                if (m == 0) m = 26;
                s = (char)(m + 64) + s;
                n = (n - m) / 26;
            }
            return s;
        }


        /// <summary>
        /// 获取需复制文件的名称
        /// </summary>

        /// <param name="copyFolderPosition">需复制文件的路径</param>

        ///需要注意的是这里需要传入绝对路径,如果传入的是相对路径需要先转换成绝对路径

        /// <returns></returns>
        public string[] getFileName(string copyFolderPosition)
        {
            // string[] files = Directory.GetFiles(copyFolderPosition, "*.*", SearchOption.AllDirectories);包含子目录
            string[] files = Directory.GetFiles(copyFolderPosition, "*.xls*", SearchOption.TopDirectoryOnly);//不包含子目录 


            //foreach (string file in files)
            //{
            //    Console.WriteLine(file);
            //}
            //Console.ReadLine();
            return files;
        }
    }

}

目标文件路径以及文件名如果不存在,则需要新建一个目标文件,方式如下,需使用NPOI

HSSFWorkbook book = new HSSFWorkbook();
                ISheet sheet = book.CreateSheet("Sheet1");
                FileStream stream = File.OpenWrite(targetPosition); ;
                book.Write(stream);
                stream.Close();

更新:这种方法可以把图片一起复制过来

Application app = new Application();


            Workbook workbook1 = app.Workbooks._Open(targetPosition, Type.Missing, Type.Missing, Type.Missing, Type.Missing
                 , Type.Missing, Type.Missing, Type.Missing, Type.Missing
                 , Type.Missing, Type.Missing, Type.Missing, Type.Missing);

            Worksheet sheet1 = workbook1.Worksheets["Sheet1"] as Worksheet;

            Workbook workbook2 = app.Workbooks._Open(copyfilePosition, Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing
                , Type.Missing, Type.Missing, Type.Missing, Type.Missing);

            Worksheet sheet2 = workbook2.Worksheets["Sheet1"] as Worksheet; 
            
            sheet2.Copy(Type.Missing, sheet1);
            workbook1.Save();
            //workbook2.Save();
            workbook1.Close(false, Type.Missing, Type.Missing);
            workbook2.Close(false, Type.Missing, Type.Missing);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值