C#实现自动打印Excel文档

解决思路:

1.首先从服务器下载需要打印的Excel文档

2.通过集成第三方SDK Spire.Xls来调用本地Excel文档实现打印

/// <summary>
/// 下载并打印Excel文档
/// </summary>
/// <param name="imei"></param>
public void PrintInspectReport(string imei)
{
    try
    {
        // 下载Excel文档
        string downloadUrl = string.Format("{0}?imei={1}", ConfigurationManager.AppSettings["downloadInsReport"], imei);
        string savePath = Application.StartupPath + "\\inspectReport";
        if (!Directory.Exists(savePath))
        {
            Directory.CreateDirectory(savePath);
        }
        savePath += "\\" + imei;
        // 在此必须用xls文件作为后缀,如果用xlsx,会出现打印时文件版本冲突异常
        while (File.Exists(savePath + ".xls"))
        {
            savePath += "I";
        }
        savePath += ".xls";
        FileUtil.getInstance().DownloadFile(downloadUrl, savePath);

        // 打印Excel文档
        if (File.Exists(savePath))
        {
            PrinterMapper printerMapper = new PrinterMapper();

            // 自定义类SpireHelper,去掉dll自带的红色警告字体
            SpireHelper.ActivateMemoryPatching();

            Workbook workbook = new Workbook();

            workbook.LoadFromFile(savePath);

            // 获取第一个worksheet
            Worksheet sheet = workbook.Worksheets[0];
            // 获取手动设置的打印页面间距参数
            DataSet dataSet = printerMapper.SelectByPrinterId(new PrintSetting { PrintSettingId = 2 });

            if (dataSet.Tables[0].Rows.Count > 0)
            {
                DataRow row = dataSet.Tables[0].Rows[0];
                // 设置打印页面间距
                sheet.PageSetup.LeftMargin = double.Parse(row[2].ToString());
                sheet.PageSetup.TopMargin = double.Parse(row[3].ToString());
                sheet.PageSetup.RightMargin = double.Parse(row[4].ToString());
                sheet.PageSetup.BottomMargin = double.Parse(row[5].ToString());

                string printerName = row[1].ToString();
                workbook.PrintDocument.PrinterSettings.PrinterName = printerName;
            }

            workbook.PrintDocument.Print();
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show("打印Excel文档异常:" + ex.Message, ConstantUtil.MessageTitle.ERROR);
    }

}

注:第三方插件Spire不要在VS的NuGet程序包下载,否则会出现大大的红色英文水印,要想解决红色水印,需要用到他们发布的旧版本Spire插件引用包。以下附上下载引用包的地址和解决水印的代码:

https://download.csdn.net/download/weixin_39026052/89052148

/// <summary>
/// 解决打印Excel出现水印的问题
/// </summary>
public class SpireHelper
{
    public static void ActivateMemoryPatching()
    {
        Assembly[] arr = AppDomain.CurrentDomain.GetAssemblies();
        foreach (Assembly assembly in arr)
        {
            if (assembly.FullName.StartsWith("Spire.License"))
                ActivateForAssembly(assembly);
        }
        AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(ActivateOnLoad);
    }

    private static void ActivateOnLoad(object sender, AssemblyLoadEventArgs e)
    {
        string Name = e.LoadedAssembly.FullName;
        if (Name.IndexOf("Spire.License") != -1)
            ActivateForAssembly(e.LoadedAssembly);
    }

    private static void ActivateForAssembly(Assembly assembly)
    {
        bool isFound = false;

        Type[] arrType = null;
        try
        {
            arrType = assembly.GetTypes();
        }
        catch (ReflectionTypeLoadException err)
        {
            arrType = err.Types;
        }

        MethodInfo miLicensed = typeof(SpireHelper).GetMethod("InvokeMe", BindingFlags.NonPublic | BindingFlags.Static);
        MethodInfo miEvaluation = null;

        foreach (Type type in arrType)
        {
            if (isFound) break;

            if (type == null) continue;

            MethodInfo[] arrMInfo = type.GetMethods(BindingFlags.NonPublic | BindingFlags.Static);

            foreach (MethodInfo info in arrMInfo)
            {
                if (isFound) break;

                try
                {
                    string strMethod = info.ToString();
                    if ((strMethod.StartsWith("Byte[]")) && (strMethod.IndexOf("(System.String)") > 0))
                    {
                        miEvaluation = info;
                        MemoryPatching(miEvaluation, miLicensed);
                        isFound = true;
                        break;
                    }
                }
                catch
                {
                    throw new InvalidOperationException("MemoryPatching for " + assembly.FullName + " failed !");
                }
            }
        }

        string LData = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8TGljZW5zZSBLZXk9ImNyOERaN1hKMkR5MUs2UUJBTkRPSVRLdlpjTzZkelVod2lsSHBnVlluQ3k0cXlHV2V6TFZubFJGeFAxNU1mSWZnUmdNWm1XaEdOQWRFNFRqZWZnQ1ovbFR2b1BkSXRIbDZXdDVBNWk1TVhFbnFkQnVPMUthRnovRFFzYUdWTGhzdjlySG1ybnRxSElFRGxJeGRxYUpNcGtLb0Frd1A3d1N6T01KMVkrbUNmVTVVRmV6REwvTjd1enJ4M0Y0d2I1SGErd0E2VFQ5VFJ3SzAzejlFS01aRmwzU1lSL3o0YVU3TE0wZFNYWTlqU0ZKZ2dqZlZzRFVLaUJyVm5td1ljaXVyOUVrYmw5Q3RaWTAzdG1yZm01QlplKzZnaHRFTm4wb2gzMzh0WlJleWpjcjc0QWs3MWhnWWtuTE9CQzE1VllmalhzcXVBVW13MlI2TWNWMlBPT2JyY1RSYlhBZ3pvUWJPeWQ4U2JFWmN3aE43NktQd1dzUVFTMUowdGlZSFVLeE9tMnQ0ZkJWMGhQVmhhOUI4Y0swNHFKUVp0MDBaMWNKRGEwd2I4VWx6RWs5QkhVVzJlbk9mVDE0UnlIQ2krWUdlbVBLY2RDUXJoMXpyWVRGN0ltb0x4N3h1NGV2RFRZc2xzV0JrbFFJb3g4NnJWckVVa1N0dXErQUNTWS9xVTM5L1Zhd3Y5S0FmUjVUZUVicGt3RGhTYjBOQkFqVDhBeXRsRFZkR2ZpZzBxS0czVllpVHBYRnc1cHRMVmgrYmtkK2RnN3Z4dHZyNDVaVVdKZXlyekdOR0g3YUZZZDZwLzJNRy9YSlRsR3ovU05RbzJDUExraU83SlhuOU5HZXhaN3BIbTBkZ3pNWmJHRVhxVmR2bG04MTJhL1hMMVNxeEdVWStvNVpsVUM3WTV4Z2dhRCtGZVA5enpoeUpxSUVwcDk3My9ScTRteG1wQWZMcVNzTzJSeHlTcStpdjFDc3AwQ3JvMDc4OEhybDFteWt4dVQweWRSWVpDNkRTeDhNMi9MWTNkOXNud3U3NkFmYjVDOVF1ZE9Zc0wzREh2aGZncmNVSWUvcUhmVFo5QWF6Y3pUanlyM2RPQkFjczBLZk12Y0xVUzRSeHZDdW1NNDVyNDJnMXJ3UGluN2JBcmYvZnNMTzZtS3g0WWRoSURNWlF6V3RjbkhFSTF5TXJ6aU9pdXhMdE8xalRBV25uU2VLVDJ0cXI3Tm42Qmg5TURHNjZZK2lJaW4xV05TUCtMdDFYdXRkajNKTyt4b1FNUVB5ZFpoZkJYZXpVMEhRMnd0eEdwdzRNczRTMTVJbFg1TEdXR3dXeUdYTWNjVWd3b1RDeFRGYmgyZFo0Vkg3OVZHTEVFR1JRWEZrNTRBdlFLdFBpdUcxY0w4RFo3WEoyRHkxSzZUUWVORE9YeFl2NFNveitCMHNBS0VwTVRrNCtTYWpYNksrSjlUOFhZVXRTOE8wWWZGUFZqZkhIYTZORWQyODdVcUlqMnJnQlF1bjVDV3hCczFHUm5BYmd1Z3MyL2ZQakcwZmdQemdSYzR5Q3ZObFg4V2pKUnloc3U5VFRKTjd1R3NOdnprU2IyZWlyQmhEaG1vQ0Jqa0wyYnMzT3I2d2pnNnBUNVpmNGhEdDF0STBJNXo1aytxQXVSZnRhd1lmamhXYmpMS0xKOTlUVk1kRDZaTCtTenNtQkNWN05lYm96V0RUTWgrRnJPT292R09ZbUk1bWp4Smd1MVRXNnI1V0JUK2oxSjBFNmJIb2tEMWo0Wm1DWUQreVBPUW1PMm1yUTNGdC9jVmZwQWlJdzliRkgwZ1FIbXQ4QnNuZnQ2MVV3c1h6cSs2akNvY1hOOUMvRXZPblhTczZuVlNGSkVBL3l1QmNIazZxOWdqanBnRG1NTEcrNlpxR1VjRWMzZEp2THpuK3pNT0p3TDI4WUQxN3BLSXBUNnd6WFBFVFJwWS9qNHhoMkQvaFhJRVNHcTk1eTVmZE9MNmx1QT09IiBWZXJzaW9uPSI5LjkiPgogICAgPFR5cGU+UnVudGltZTwvVHlwZT4KICAgIDxVc2VybmFtZT5Vc2VyTmFtZTwvVXNlcm5hbWU+CiAgICA8RW1haWw+ZU1haWxAaG9zdC5jb208L0VtYWlsPgogICAgPE9yZ2FuaXphdGlvbj5Pcmdhbml6YXRpb248L09yZ2FuaXphdGlvbj4KICAgIDxMaWNlbnNlZERhdGU+MjAxNi0wMS0wMVQxMjowMDowMFo8L0xpY2Vuc2VkRGF0ZT4KICAgIDxFeHBpcmVkRGF0ZT4yMDk5LTEyLTMxVDEyOjAwOjAwWjwvRXhwaXJlZERhdGU+CiAgICA8UHJvZHVjdHM+CiAgICAgICAgPFByb2R1Y3Q+CiAgICAgICAgICAgIDxOYW1lPlNwaXJlLk9mZmljZSBQbGF0aW51bTwvTmFtZT4KICAgICAgICAgICAgPFZlcnNpb24+OS45OTwvVmVyc2lvbj4KICAgICAgICAgICAgPFN1YnNjcmlwdGlvbj4KICAgICAgICAgICAgICAgIDxOdW1iZXJPZlBlcm1pdHRlZERldmVsb3Blcj45OTk5OTwvTnVtYmVyT2ZQZXJtaXR0ZWREZXZlbG9wZXI+CiAgICAgICAgICAgICAgICA8TnVtYmVyT2ZQZXJtaXR0ZWRTaXRlPjk5OTk5PC9OdW1iZXJPZlBlcm1pdHRlZFNpdGU+CiAgICAgICAgICAgIDwvU3Vic2NyaXB0aW9uPgogICAgICAgIDwvUHJvZHVjdD4KICAgIDwvUHJvZHVjdHM+CiAgICA8SXNzdWVyPgogICAgICAgIDxOYW1lPklzc3VlcjwvTmFtZT4KICAgICAgICA8RW1haWw+aXNzdWVyQGlzc3Vlci5jb208L0VtYWlsPgogICAgICAgIDxVcmw+aHR0cDovL3d3dy5pc3N1ZXIuY29tPC9Vcmw+CiAgICA8L0lzc3Vlcj4KPC9MaWNlbnNlPg==";

        //Spire.License.LicenseProvider.SetLicenseKey(LData);
        Type type2 = assembly.GetType("Spire.License.LicenseProvider");
        MethodInfo mi = type2.GetMethod("SetLicenseKey", new Type[] { typeof(String) });
        mi.Invoke(Activator.CreateInstance(type2, null), new String[] { LData });
    }


    private static byte[] InvokeMe(String string_0)
    {
        return Convert.FromBase64String("PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiIHN0YW5kYWxvbmU9InllcyI/Pgo8TGljZW5zZSBLZXk9IngiIFZlcnNpb249IjkuOSI+CiAgICA8VHlwZT5SdW50aW1lPC9UeXBlPgogICAgPFVzZXJuYW1lPlVzZXJOYW1lPC9Vc2VybmFtZT4KICAgIDxFbWFpbD5lTWFpbEBob3N0LmNvbTwvRW1haWw+CiAgICA8T3JnYW5pemF0aW9uPk9yZ2FuaXphdGlvbjwvT3JnYW5pemF0aW9uPgogICAgPExpY2Vuc2VkRGF0ZT4yMDE2LTAxLTAxVDEyOjAwOjAwWjwvTGljZW5zZWREYXRlPgogICAgPEV4cGlyZWREYXRlPjIwOTktMTItMzFUMTI6MDA6MDBaPC9FeHBpcmVkRGF0ZT4KICAgIDxQcm9kdWN0cz4KICAgICAgICA8UHJvZHVjdD4KICAgICAgICAgICAgPE5hbWU+U3BpcmUuT2ZmaWNlIFBsYXRpbnVtPC9OYW1lPgogICAgICAgICAgICA8VmVyc2lvbj45Ljk5PC9WZXJzaW9uPgogICAgICAgICAgICA8U3Vic2NyaXB0aW9uPgogICAgICAgICAgICAgICAgPE51bWJlck9mUGVybWl0dGVkRGV2ZWxvcGVyPjk5OTk5PC9OdW1iZXJPZlBlcm1pdHRlZERldmVsb3Blcj4KICAgICAgICAgICAgICAgIDxOdW1iZXJPZlBlcm1pdHRlZFNpdGU+OTk5OTk8L051bWJlck9mUGVybWl0dGVkU2l0ZT4KICAgICAgICAgICAgPC9TdWJzY3JpcHRpb24+CiAgICAgICAgPC9Qcm9kdWN0PgogICAgPC9Qcm9kdWN0cz4KICAgIDxJc3N1ZXI+CiAgICAgICAgPE5hbWU+SXNzdWVyPC9OYW1lPgogICAgICAgIDxFbWFpbD5pc3N1ZXJAaXNzdWVyLmNvbTwvRW1haWw+CiAgICAgICAgPFVybD5odHRwOi8vd3d3Lmlzc3Vlci5jb208L1VybD4KICAgIDwvSXNzdWVyPgo8L0xpY2Vuc2U+Cg==");
    }

    private static unsafe void MemoryPatching(MethodBase miEvaluation, MethodBase miLicensed)
    {
        IntPtr IntPtrEval = GetMemoryAddress(miEvaluation);
        IntPtr IntPtrLicensed = GetMemoryAddress(miLicensed);

        if (IntPtr.Size == 8)
            *((long*)IntPtrEval.ToPointer()) = *((long*)IntPtrLicensed.ToPointer());
        else
            *((int*)IntPtrEval.ToPointer()) = *((int*)IntPtrLicensed.ToPointer());
    }

    private static unsafe IntPtr GetMemoryAddress(MethodBase mb)
    {
        RuntimeHelpers.PrepareMethod(mb.MethodHandle);

        if ((Environment.Version.Major >= 4) || ((Environment.Version.Major == 2) && (Environment.Version.MinorRevision >= 3053)))
        {
            return new IntPtr(((int*)mb.MethodHandle.Value.ToPointer() + 2));
        }

        UInt64* location = (UInt64*)(mb.MethodHandle.Value.ToPointer());
        int index = (int)(((*location) >> 32) & 0xFF);
        if (IntPtr.Size == 8)
        {
            ulong* classStart = (ulong*)mb.DeclaringType.TypeHandle.Value.ToPointer();
            ulong* address = classStart + index + 10;
            return new IntPtr(address);
        }
        else
        {
            uint* classStart = (uint*)mb.DeclaringType.TypeHandle.Value.ToPointer();
            uint* address = classStart + index + 10;
            return new IntPtr(address);
        }
    }
}

这样就可以完美解决出现的红色水印问题。。

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ConserWang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值