小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

.NET Core一行代碼導入導出Excel生成Word

 蘭亭文藝 2019-06-21

作者:holdengong

鏈接:https://www.cnblogs.com/holdengong/p/10889838.html

簡介

Excel和Word操作在開發(fā)過程中經(jīng)常需要使用,這類工作不涉及到核心業(yè)務(wù),但又往往不可缺少。以往的開發(fā)方式在業(yè)務(wù)代碼中直接引入NPOI、Aspose或者其他第三方庫,工作繁瑣,耗時多,擴展性差——比如基礎(chǔ)庫由NPOI修改為EPPlus,意味著業(yè)務(wù)代碼需要全部修改。

由于工作需要,我在之前版本的基礎(chǔ)上,封裝了OfficeService,目的是最大化節(jié)省導入導出這種非核心功能開發(fā)時間,專注于業(yè)務(wù)實現(xiàn),并且業(yè)務(wù)端與底層基礎(chǔ)組件完全解耦,即業(yè)務(wù)端完全不需要知道底層使用的是什么基礎(chǔ)庫,使得重構(gòu)代價大大降低。

EasyOffice提供了

  • Excel導入:通過對模板類標記特性自動校驗數(shù)據(jù)(后期計劃支持FluentApi,即傳參決定校驗行為),并將有效數(shù)據(jù)轉(zhuǎn)換為指定類型,業(yè)務(wù)端只在拿到正確和錯誤數(shù)據(jù)后決定如何處理;

  • Excel導出:通過對模板類標記特性自動渲染樣式(后期計劃支持FluentApi,即傳參決定導出行為);

  • Word根據(jù)模板生成:支持使用文本和圖片替換,占位符只需定義模板類,制作Word模板,一行代碼導出docx文檔(后期計劃支持轉(zhuǎn)換為pdf);

  • Word根據(jù)Table母版生成:只需定義模板類,制作表格模板,傳入數(shù)據(jù),服務(wù)會根據(jù)數(shù)據(jù)條數(shù)自動復(fù)制表格母版,并填充數(shù)據(jù);

  • Word從空白創(chuàng)建等功能:特別復(fù)雜的Word導出任務(wù),支持從空白創(chuàng)建;

EasyOffice底層庫目前使用NPOI,因此是完全免費的。

通過IExcelImportProvider等Provider接口實現(xiàn)了底層庫與實現(xiàn)的解耦,后期如果需要切換比如Excel導入的基礎(chǔ)庫為EPPlus,只需要提供IExcelImportProvider接口的EPPlus實現(xiàn),并且修改依賴注入代碼即可。

依賴注入

提供了.NET Core自帶ServiceCollection注入和Autofac注入

// Autofac注入Office基礎(chǔ)服務(wù)
builder.AddOffice(new OfficeOptions());

//.NET Core自帶ServiceCollection注入
services.AddOffice(new OfficeOptions());

IExcelImportService - Excel通用導入

定義Excel模板類

public class Car
{
[ColName('車牌號')] //對應(yīng)Excel列名
[Required] //校驗必填
[Regex(RegexConstant.CAR_CODE_REGEX)] //正則表達式校驗,RegexConstant預(yù)置了一些常用的正則表達式,也可以自定義
[Duplication] //校驗?zāi)0孱愒摿袛?shù)據(jù)是否重復(fù)
public string CarCode { get; set; }

[ColName('手機號')]
[Regex(RegexConstant.MOBILE_CHINA_REGEX)]
public string Mobile { get; set; }

[ColName('身份證號')]
[Regex(RegexConstant.IDENTITY_NUMBER_REGEX)]
public string IdentityNumber { get; set; }

[ColName('姓名')]
[MaxLength(10)] //最大長度校驗
public string Name { get; set; }

[ColName('性別')]
[Regex(RegexConstant.GENDER_REGEX)]
public GenderEnum Gender { get; set; }

[ColName('注冊日期')]
[DateTime] //日期校驗
public DateTime RegisterDate { get; set; }

[ColName('年齡')]
[Range(0, 150)] //數(shù)值范圍校驗
public int Age { get; set; }
}

校驗數(shù)據(jù)

var _rows = _excelImportService.ValidateAsync<ExcelCarTemplateDTO>(new ImportOption()
{
FileUrl = fileUrl, //Excel文件絕對地址
DataRowStartIndex = 1, //數(shù)據(jù)起始行索引,默認1第二行
HeaderRowIndex = 0, //表頭起始行索引,默認0第一行
MappingDictionary = null, //映射字典,可以將模板類與Excel列重新映射, 默認null
SheetIndex = 0, //頁面索引,默認0第一個頁簽
ValidateMode = ValidateModeEnum.Continue //校驗?zāi)J?,默認StopOnFirstFailure校驗錯誤后此行停止繼續(xù)校驗,Continue:校驗錯誤后繼續(xù)校驗
}).Result;

//得到錯誤行
var errorDatas = _rows.Where(x => !x.IsValid);
//錯誤行業(yè)務(wù)處理

//將有效數(shù)據(jù)行轉(zhuǎn)換為指定類型
var validDatas = _rows.Where(x=>x.IsValid).FastConvert<ExcelCarTemplateDTO>();

//正確數(shù)據(jù)業(yè)務(wù)處理

轉(zhuǎn)換為DataTable

var dt = _excelImportService.ToTableAsync<ExcelCarTemplateDTO> //模板類型
(
fileUrl, //文件絕對地址
0, //頁簽索引,默認0
0, //表頭行索引,默認0
1, //數(shù)據(jù)行索引,默認1
-1); //讀取多少條數(shù)據(jù),默認-1全部
IExcelExportService - 通用Excel導出服務(wù)

IExcelExportService - 通用Excel導出服務(wù)

定義導出模板類

[Header(Color = ColorEnum.BRIGHT_GREEN, FontSize = 22, IsBold = true)] //表頭樣式
[WrapText] //自動換行
public class ExcelCarTemplateDTO
{
[ColName('車牌號')]
[MergeCols] //相同數(shù)據(jù)自動合并單元格
public string CarCode { get; set; }

[ColName('手機號')]
public string Mobile { get; set; }

[ColName('身份證號')]
public string IdentityNumber { get; set; }

[ColName('姓名')]
public string Name { get; set; }

[ColName('性別')]
public GenderEnum Gender { get; set; }

[ColName('注冊日期')]
public DateTime RegisterDate { get; set; }

[ColName('年齡')]
public int Age { get; set; }

導出Excel

var bytes = await _excelExportService.ExportAsync(new ExportOption<ExcelCarTemplateDTO>()
{
Data = list,
DataRowStartIndex = 1, //數(shù)據(jù)行起始索引,默認1
ExcelType = Bayantu.Extensions.Office.Enums.ExcelTypeEnum.XLS,//導出Excel類型,默認xls
HeaderRowIndex = 0, //表頭行索引,默認0
SheetName = 'sheet1' //頁簽名稱,默認sheet1
});

File.WriteAllBytes(@'c: est.xls', bytes);

IExcelImportSolutionService - Excel導入解決方案服務(wù)(與前端控件配套的完整解決方案,可忽略)

首先定義模板類,參考通用Excel導入

//獲取默認導入模板
var templateBytes = await _excelImportSolutionService.GetImportTemplateAsync<DemoTemplateDTO>();

//獲取導入配置
var importConfig = await _excelImportSolutionService.GetImportConfigAsync<DemoTemplateDTO>('uploadUrl','templateUrl');
//獲取預(yù)覽數(shù)據(jù)
var previewData = await _excelImportSolutionService.GetFileHeadersAndRowsAsync<DemoTemplateDTO>('fileUrl');
//導入
var importOption = new ImportOption()
{
FileUrl = 'fileUrl',
ValidateMode = ValidateModeEnum.Continue
};
object importSetData = new object(); //前端傳過來的映射數(shù)據(jù)
var importResult = await _excelImportSolutionService.ImportAsync<DemoTemplateDTO>
(importOption
, importSetData
, BusinessAction //業(yè)務(wù)方法委托
, CustomValidate //自定義校驗委托
);
//獲取導入錯誤消息
var errorMsg = await _excelImportSolutionService.ExportErrorMsgAsync(importResult.Tag);

IWordExportService - Word通用導出服務(wù)

CreateFromTemplateAsync - 根據(jù)模板生成Word

//step1 - 定義模板類
public class WordCarTemplateDTO
{
//默認占位符為{PropertyName}
public string OwnerName { get; set; }

[Placeholder('{Car_Type Car Type}')] //重寫占位符
public string CarType { get; set; }

//使用Picture或IEnumerable<Picture>類型可以將占位符替換為圖片
public IEnumerable<Picture> CarPictures { get; set; }

public Picture CarLicense { get; set; }
}

//step2 - 制作word模板
//step3 - 導出word
string templateUrl = @'c: emplate.docx';
WordCarTemplateDTO car = new WordCarTemplateDTO()
{
OwnerName = '劉德華',
CarType = '豪華型賓利',
CarPictures = new List<Picture>() {
new Picture()
{
PictureUrl = pic1, //圖片絕對地址,如果設(shè)置了PictureData此項不生效
FileName = '圖片1',//文件名稱
Height = 10,//圖片高度單位厘米默認8
Width = 3,//圖片寬度單位厘米默認14
PictureData = null,//圖片流數(shù)據(jù),優(yōu)先取這里的數(shù)據(jù),沒有則取url
PictureType = PictureTypeEnum.JPEG //圖片類型,默認jpeg
},
new Picture(){
PictureUrl = pic2
}
},
CarLicense = new Picture { PictureUrl = pic3 }
};

var word = await _wordExportService.CreateFromTemplateAsync(templateUrl, car);
File.WriteAllBytes(@'c:ile.docx', word.WordBytes);

CreateWordFromMasterTable-根據(jù)模板表格循環(huán)生成word

//step1 - 定義模板類,參考上面
//step2 - 定義word模板,制作一個表格,填好占位符。
//step3 - 調(diào)用,如下示例,最終生成的word有兩個用戶表格
string templateurl = @'c: emplate.docx';
var user1 = new UserInfoDTO()
{
Name = '張三',
Age = 15,
Gender = '男',
Remarks = '簡介簡介'
};
var user2 = new UserInfoDTO()
{
Name = '李四',
Age = 20,
Gender = '女',
Remarks = '簡介簡介簡介'
};

var datas = new List<UserInfoDTO>() { user1, user2 };

for (int i = 0; i < 10; i++)
{
datas.Add(user1);
datas.Add(user2);
}
var word = await _wordExportService.CreateFromMasterTableAsync(templateurl, datas);
File.WriteAllBytes(@'c:ile.docx', word.WordBytes);

CreateWordAsync - 從空白生成word

//step1 - 定義模板類,參考上面
//step2 - 定義word模板,制作一個表格,填好占位符。
//step3 - 調(diào)用,如下示例,最終生成的word有兩個用戶表格
string templateurl = @'c: emplate.docx';
var user1 = new UserInfoDTO()
{
Name = '張三',
Age = 15,
Gender = '男',
Remarks = '簡介簡介'
};
var user2 = new UserInfoDTO()
{
Name = '李四',
Age = 20,
Gender = '女',
Remarks = '簡介簡介簡介'
};

var datas = new List<UserInfoDTO>() { user1, user2 };
for (int i = 0; i < 10; i++)
{
datas.Add(user1);
datas.Add(user2);
}
var word = await _wordExportService.CreateFromMasterTableAsync(templateurl, datas);

File.WriteAllBytes(@'c:ile.docx', word.WordBytes);
CreateWordAsync - 從空白生成word
[Fact]
public async Task 導出所有日程()
{
//準備數(shù)據(jù)
var date1 = new ScheduleDate()
{
DateTimeStr = '2019年5月5日 星期八',
Addresses = new List<Address>()
};

var address1 = new Address()
{
Name = '會場一',
Categories = new List<Category>()
};

var cate1 = new Category()
{
Name = '分類1',
Schedules = new List<Schedule>()
};

var schedule1 = new Schedule()
{
Name = '日程1',
TimeString = '上午9:00 - 上午12:00',
Speakers = new List<Speaker>()
};

var schedule2 = new Schedule()
{
Name = '日程2',
TimeString = '下午13:00 - 下午14:00',
Speakers = new List<Speaker>()
};

var speaker1 = new Speaker()
{
Name = '張三',
Position = '總經(jīng)理'
};
var speaker2 = new Speaker()
{
Name = '李四',
Position = '副總經(jīng)理'
};
schedule1.Speakers.Add(speaker1);
schedule1.Speakers.Add(speaker2);
cate1.Schedules.Add(schedule1);
cate1.Schedules.Add(schedule2);
address1.Categories.Add(cate1);
date1.Addresses.Add(address1);
var dates = new List<ScheduleDate>() { date1,date1,date1 };
var tables = new List<Table>();
//新建一個表格
var table = new Table()
{
Rows = new List<TableRow>()
};
foreach (var date in dates)
{
//新建一行
var rowDate = new TableRow()
{
Cells = new List<TableCell>()
};
//新增單元格
rowDate.Cells.Add(new TableCell()
{
Color = 'lightblue', //設(shè)置單元格顏色
Paragraphs = new List<Paragraph>()
{
//新增段落
new Paragraph()
{
//段落里面新增文本域
Run = new Run()
{
Text = date.DateTimeStr,//文本域文本,Run還可以
Color = 'red', //設(shè)置文本顏色
FontFamily = '微軟雅黑',//設(shè)置文本字體
FontSize = 12,//設(shè)置文本字號
IsBold = true,//是否粗體
Pictures = new List<Picture>()//也可以插入圖片
},
Alignment = Alignment.CENTER //段落居中
}
}
});
table.Rows.Add(rowDate);
//會場
foreach (var addr in date.Addresses)
{
//分類
foreach (var cate in addr.Categories)
{
var rowCate = new TableRow()
{
Cells = new List<TableCell>()
};

//會場名稱
rowCate.Cells.Add(new TableCell()
{
Paragraphs = new List<Paragraph>{ new Paragraph()
{
Run = new Run()
{
Text = addr.Name,
}
}
}
});
rowCate.Cells.Add(new TableCell()
{
Paragraphs = new List<Paragraph>(){ new Paragraph()
{
Run = new Run()
{
Text = cate.Name,
}
}
}
});
table.Rows.Add(rowCate);
//日程
foreach (var sche in cate.Schedules)
{
var rowSche = new TableRow()
{
Cells = new List<TableCell>()
};
var scheCell = new TableCell()
{
Paragraphs = new List<Paragraph>()
{
new Paragraph()
{
Run = new Run()
{
Text = sche.Name
}
},
{
new Paragraph()
{
Run = new Run()
{
Text = sche.TimeString
}
}
}
}
};
foreach (var speaker in sche.Speakers)
{
scheCell.Paragraphs.Add(new Paragraph()
{
Run = new Run()
{
Text = $'{speaker.Position}:{speaker.Name}'
}
});
}
rowSche.Cells.Add(scheCell);
table.Rows.Add(rowSche);
}
}
}
}
tables.Add(table);
var word = await _wordExportService.CreateWordAsync(tables);
File.WriteAllBytes(fileUrl, word.WordBytes);
}

詳細例子請github下載代碼后自行跑單元測試查看

github地址:https://github.com/holdengong/EasyOffice

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約