Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

导出存在BUG #179

Closed
wuyajungo opened this issue Nov 5, 2020 · 15 comments
Closed

导出存在BUG #179

wuyajungo opened this issue Nov 5, 2020 · 15 comments
Assignees
Labels

Comments

@wuyajungo
Copy link

Describe the bug
ExportHelper类下的ParseData函数,
代码行数:633
((IDictionary<string, object>)obj)[propertyInfo.Name] = type.GetProperty(propertyInfo.Name)?.GetValue(dataItem)?.ToString();
数据类型转换时,除bool,枚举外,其他类型均调用ToString()
导致导出的日期,百分比等需要格式化的数据全部为文本,格式化功能失效。

还有一个问题就是我的列数有200多列时,我导出的列顺序跟实体类的属性顺序不一致,目前还没找到问题,是否可以增加列特性用于指定列的排序
以上

@hueifeng hueifeng added the area-excel excel label Nov 5, 2020
@hueifeng
Copy link
Member

hueifeng commented Nov 5, 2020

导致导出的日期,百分比等需要格式化的数据全部为文本,格式化功能失效。

请问您是否指定format?

还有一个问题就是我的列数有200多列时,我导出的列顺序跟实体类的属性顺序不一致,目前还没找到问题,是否可以增加列特性用于指定列的排序

您能否向我们提供实体文件吗?

@wuyajungo
Copy link
Author

导致导出的日期,百分比等需要格式化的数据全部为文本,格式化功能失效。

请问您是否指定format?

还有一个问题就是我的列数有200多列时,我导出的列顺序跟实体类的属性顺序不一致,目前还没找到问题,是否可以增加列特性用于指定列的排序

您能否向我们提供实体文件吗?

是的,实体属性指定Format.

摘取部分如下:
[ImporterHeader(Name = "开始日期(下料)")] [Required(ErrorMessage = "不能为空")] [ExporterHeader(DisplayName = "开始日期(下料)", Format = "yyyy-m-d")] public DateTime StartDate { get; set; } [ImporterHeader(Name = "结束日期(入库)")] [Required(ErrorMessage = "不能为空")] [ExporterHeader(DisplayName = "结束日期(入库)", Format = "yyyy-MM-dd")] public DateTime EndDate { get; set; } [ImporterHeader(Name = "总合格率(外层)")] [Required(ErrorMessage = "不能为空")] [ExporterHeader(DisplayName = "总合格率(外层)", Format = "0.00%")] public decimal PassedRateForOuter { get; set; }

@wuyajungo
Copy link
Author

列数过多时出现的问题目前还未仔细研究,研究定位问题后一并发出来

@xin-lai
Copy link
Collaborator

xin-lai commented Nov 16, 2020

@wuyajungo 列的顺序是可以指定的,有个索引的属性。

@wuyajungo
Copy link
Author

`///


/// 显示名称
///

public string DisplayName { set; get; }

    /// <summary>
    ///     字体大小
    /// </summary>
    public float? FontSize { set; get; }

    /// <summary>
    ///     是否加粗
    /// </summary>
    public bool IsBold { set; get; }

    /// <summary>
    ///     格式化
    /// </summary>
    public string Format { get; set; }

    /// <summary>
    ///     是否自适应
    /// </summary>
    public bool IsAutoFit { set; get; }

    /// <summary>
    ///     自动居中
    /// </summary>
    public bool AutoCenterColumn { get; set; }

    /// <summary>
    ///     是否忽略
    /// </summary>
    public bool IsIgnore { get; set; }

    /// <summary>
    ///     宽度
    /// </summary>
    public int Width { get; set; }`

导出的特性就这些把。没看到有索引?导入倒是有索引

@xin-lai
Copy link
Collaborator

xin-lai commented Nov 22, 2020

@wuyajungo

    /// <summary>
    ///     Excel导出特性
    /// </summary>
    public class ExcelExporterAttribute : ExporterAttribute
    {
        /// <summary>
        ///  输出类型
        /// </summary>
        public ExcelOutputTypes ExcelOutputType { get; set; } = ExcelOutputTypes.DataTable;

        /// <summary>
        ///     自动居中(设置后为全局居中显示)
        /// </summary>
        public bool AutoCenter { get; set; }

        /// <summary>
        ///     表头位置
        /// </summary>
        public int HeaderRowIndex { get; set; } = 1;
    }

@wuyajungo
Copy link
Author

@xin-lai
HeaderRowIndex 这不是表头位置吗?跟列的顺序没有关系吧?
最近老是出现列顺序混乱,但是我debug源码时又是正常的,找不到问题在哪,有点无语。我贴下我的Dto
`///


/// 用于显示,导入的AOI内层实体类
///

[ExcelImporter(IsLabelingError = true)]
[ExcelExporter(Name = "AOI内层", TableStyle = "Medium4")]
[Serializable]
public class F5QualityData_AOI_IN_Dto
{
[ImporterHeader(IsIgnore = true)]
[ExporterHeader(IsIgnore = true)]
public long Id
{
get; set;
}
///
/// 用于页面显示的唯一ID
///

[ImporterHeader(IsIgnore = true)]
[ExporterHeader(IsIgnore = true)]
public string UniqueId{ get; set; }
///
/// 用于页面使用,是否存在子节点
///

[ImporterHeader(IsIgnore = true)]
[ExporterHeader(IsIgnore = true)]
public bool HasChildren { get; set; }
///
/// 日期
///

[ImporterHeader(Name = "日期")]
[Required(ErrorMessage = "日期不能为空")]
[ExporterHeader(DisplayName = "日期", Format = "yyyy-m-d")]
public DateTime CheckDate { get; set; }
///
/// 员工姓名
///

[ImporterHeader(Name = "员工姓名")]
[Required(ErrorMessage = "员工姓名不能为空")]
[MaxLength(20, ErrorMessage = "测试治具最大长度20")]
[ExporterHeader(DisplayName = "员工姓名")]
public string CheckUserName { get; set; }

    [ImporterHeader(Name = "料号")]
    [Required(ErrorMessage = "料号不能为空")]
    [ExporterHeader(DisplayName = "料号")]
    public string InvPartNumber { get; set; }
    /// <summary>
    /// 检查总数PANEL
    /// </summary>
    [ImporterHeader(Name = "检测总数(PNL)")]
    [Required(ErrorMessage = "检测总数(PNL)不能为空")]
    [ExporterHeader(DisplayName = "检测总数(PNL)")]
    public int CheckQTY_PNL { get; set; }
    /// <summary>
    /// 排版SET数
    /// </summary>
    [ImporterHeader(Name = "排版SET数")]
    [Required(ErrorMessage = "排版SET数不能为空")]
    [ExporterHeader(DisplayName = "排版SET数")]
    public int PnlSet { get; set; }
    /// <summary>
    /// 排版SET总数=CheckQTY_PNL* PnlSet
    /// </summary>
    [ImporterHeader(IsIgnore = true)]
    [ExporterHeader(DisplayName = "排版SET总数")]
    public int CheckQTY_SET { get; set; }

    [ImporterHeader(Name = "PO")]
    [MaxLength(40, ErrorMessage = "测试治具最大长度40")]
    [ExporterHeader(DisplayName = "PO")]
    public string PONumber { get; set; }

    //层别信息--------------------------
    /// <summary>
    /// 层别名称
    /// </summary>
    [ImporterHeader(Name = "层别")]
    [Required(ErrorMessage = "层别不能为空")]
    [MaxLength(10, ErrorMessage = "层别最大长度10")]
    [ExporterHeader(DisplayName = "层别")]
    public string LayerName { get; set; }
    /// <summary>
    /// 不良数=修补,报废所有缺陷数总和
    /// </summary>
    [ImporterHeader(IsIgnore = true)]
    [ExporterHeader(DisplayName = "不良数(点)")]
    public int BadQTY { get; set; }
    /// <summary>
    /// 报废数=报废数总和
    /// </summary>
    [ImporterHeader(IsIgnore = true)]
    [ExporterHeader(DisplayName = "报废总数(SET)")]
    public int ScrapQTY { get; set; }
    /// <summary>
    /// 一次直行率(点)=(CheckQTY_SET*2-BadQTY)/(CheckQTY_SET*2)
    /// </summary>
    [ImporterHeader(IsIgnore = true)]
    [ExporterHeader(DisplayName = "一次直行率(点)", Format = "0.00%")]
    public decimal? DirectRate { get; set; }
    /// <summary>
    /// 修补后良率=(CheckQTY_SET-ScrapQTY)/CheckQTY_SET
    /// </summary>
    [ImporterHeader(IsIgnore = true)]
    [ExporterHeader(DisplayName = "修补后良率(点)", Format = "0.00%")]
    public decimal? RepairRate { get; set; }

    //具体项目
    /// <summary>
    /// 判定项  - 修补/报废
    /// </summary>
    [ImporterHeader(Name = "判定项")]
    [Required(ErrorMessage = "判定项不能为空")]
    [ValueMapping("修补", "修补")]
    [ValueMapping("报废", "报废")]
    [ExporterHeader(DisplayName = "判定项")]
    public string JudgeItem { get; set; }

    [ImporterHeader(Name = "开路")]
    [ExporterHeader(DisplayName = "开路")]
    public int? DefectQty1 { get; set; }

    [ImporterHeader(Name = "缺口")]
    [ExporterHeader(DisplayName = "缺口")]
    public int? DefectQty2 { get; set; }

    [ImporterHeader(Name = "短路")]
    [ExporterHeader(DisplayName = "短路")]
    public int? DefectQty3 { get; set; }

    [ImporterHeader(Name = "曝光不良")]
    [ExporterHeader(DisplayName = "曝光不良")]
    public int? DefectQty4 { get; set; }

    [ImporterHeader(Name = "蚀刻不净")]
    [ExporterHeader(DisplayName = "蚀刻不净")]
    public int? DefectQty5 { get; set; }

    [ImporterHeader(Name = "残铜毛刺")]
    [ExporterHeader(DisplayName = "残铜毛刺")]
    public int? DefectQty6 { get; set; }

    [ImporterHeader(Name = "孔内无铜")]
    [ExporterHeader(DisplayName = "孔内无铜")]
    public int? DefectQty7 { get; set; }

    [ImporterHeader(Name = "孔内毛刺")]
    [ExporterHeader(DisplayName = "孔内毛刺")]
    public int? DefectQty8 { get; set; }

    [ImporterHeader(Name = "掉膜")]
    [ExporterHeader(DisplayName = "掉膜")]
    public int? DefectQty9 { get; set; }

    [ImporterHeader(Name = "线细")]
    [ExporterHeader(DisplayName = "线细")]
    public int? DefectQty10 { get; set; }

    [ImporterHeader(Name = "铜渣")]
    [ExporterHeader(DisplayName = "铜渣")]
    public int? DefectQty11 { get; set; }

    [ImporterHeader(Name = "针孔")]
    [ExporterHeader(DisplayName = "针孔")]
    public int? DefectQty12 { get; set; }

    [ImporterHeader(Name = "撞断线")]
    [ExporterHeader(DisplayName = "撞断线")]
    public int? DefectQty13 { get; set; }

    [ImporterHeader(Name = "折板")]
    [ExporterHeader(DisplayName = "折板")]
    public int? DefectQty14 { get; set; }

    [ImporterHeader(Name = "孔塞")]
    [ExporterHeader(DisplayName = "孔塞")]
    public int? DefectQty15 { get; set; }

    [ImporterHeader(Name = "孔偏破")]
    [ExporterHeader(DisplayName = "孔偏破")]
    public int? DefectQty16 { get; set; }

    [ImporterHeader(Name = "多/少孔")]
    [ExporterHeader(DisplayName = "多/少孔")]
    public int? DefectQty17 { get; set; }

    [ImporterHeader(Name = "压痕")]
    [ExporterHeader(DisplayName = "压痕")]
    public int? DefectQty18 { get; set; }

    [ImporterHeader(Name = "杂物")]
    [ExporterHeader(DisplayName = "杂物")]
    public int? DefectQty19 { get; set; }

    [ImporterHeader(Name = "划伤")]
    [ExporterHeader(DisplayName = "划伤")]
    public int? DefectQty20 { get; set; }

    [ImporterHeader(Name = "其它")]
    [ExporterHeader(DisplayName = "其它")]
    public int? DefectQty21 { get; set; }
}`

然后导出来的excel列顺序是这样的。

开路 | 缺口 | 短路 | 曝光不良 | 蚀刻不净 | 残铜毛刺 | 孔内无铜 | 孔内毛刺 | 掉膜 | 线细 | 铜渣 | 针孔 | 撞断线 | 折板 | 孔塞 | 孔偏破 | 多/少孔 | 压痕 | 杂物 | 划伤 | 其它 | 日期 | 员工姓名 | 料号 | 检测总数(PNL) | 排版SET数 | 排版SET总数 | PO | 层别 | 不良数(点) | 报废总数(SET) | 一次直行率(点) | 修补后良率(点) | 判定项

另外,啥时候发布下一个稳定版啊?NUGET上,那个Format的问题等着修复呢

@xin-lai
Copy link
Collaborator

xin-lai commented Dec 4, 2020

@wuyajungo 2.5 已发布
HeaderRowIndex 确实是表头位置,是我看错了。

@wuyajungo
Copy link
Author

@xin-lai
好的,感谢,这就去更新2.5
另外,还是建议能不能在导出时也加一个ColumnIndex ,用来指定列的位置。

@xin-lai
Copy link
Collaborator

xin-lai commented Dec 4, 2020

@xin-lai
好的,感谢,这就去更新2.5
另外,还是建议能不能在导出时也加一个ColumnIndex ,用来指定列的位置。

与导入不同,感觉导出指定ColumnIndex 有些显得多余,理论是列顺序应该是由属性的位置决定的。我们先确定导出Excel列的顺序是否和属性位置一致。

@wuyajungo
Copy link
Author

wuyajungo commented Dec 7, 2020

@xin-lai
今天更新了2.5,仍然在导出List时出现列顺序与属性顺序不一致的问题,这个问题不好重现,好像时有时无,有的Dto存在,有的不存在。
查询了MSDN对Type.GetProperties 方法的注释。
https://docs.microsoft.com/zh-cn/dotnet/api/system.type.getproperties?redirectedfrom=MSDN&view=netframework-4.8
里面有一句话说到这种情况:
GetProperties方法不按特定顺序(如字母顺序或声明顺序)返回属性。 你的代码不能依赖属性的返回顺序,因为该顺序会有所不同。
可能是导致此问题的原因,请教该如何处理?

@xin-lai
Copy link
Collaborator

xin-lai commented Dec 21, 2020

@wuyajungo 非常感谢。我们来跟进和处理。

@xin-lai
Copy link
Collaborator

xin-lai commented Dec 21, 2020

@wuyajungo 目前考虑在导出这块增加ColumnIndex以支持导出列排序。

@wuyajungo
Copy link
Author

好的。非常期待发布下一版本

@xin-lai
Copy link
Collaborator

xin-lai commented Dec 21, 2020

@wuyajungo 已发布2.5.1

@xin-lai xin-lai self-assigned this Dec 21, 2020
@xin-lai xin-lai closed this as completed Feb 26, 2021
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants