Skip to content
New issue

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

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

Already on GitHub? Sign in 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants