Этот учебник объясняет, как использовать Magicodes.IE.Excel для завершения импорта данных студентов из Excel.
В этом учебнике мы продемонстрируем использование Excel для завершения импорта данных студентов. Нам потребуется установить следующие пакеты в подготовленном проекте с помощью следующих команд:
Install-Package Magicodes.IE.Excel
Основной код представлен ниже:
Данные студента Dto
/// <summary>
/// Dto для импорта данных студентов
/// IsLabelingError: Отмечать ли ошибки данных
/// </summary>
[ExcelImporter(IsLabelingError = true)]
public class ImportStudentDto
{
/// <summary>
/// Серийный номер
/// </summary>
[ImporterHeader(Name = "Серийный номер")]
public long SerialNumber { get; set; }
/// <summary>
/// Номер регистрации студента
/// </summary>
[ImporterHeader(Name = "Номер регистрации студента")]
[MaxLength(30, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string StudentCode { get; set; }
/// <summary>
/// Имя
/// </summary>
[ImporterHeader(Name = "Имя")]
[Required(ErrorMessage = "Имя не может быть пустым")]
[MaxLength(50, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string Name { get; set; }
/// <summary>
/// Номер удостоверения личности
/// </summary>
[ImporterHeader(Name = "Номер удостоверения личности", IsAllowRepeat = false)]
[Required(ErrorMessage = "Номер удостоверения личности не может быть пустым")]
[MaxLength(18, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string IdCard { get; set; }
/// <summary>
/// Пол
/// </summary>
[ImporterHeader(Name = "Пол")]
[Required(ErrorMessage = "Пол не может быть пустым")]
[ValueMapping("Мужской", 0)]
[ValueMapping("Женский", 1)]
public Genders Gender { get; set; }
/// <summary>
/// Адрес проживания
/// </summary>
[ImporterHeader(Name = "Адрес проживания")]
[Required(ErrorMessage = "Адрес проживания не может быть пустым")]
[MaxLength(200, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string Address { get; set; }
/// <summary>
/// Имя родителя
/// </summary>
[ImporterHeader(Name = "Имя родителя")]
[Required(ErrorMessage = "Имя родителя не может быть пустым")]
[MaxLength(50, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string Guardian { get; set; }
/// <summary>
/// Контактный телефон родителей
/// </summary>
[ImporterHeader(Name = "Контактный телефон родителей")]
[MaxLength(20, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string GuardianPhone { get; set; }
/// <summary>
/// Уникальный номер студента
/// </summary>
[ImporterHeader(Name = "Уникальный номер студента")]
[MaxLength(30, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string StudentNub { get; set; }
/// <summary>
/// Номер общежития
/// </summary>
[ImporterHeader(Name = "Номер общежития")]
[MaxLength(20, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string DormitoryNo { get; set; }
/// <summary>
/// Номер ICQ
/// </summary>
[ImporterHeader(Name = "Номер ICQ")]
[MaxLength(30, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string QQ { get; set; }
/// <summary>
/// Национальность
/// </summary>
[ImporterHeader(Name = "Национальность")]
[MaxLength(2, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string Nation { get; set; }
/// <summary>
/// Вид семьи
/// </summary>
[ImporterHeader(Name = "Вид семьи")]
[MaxLength(10, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string HouseholdType { get; set; }
/// <summary>
/// Контактный телефон
/// </summary>
[ImporterHeader(Name = "Контактный телефон")]
[MaxLength(20, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string Phone { get; set; }
/// <summary>
/// Статус
/// Тест для nullable перечислений типов
/// </summary>
[ImporterHeader(Name = "Статус")]
public StudentStatus? Status { get; set; }
/// <summary>
/// Примечания
/// </summary>
[ImporterHeader(Name = "Примечания")]
[MaxLength(200, ErrorMessage = "Количество слов превышает максимальное значение, пожалуйста, исправьте!")]
public string Remark { get; set; }
/// <summary>
/// Живёт ли на кампусе (общежитие)?
/// </summary>
[ImporterHeader(IsIgnore = true)]
public bool? IsBoarding { get; set; }
/// <summary>
/// ID класса
/// </summary>
[ImporterHeader(IsIgnore = true)]
public Guid ClassId { get; set; }
/// <summary>
/// ID школы
/// </summary>
[ImporterHeader(IsIgnore = true)]
public Guid? SchoolId { get; set; }
/// <summary>
/// ID кампуса
/// </summary>
[ImporterHeader(IsIgnore = true)]
public Guid? CampusId { get; set; }
/// <summary>
/// ID специальности
/// </summary>
[ImporterHeader(IsIgnore = true)]
public Guid? MajorsId { get; set; }
/// <summary>
/// ID курса
/// </summary>
[ImporterHeader(IsIgnore = true)]
public Guid? GradeId { get; set; }
}
Как показано выше, мы определили Dto данных студента с учетом следующих основных аспектов:1. Возможность ExcelImporter для установки некоторых глобальных настроек импорта, таких как отметка ошибок, имя импортированного листа (если не указано, первое автоматически выбирается), количество столбцов для чтения и положение заголовков листа.
2. Поддержка обычных настроек проверки данных, таких как обязательность и максимальная длина.
3. Поддержка проверки повторений данных, таких как номер удостоверения личности. Ссылается на функцию ImporterHeader с настройкой IsAllowRepeat.
4. Поддержка настроек заголовков колонок, например свойство ImporterHeader — Name. Кроме того, ImporterHeader поддерживает автоматическую фильтрацию пробелов (включена по умолчанию), удаление всех пробелов, индексацию колонок и т.д.
5. Настройка игнорирования для колонок данных, например SchoolId [ImporterHeader(IsIgnore = true)]
.
6. Использование отображения значений, например атрибут Gender
. Когда отображение значений включено, значения будут получены непосредственно из перечисления, а не из его определения.
7. Поддержка перечислений, поддержка получения отображения значений из Display, Description и других.
Перечисление пола
Определение представлено ниже:
/// <summary>
/// Пол
/// </summary>
public enum Genders
{
/// <summary>
/// Мужской
/// </summary>
Man = 0,
/// <summary>
/// Женский
/// </summary>
Female = 1
}
Обратите внимание на пункт 7 выше.
Перечисление статуса студента
/// <summary>
/// Статус студента: Обычный, Отчисление, Приостановка, Работа-учёба, Прохождение практики, Выпуск, Военная служба
/// </summary>
public enum StudentStatus
{
/// <summary>
/// Обычный
/// </summary>
[Display(Name = "Обычный")] Normal = 0,
/// <summary>
/// Отчисление
/// </summary>
[Description("Отчисление")] PupilsAway = 1,
/// <summary>
/// Приостановка
/// </summary>
[Display(Name = "Приостановка")] Suspension = 2,
/// <summary>
/// Работа-учёба
/// </summary>
[Display(Name = "Работа-учёба")] WorkStudy = 3,
/// <summary>
/// Прохождение практики
/// </summary>
[Display(Name = "Прохождение практики")] PostPractice = 4,
/// <summary>
/// Выпуск
/// </summary>
[Display(Name = "Выпуск")] Graduation = 5,
/// <summary>
/// Военная служба
/// </summary>
[Display(Name = "Военная служба")] JoinTheArmy = 6
}
Обратите внимание на пункт 7 выше.
/// <summary>
/// Импорт
/// </summary>
public interface IImporter
{
/// <summary>
/// Генерация шаблона импорта Excel
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
Task<TemplateFileInfo> GenerateTemplate<T>(string fileName) where T : class, new();
/// <summary>
/// Генерация байтового представления шаблона импорта Excel
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns>Байты файла</returns>
Task<byte[]> GenerateTemplateBytes<T>() where T : class, new();
/// <summary>
/// Импорт данных модели
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="filePath"></param>
/// <returns></returns>
Task<ImportResult<T>> Import<T>(string filePath) where T : class, new();
}
Используя метод GenerateTemplate
, можно получить требуемый шаблон импорта. Конкретное использование можно найти в следующих юнит-тестах.
public IImporter Importer = new ExcelImporter();
[Fact(DisplayName = "Генерация шаблона импорта студентов")]
public async Task GenerateStudentImportTemplate_Test()
{
var filePath = Path.Combine(Directory.GetCurrentDirectory(),
nameof(GenerateStudentImportTemplate_Test) + ".xlsx");
if (File.Exists(filePath)) File.Delete(filePath);
var result = await Importer.GenerateTemplate<ImportStudentDto>(filePath);
result.ShouldNotBeNull();
File.Exists(filePath).ShouldBeTrue();
//TODO: Чтение Excel для проверки заголовков и формата
}
Вышеуказанный DTO получает шаблон и заполняет данные как показано ниже:
Примечание: Перечисление автоматически генерирует выпадающий список, а необходимые заголовки столбцов будут отмечены красным цветом.
После заполнения данных согласно шаблону мы готовы выполнить импорт данных. Обычно у нас есть следующие шаги.
Валидация импортированных данных
Импорт данных через Magicodes.IE.Excel автоматически выполняет валидацию и выводит результаты валидации для отображения на фронте. Конкретнее, мы можем просмотреть его классы с результатами импорта.
/// <summary>
/// Результат импорта
/// </summary>
public class ImportResult<T> where T : class
{
/// <summary>
/// </summary>
public ImportResult()
{
RowErrors = new List<DataRowErrorInfo>();
}
/// <summary>
/// Импортированные данные
/// </summary>
public virtual ICollection<T> Data { get; set; }
/// <summary>
/// Ошибки строки
/// </summary>
public virtual IList<DataRowErrorInfo> RowErrors { get; set; }
/// <summary>
/// Ошибки шаблона
/// </summary>
public virtual IList<TemplateErrorInfo> TemplateErrors { get; set; }
/// <summary>
/// Исключение при импорте
/// </summary>
public virtual Exception Exception { get; set; }
/// <summary>
/// Есть ли ошибки?
/// </summary>
public virtual bool HasError => Exception != null ||
(TemplateErrors?.Count(p => p.ErrorLevel == ErrorLevels.Error) ?? 0) > 0 ||
(RowErrors?.Count ?? 0) > 0;
}
Среди них:
Data — это результат данных
RowErrors — это ошибки валидации строк, такие как обязательность, уникальность, длина текста и т.д., предоставляют номер строки, поле и набор ошибок поля
TemplateErrors — это ошибки шаблона, такие как отсутствие обязательных колонок и другие сообщения об ошибках. Поддерживает уровень ошибки (предупреждение, ошибка)
Exception — это информация об исключении при импорте
HasError — наличие ошибок (без предупреждений)
Через класс ImportResult
мы легко можем получить ошибки валидации импорта без необходимости писать дополнительный код. Обычно нам нужно определить свойство HasError
во время импорта и вернуть конкретный результат ошибки на фронт.
Пример кода для импорта данных представлен ниже:
[Fact(DisplayName = "Импорт базовых данных студентов")]
public async Task StudentInfoImporter_Test()
{
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "TestFiles", "Import", "Студенты_базовые_данные_импорта.xlsx");
var import = await Importer.Import<ImportStudentDto>(filePath);
import.ShouldNotBeNull();
if (import.Exception != null) _testOutputHelper.WriteLine(import.Exception.ToString());
if (import.RowErrors.Count > 0) _testOutputHelper.WriteLine(JsonConvert.SerializeObject(import.RowErrors));
import.HasError.ShouldBeFalse();
import.Data.ShouldNotBeNull();
import.Data.Count.ShouldBe(16);
}
Получение метки верификации
Клиент сказал, что хотя вы намекнули, но я все равно не знаю, что именно неправильно! Что делать?!!!
Мы предусмотрительно подготовили вам метку ошибок файла Excel для импорта данных:
Как открыть этот [Эпический План]? Просто одним шагом:
[ExcelImporter(IsLabelingError = true)]
После активации, мы автоматически сохраним файл метки ошибок "{имя целевого файла}_xlsx" в указанное место.
Получение импортированных данных
Больше нет ошибок? То есть HasError
равен false
, тогда мы просто получаем Data
и делаем с ними что хотим!
Это завершает весь учебник по импорту данных студентов. Связанные библиотеки будут постоянно обновляться, и может возникнуть небольшие различия в опыте использования данной статьи, обратитесь к соответствующему коду, журналам версий и примерам юнит-тестов.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )