Dynamic CRM 2013學習筆記(三十一)自定義用excel批量導入實體數據


有一個實體的子表數據量太大,於是客戶想用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學習筆記 系列匯總 -- 持續更新中


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM