有一个实体的子表数据量太大,于是客户想用execel来导入实体数据。首先想到的是用系统自带的Import Data,客户嫌太麻烦,比如lookup字段要做map等。

下面是具体的实现步骤:

一、定义excel数据模板

1. 利用系统自带的Download Template For Import下载系统自带的模板

2. 去掉不需要的列,比如有些列是自动计算,自动赋值

3. 保存为excel文件,并copy到crm server里的isv目录下

4. 定义一个按钮,并指定调用下面的js:

// export purchase detail template

function downloadDetailTemplate() {

    var url = "/ISV/TempDownLoad/OrderDetail.xls";

    var hiddenIFrameID = 'hiddenDownloader',

            iframe = document.getElementById(hiddenIFrameID);

    if (iframe === null) {

        iframe = document.createElement('iframe');

        iframe.id = hiddenIFrameID;

        iframe.style.display = 'none';

        document.body.appendChild(iframe);

    }

    iframe.src = url;

}

二、导入数据

1. 在上面定义的excel模板里填充数据

2. 定义一个aspx页面:

<div style="margin-top: 20px; margin-left: 10px">

       <asp:FileUpload ID="FileUpload1" runat="server" Height="20px" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

       <asp:Button ID="btSubmit" runat="server" Text="上传" OnClientClick="javascript:return extension();"

           OnClick="btSubmit_Click" Height="20px" />

       <br />

       <br />

       <asp:Label ID="lbMessage" runat="server" Text=""></asp:Label>

   </div>

很简单,一个上传控件,一个上传按钮

3. 为这个实体建一个类,跟excel里的列一一对应

public class PurchaseOrderDetails

    {

        //public string OrderNo { get; set; }

 

        public string PartNo { get; set; }

        public decimal Quantity { get; set; }

        public decimal UnitPrice { get; set; }

        public string Remarks { get; set; }

        public string CorrespondingSONo { get; set; }

        public decimal SWAPRate { get; set; }

        public DateTime RequestedDeliveryDate { get; set; }

 

        public string Model { get; set; }

        public string Description { get; set; }

        public decimal SOQuantity { get; set; }

    }

4. 读取excel里的数据,并转换成上面定义的类

System.IO.FileInfo fileinfo = new System.IO.FileInfo(FileUpload1.PostedFile.FileName);

int fileLen = FileUpload1.PostedFile.ContentLength;

Byte[] FileData = new Byte[fileLen];

 

HttpPostedFile hps = FileUpload1.PostedFile;

System.IO.Stream stream = hps.InputStream;

stream.Read(FileData, 0, fileLen);

ExcelDataReader.ExcelDataReader spreadsheet = new ExcelDataReader.ExcelDataReader(stream);

if (spreadsheet.WorkbookData.Tables.Count == 0)

{

    throw new Exception("File loading error!");

}

 

DataTable dt = spreadsheet.WorkbookData.Tables[0];

int filecount = dt.Columns.Count;

PurchaseOrderDetails detail = new PurchaseOrderDetails();

Type type = detail.GetType();

PropertyInfo[] propertyInfos = type.GetProperties();

if (propertyInfos.Length != filecount)

{

    throw new Exception("File Template is not correct!");

}

 

List<PurchaseOrderDetails> detailList = new List<PurchaseOrderDetails>();

for (int index = 1; index < dt.Rows.Count - 1; index++)

{

    detail = new PurchaseOrderDetails();

    int count = 0;

    int nullcount = 0;//判断是否空数据

 

    foreach (PropertyInfo property in propertyInfos)

    {

        string csvvalue = dt.Rows[index][count].ToString();

        if (csvvalue != null && csvvalue != "")

        {

            csvvalue = ToDBC(csvvalue);

            object convertValue = null;

            try

            {

                convertValue = Convert.ChangeType(csvvalue, property.PropertyType);

            }

            catch (Exception ex)

            {

                property.SetValue(detail, convertValue, null);

                count++;

                continue;

            }

            property.SetValue(detail, convertValue, null);

        }

        else

        {

            property.SetValue(detail, null, null);

 

 

            nullcount++;

        }

        count++;

    }

    if (nullcount == propertyInfos.Length)

    {

        continue;

    }

 

    detailList.Add(detail);

}

 

 

spreadsheet.WorkbookData.Dispose();

 

stream.Close();

5. 验证,转换成真实的实体

Entity orderDetail = new Entity("new_purchase_details");

 

// 0. order no

orderDetail["new_purchaseid"] = new EntityReference("new_purchase", Guid.Parse( entityId));

 

// 1. part no

var ents = getData("new_product", "new_name", item.PartNo.Trim());

Guid productid;

if (ents.Entities.Count == 0)

{

throw new Exception(string.Format("Part No (row {0}) is wrong !", i + 1));

}

else

{

productid = ents.Entities[0].Id;

orderDetail["new_productid"] = new EntityReference("new_product", productid);

}

 

// 2. model

ents = getData("new_model", "new_name", item.Model.Trim());

if (ents.Entities.Count == 0)

{

throw new Exception(string.Format("Model (row {0}) is wrong !", i + 1));

}

else

{

orderDetail["new_model"] = new EntityReference("new_model", ents.Entities[0].Id);

}

 

// 3. Quantity

orderDetail["new_request_quantity"] = item.Quantity;

 

// 4. Description

orderDetail["new_description"] = item.Description;

 

// 5. Unit Price

orderDetail["new_unit_price"] = item.UnitPrice;

 

// 6. Amount

orderDetail["new_amount"] = item.Quantity * item.UnitPrice;

 

using (OrganizationServiceContext orgContext = new OrganizationServiceContext(m_CrmService))

{

    foreach (Entity item in entityList)

    {

        orgContext.AddObject(item);

    }

    orgContext.SaveChanges();

}

6. 发布这个页面,并在实体上加上按钮,调用下面的js

var openURL = "http://12.2.3/ImportOrderDetail.aspx?entityId=";

window.open(openURL + Xrm.Page.data.entity.getId().toString(), "_blank", "dialogWidth=800px;dialogHeight=400px;help:no;status:no");

这里要把主实体的id带过去, 因为插入子实体时要用到,否保存时会报下面的错误:

Exception has been thrown by the target of an invocation

Dynamic CRM 2013学习笔记 系列汇总 -- 持续更新中

Dynamic CRM 2013学习笔记(三十一)自定义用excel批量导入实体数据的更多相关文章

  1. Dynamic CRM 2013学习笔记(十一)利用Javascript实现子表合计(汇总,求和)功能

    我们经常有这样一种需求,子表里新加或修改一数值后,要马上在主表里把它们的和显示在主表上.如果用插件来实现,可以实现求和,但页面上还要刷新一下才能显示正确.这时就考虑到用JS来实现这一功能,并自动刷新页 ...

  2. Dynamic CRM 2013学习笔记 系列汇总

    这里列出所有 Dynamic CRM 2013学习笔记 系列文章,方便大家查阅.有任何建议.意见.需要,欢迎大家提交评论一起讨论. 本文原文地址: Dynamic CRM 2013学习笔记 系列汇总 ...

  3. Dynamic CRM 2013学习笔记(十二)实现子表合计(汇总,求和)功能的通用插件

    上一篇 Dynamic CRM 2013学习笔记(十一)利用Javascript实现子表合计(汇总,求和)功能 , 介绍了如何用js来实现子表合计功能,这种方法要求在各个表单上添加js方法,如果有很多 ...

  4. Dynamic CRM 2013学习笔记(三十二)自定义审批流3 - 节点及实体配置

    上次介绍了<Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示> 以及如何配置自定义审批流的按钮:<Dynamic CRM 2013学习笔记(二十一)自定义 ...

  5. Dynamic CRM 2013学习笔记(三十七)自定义审批流7 - 初始化(整套审批流下载、安装)

    前面介绍了自定义审批流的配置.使用,这篇介绍下如何进行初始化. 一. 下载 从下面的地址下载整个审批流: http://yunpan.cn/cZ5Rdx5HCt3VF 下载完后,一共有三块内容: 二. ...

  6. Dynamic CRM 2013学习笔记(二十一)自定义审批流2 - 配置按钮

    上次介绍了 Dynamic CRM 2013学习笔记(十九)自定义审批流1 - 效果演示 现在开始介绍如何配置审批流,首先在form上添加三个按钮,Submit, Agree, Reject: 1. ...

  7. Dynamic CRM 2013学习笔记(三十三)自定义审批流4 - 规则节点 -有分支的流程处理

    上次介绍过节点的基本配置<Dynamic CRM 2013学习笔记(三十二)自定义审批流3 - 节点及实体配置>,这次介绍下规则节点,因为有时流程里会有一些分支.合并,这时就要用到规则节点 ...

  8. Dynamic CRM 2013学习笔记(三十五)自定义审批流6 - 审批通过后,再审批 - 二次审批

    最近有个特殊的需求,客户想做二次审批,就是审批通过后,再走一次审批流程.最开始一想,这还不简单,审批通过后,直接把状态改成draft就完了,后来一试,发现一堆问题,比如第一次审批完后,界面是不允许修改 ...

  9. Dynamic CRM 2013学习笔记(三十四)自定义审批流5 - 自动邮件通知

    审批过程中,经常要求自动发邮件:审批中要通知下一个审批人进行审批:审批完通知申请人已审批完:被拒绝后,要通知已批准的人和申请人.下面详细介绍如何实现一个自动发邮件的插件:   1. 根据审批状态来确定 ...

随机推荐

  1. js中Array对象方法详解

    操作方法:concat() slice() splice() concat()方法可以基于当前数组中的所有项创建一个新数组.具体来说,这个方法会创建当前数组一个副本,将接收到参数添加到副本的末尾,最后 ...

  2. c#基础-类型基础深入了解

    对象类型需要动态内存,基础类型需要静态内存 动态内存分配在堆上,静态内存分配在栈上. 静态内存保存着简单的变量,如 int a=0; 值类型:把一个值类型赋值给另外一个值类型,改变其中一个另外一个不会 ...

  3. swift 批量 取出中间文本

    func stringmid_pl (wholestring:String,front:String,behind:String,inout return_string:String,getheroi ...

  4. OpenSSL命令---passwd

    NAME passwd - compute password hashes SYNOPSIS openssl passwd [-crypt] [-1] [-apr1] [-salt string] [ ...

  5. mysql 基础语法

    以下为自己学习mysql 的一些笔记,以方便查询 目录 一. ALTER的 语法 二. 表的完整性约束 三. 索引的操作(mysql 数据库支持至少 16 个索引) 四. 视图的操作 五. 触发器的操 ...

  6. TortoiseSVN汉化包装了,不管用,仍然是英文菜单

    TortoiseSVN装了后,把对应的汉化包也装了,但不管用,仍然是英文菜单. 想着是因为没有重启的原因,但是重启了再装,仍然看不到中文工菜单. 想了一下,TortoiseSVN汉化包在装的时候,没有 ...

  7. ln 软链接与硬链接的区别再次回顾

    以下是整理的笔记 软硬链接区别 硬链接 软链接 文件有相同的 inode 及 data block 是另一个文件 只能对已存在的文件进行创建 可以对不存在的文件进行创建 不能交叉文件系统进行硬链接的创 ...

  8. sublime txt 设置在浏览器预览

    1. 安装SideBarEnhancements插件 ctrl+shift+p —> Install Package —> 找到SideBarEnhancements 2. 配置预览快捷键 ...

  9. 第六次课:springMVC与spring的集成

    spring在项目中起到了管理bean的作用,即可以通过配置,让系统自动创建所需的对象,通过一定的方式引用系统创建的对象,对象的创建和引用都是由spring自动完成的,用户不必参与,可以直接引用. 实 ...

  10. 【转】Linux下查看文件和文件夹大小

    当磁盘大小超过标准时会有报警提示,这时如果掌握df和du命令是非常明智的选择. df可以查看一级文件夹大小.使用比例.档案系统及其挂入点,但对文件却无能为力.    du可以查看文件及文件夹的大小. ...