知识分享 - 引入单据体数据
金蝶云社区-JohnnyDing
JohnnyDing
17人赞赏了该文章 1.4万次浏览 未经作者许可,禁止转载编辑于2015年12月09日 14:33:52
summary-icon摘要由AI智能服务提供

本文描述了一个在ERP系统中通过Excel文件导入单据体的技术案例。用户首先通过单据A界面的菜单点击引入单据体,然后弹出文件上传动态表单B,用于上传Excel文件。表单B验证文件类型后,解锁确认按钮并上传文件。上传成功后,系统调用第三方工具读取Excel文件为DataSet对象,并逐行将数据填充到单据A的单据体中。代码中展示了如何在单据插件和动态表单插件中实现这一过程,包括文件上传、读取Excel、以及数据填充的具体实现。

需求背景:
部分单据的单据体数据行非常多,在单据维护界面录入效率不高,需要在Excel中录入后导入

技术难点:
1. 如何上传文件?
2. 如何读取上传的Excel文件?

案例设计:
此案例,需要包含两个界面,一个是需要引入单据体的单据A,另外一个,是用于上传文件的动态表单B。

单据A上:
1. 增加一个菜单,引入单据体;
2. 用户点击引入单据体菜单后,弹出一个新窗口(文件上传动态表单B),供用户上传Excel文件
3. 确定文件上传完毕,调用第三方工具,读取Excel内容为DataSet对象
4. 把DataSet中的数据,逐行、逐字段,填写到单据体中

文件上传动态表单B
1. 添加一个文件上传控件,设置文件后缀,必须为*.xls
2. 添加确定、取消两个按钮
3. 默认情况下,确定按钮时锁定的,只有上传文件完毕,才解锁

效果示意:
图一:在单据上增加引入单据体菜单

图二:文件上传界面

图三:待引入的单据体数据

示例代码:
//*************************************************************

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Data;


using Kingdee.BOS;
using Kingdee.BOS.Util;
using Kingdee.BOS.JSON;
using Kingdee.BOS.Core;
using Kingdee.BOS.Core.DynamicForm;
using Kingdee.BOS.Core.DynamicForm.PlugIn;
using Kingdee.BOS.Core.DynamicForm.PlugIn.Args;
using Kingdee.BOS.Core.Bill;
using Kingdee.BOS.Core.Bill.PlugIn;
using Kingdee.BOS.Core.Metadata;
using Kingdee.BOS.Core.Metadata.FieldElement;
using Kingdee.BOS.ServiceHelper.Excel;


namespace JDSample.FormPlugIn.Bill
{
///


/// 引入单据体
///

[Description("引入单据体")]
public class S151209ImportEntryEdit : AbstractBillPlugIn
{
///
/// 菜单点击事件
///

///
public override void AfterBarItemClick(AfterBarItemClickEventArgs e)
{
if (e.BarItemKey.EqualsIgnoreCase("tb_JD_ImportEntry"))
{
// 显示文件上传界面,上传Excel文件
DynamicFormShowParameter showParam = new DynamicFormShowParameter();
showParam.FormId = "a6fe71c4beda4f7baf60411c4b5f3b3e";
this.View.ShowForm(showParam,
new Action((formResult) =>
{
if (formResult != null && formResult.ReturnData != null)
{
string fullFileName = formResult.ReturnData.ToString();
this.DoImportEntry(fullFileName);
}
}));
}
}
///
/// 开始导入单据体
///

/// Excel文件
///
/// 特别说明:此函数仅演示如何把Excel转换为DataSet,
/// 并读取DataSet内容,填写到单据体,
/// 未进行任何的安全处理,实际生产环境,需要对数据的合法性进行严格的判断
///

private void DoImportEntry(string fullFileName)
{
using (ExcelOperation helper = new ExcelOperation(this.View))
{
// 利用ExcelOperation对象,把xml文件,转为DataSet对象
// 参数说明:
// filePath : 完整的文件名,包含了物理目录
// dataStartIndex : 数据开始行索引,从0开始。通常第一行为标题,第二行开始为数据行
// colNameIndex : 列名所在行索引,从0开始。如此参数为0,表明第一行为列名行
DataSet ds = helper.ReadFromFile(fullFileName, 1, 0);

// 取第一个表格中的数据导入
DataTable dt = ds.Tables[0];

int rowIndex = this.Model.GetEntryRowCount("FEntity");
foreach (DataRow dataRow in dt.Rows)
{
// 单据体增加新行,并更新行索引
this.Model.CreateNewEntryRow("FEntity");
this.Model.SetEntryCurrentRowIndex("FEntity",rowIndex);

// 设置基础资料字段值
this.Model.SetItemValueByNumber(
"F_JD_MaterialId", Convert.ToString(dataRow["物料编码"]), rowIndex);

// 设置普通字段值
this.Model.SetValue("F_JD_Qty", dataRow["数量"], rowIndex);

// TODO : 设置其他字段值,此处略
rowIndex++;
}
}
}
}


///
/// 上传单据体数据文件
///

///
/// 界面说明:
/// 1. 添加一个文件上传控件,设置文件后缀,必须为*.xls
/// 2. 添加确定、取消两个按钮
/// 3. 默认情况下,确定按钮时锁定的,只有上传文件完毕,才解锁
///

[Description("上传单据体数据文件")]
public class S151209ImportFileUpdateEdit : AbstractDynamicFormPlugIn
{
///
/// 上传上来的文件名:完整的文件名,包含了物理路径
///

private string _fullFileName = string.Empty;

public override void AfterBindData(EventArgs e)
{
this.View.GetControl("F_JD_BTNOK").Enabled = false;
}

///
/// 文件上传完毕,触发此事件:通过此事件获取上传上来的文件名
///

///
public override void CustomEvents(CustomEventsArgs e)
{
if (e.Key.EqualsIgnoreCase("F_JD_FileUpdate"))
{
this.View.GetControl("F_JD_FileUpdate").SetCustomPropertyValue("NeedCallback", true);
this.View.GetControl("F_JD_FileUpdate").SetCustomPropertyValue("IsRequesting", false);

if (e.EventName.EqualsIgnoreCase("FileChanged"))
{// 文件上传完毕
// 取文件上传参数,文件名
JSONObject uploadInfo = KDObjectConverter.DeserializeObject(e.EventArgs);
if (uploadInfo != null)
{
JSONArray json = new JSONArray(uploadInfo["NewValue"].ToString());
if (json.Count > 0)
{
// 取上传的文件名
string fileName = (json[0] as Dictionary)["ServerFileName"].ToString();
this._fullFileName = this.GetFullFileName(fileName);

// 解锁确定按钮
this.View.GetControl("F_JD_BTNOK").Enabled = true;
}
else
{
// 锁定确定按钮
this.View.GetControl("F_JD_BTNOK").Enabled = false;
}
}
}
}
}

///
/// 按钮点击事件
///

///
public override void ButtonClick(ButtonClickEventArgs e)
{
if (e.Key.EqualsIgnoreCase("F_JD_BTNOK"))
{// 确定
this.View.ReturnToParentWindow(new FormResult(this._fullFileName));
this.View.Close();
}
else if (e.Key.EqualsIgnoreCase("F_JD_BTNCancel"))
{// 取消
this.View.Close();
}
}

///
/// 产生完整的文件名,包含了物理路径
///

///
///
private string GetFullFileName(string fileName)
{
string dir = "FileUpLoadServices\\UploadFiles";
return PathUtils.GetPhysicalPath(dir, fileName);
}
}
}