在ASP.NETCore中如何将各种文档合并为PDF?Aspose快速搞定!

在ASP.NETCore中如何将各种文档合并为PDF?Aspose快速搞定!

2023年7月14日发(作者:)

在e中如何将各种⽂档合并为PDF?Aspose快速搞定!在各种业务环境中,将各种⽂档合并为⼀个PDF是客户最常问的问题之⼀。例如,假设您的组织有多个应⽤程序以XPS和PDF⽣成特定的⽂档,使⽤扫描的图像,并且您的⽤户希望将其中⼀些⽂档合并为⼀个PDF。本⽂演⽰了如何使⽤ Core框架将多个⽂档合并到⼀个PDF中。提出了⼏种使⽤.NET合并PDF的⽅法,这些内容在本⽂中进⾏了介绍。在本⽂中,将讨论以下主题:如何使⽤ Core Web API上传PDF或其他⽂档;如何实现简单的Web UI来选择要合并的PDF⽂件;如何实现⽤于合并PDF的简单Web API容器;在本⽂中,我们将创建⼀个简单的 Web API应⽤程序,该应⽤程序允许我们上载⽂档,选择2个或更多⽂件进⾏合并以及下载结果。实施 Core Web App以将各种⽂档合并为PDF步骤1:创建⼀个 Core Web应⽤程序我们将为此应⽤程序使⽤Web应⽤程序(模型-视图-控制器)模板。创建基本应⽤程序后,我们将需要执⾏⼀些其他操作。为.NET库添加作为依赖项(通过Nuget软件包管理器);添加库;将临时⽂件和⽂档的wwwroot⽂件夹添加到该⽂件夹(例如files和temp);在中创建相应的属性"Folders": { "Files": "files", "Temporary" : "temp"

}

步骤2:实施Web API控制器以管理服务器上的⽂件我们的控制器应执⾏以下操作:返回具有某些扩展名的⽂件列表(在本⽰例中,将仅显⽰.pdf,.jpg和.oxps⽂件);允许按⽂件名下载⽂件;允许通过⽂件名删除服务器上的⽂件;using ;using g;using ;using g;using c;using ;using ;using uration;namespace llers{ [Route("api/[controller]")] [ApiController] public class FilesController : ControllerBase { private readonly Dictionary _contentType; private readonly ILogger _logger; private readonly string _storageRootFolder; public FilesController(ILogger logger, IWebHostEnvironment env, IConfiguration configuration) { _logger = logger; _storageRootFolder = e(tPath, configuration["Folders:Files"]);

_contentType = new Dictionary { { ".txt", "text/plain"}, { ".pdf", "application/pdf"}, { ".doc", "application/-word"}, { ".docx", "application/-word"}, { ".xls", "application/-excel"}, { ".xlsx", "application/"}, { ".png", "image/png"}, { ".jpg", "image/jpeg"}, { ".jpeg", "image/jpeg"}, { ".gif", "image/gif"}, { ".csv", "text/csv"} }; } // GET: /api/files

[HttpGet] public IEnumerable GetFiles() { _ormation($"Get files from {_storageRootFolder}"); var files = new DirectoryInfo(_storageRootFolder).EnumerateFiles("*.pdf").ToList(); var files = new DirectoryInfo(_storageRootFolder).EnumerateFiles("*.pdf").ToList(); ge(new DirectoryInfo(_storageRootFolder).EnumerateFiles("*.jpg")); ge(new DirectoryInfo(_storageRootFolder).EnumerateFiles("*.oxps")); //TODO: add other file types below

return (f => new FileViewModel { Name = , Size = }); } [HttpGet("{id}")] public IActionResult OnGetFile(string id) { _ormation($"Get file {id}"); var fileName = e(_storageRootFolder, id); return File(ad(fileName), _contentType[ension(fileName)]); } [HttpDelete("{id}")] public IActionResult OnDeleteFile(string id) { _ormation($"Delete file {id}"); var fileName = e(_storageRootFolder, id); (fileName); return Ok(); }

}}然后将使⽤附加的库来加载⽂件,因此将与加载⽂件相关的代码移⾄单独的控制器是有意义的。步骤3:实现Web API控制器以使⽤上传⽂件库的主要功能是它允许您分块加载⽂件。因此,我们需要实现⼀些⽅法来处理此过程:HTTP GET请求的⽅法,该⽅法应检查服务器上是否存在块;HTTP POST请求的⽅法,该⽅法应该是服务器上的上传块;其他辅助⽅法(⽤于HTTP OPTIONS请求,合并块等)using g;using ;using ;using g;using ;using uration;namespace llers{ [Route("api/[controller]")] [ApiController] public class UploadController : ControllerBase { private readonly ILogger_logger; private readonly string _storageRootFolder; private readonly string _filesRootFolder; public UploadController( ILoggerlogger, IConfiguration configuration, IWebHostEnvironment env) { _logger = logger; _storageRootFolder = e(tPath, configuration["Folders:Temporary"]); _filesRootFolder = e(tPath, configuration["Folders:Files"]); if (!(_storageRootFolder)) Directory(_storageRootFolder); } [HttpOptions] public object UploadFileOptions() { return Ok(); } [HttpGet] public object Upload(int resumableChunkNumber, string resumableIdentifier) { _ormation($"Check if chunck {resumableChunkNumber} from {resumableIdentifier} is here.");

return ChunkIsHere(resumableChunkNumber, resumableIdentifier) ? Ok() : StatusCode(418); } [HttpPost] public IActionResult Upload( [FromQuery(Name = "ResumableIdentifier")] string resumableIdentifier, [FromQuery(Name = "ResumableFilename")] string resumableFilename, [FromQuery(Name = "ResumableChunkNumber")] int resumableChunkNumber, [FromQuery(Name = "ResumableTotalChunks")] int resumableTotalChunks, IFormFile file) { _ormation(me); var stream = (GetChunkFileName(resumableChunkNumber, resumableIdentifier)); (stream); (); TryAssembleFile(resumableFilename, resumableIdentifier, resumableTotalChunks); return Ok(); } #region Chunk methods [NonAction] private string GetChunkFileName(int chunkNumber, string identifier) { return e(_storageRootFolder, $"{identifier}_{chunkNumber}"); } [NonAction] private string GetFilePath(string identifier) { return e(_storageRootFolder, identifier); } [NonAction] private bool ChunkIsHere(int chunkNumber, string identifier) { return (GetChunkFileName(chunkNumber, identifier)); } [NonAction] private bool AllChunksAreHere(string identifier, int chunks) { for (var chunkNumber = 1; chunkNumber <= chunks; chunkNumber++) if (!ChunkIsHere(chunkNumber, identifier)) return false; return true; }

[NonAction] private void DeleteChunks(string identifier, int chunks) { for (var chunkNumber = 1; chunkNumber <= chunks; chunkNumber++) { var

chunkFileName = GetChunkFileName(chunkNumber, identifier); (chunkFileName); } } [NonAction] private string

ConsolidateFile(string identifier, int chunks) { var path = GetFilePath(identifier); using var destStream = (path, 15000); for (var

chunkNumber = 1; chunkNumber <= chunks; chunkNumber++) { var chunkFileName = GetChunkFileName(chunkNumber, identifier); using var

sourceStream = ad(chunkFileName); (destStream); } (); return path; } [NonAction]

private void TryAssembleFile(string rfn, string ri, int rtc) { if (AllChunksAreHere(ri, rtc)) { // Create a single file var path = ConsolidateFile(ri, rtc); //

Move consolidated file (path, e(_filesRootFolder, rfn),true); // Delete chunk files DeleteChunks(ri, rtc); } }

#endregion } }该库将标识符⽤于内部⽬的。它可以以不同的⽅式⽣成。在⽰例应⽤程序中,我们使⽤了⼀个单独的控制器。using ;using System;using ;namespace llers{ [Route("api/[controller]")] [ApiController] public class TokenController : ControllerBase { // GET: api/Token?id= [HttpGet("{id}")] public string OnGet(string id) { var hash = new 1Managed() .ComputeHash(es(id + ng())); return ((b => ng("x2"))); } }}步骤4:为合并的应⽤程序实现Web UI现在,我们可以开始实现Web界⾯了。在⽰例应⽤程序中,我们没有使⽤Angular,React Vue或其他框架,但是我们实现了基于Bootstrap和JQuery的单页应⽤程序。应⽤程序页⾯可以分为两个部分:服务器上的⽂件部分将使我们可以查看服务器上的⽂件,下载或删除它们。此外,⽤户可以通过单击⽂件名来选择要合并的⽂档。要获取合并的⽂档,⽤户应单击“合并”按钮,合并的⽂档将显⽰在⽂件列表中。“上载⽂件”部分仅⽤于上载⽂件。由于该⽹页的代码量很⼤,因此在此不再显⽰,我们将完全局限于描述该算法的两个想法。合并序列中的⽂件位置存储在与其对应的单元格的data-order属性中。因此,要将⽂件合并为⼀个PDF,我们应该获取所有数据顺序,对它们进⾏排序并发送⽂件名序列;要选择/取消选择要合并的⽂件,请单击⽂件名。选定的⽂件标有徽章;以下代码段演⽰了这两种操作的处理程序:let lastIndex = 0;function selectFileClickHandler() { let order = parseInt($(this).attr('data-order')); if (order > 0) { $(this).attr('data-order', '0'); $(this).find('span').hide('slow'); for (let cell of $("*[data-order]")) { let currentOrder = parseInt(); if (currentOrder > order) { = currentOrder - 1; TML = currentOrder - 1; } } lastIndex--; } else { $(this).attr('data-order', ++lastIndex); $(this).find('span').html(lastIndex); $(this).find('span').show('slow'); } $('#btnMerge').prop('disabled', lastIndex<2);}$('#btnMerge').click((e) => { tDefault(); const files = $('*[data-order]').sort(function (a, b) { const contentA = parseInt($(a).data('order')); const contentB = parseInt($(b).data('order')); return (contentA < contentB) ? -1 : (contentA > contentB) ? 1 : 0; }); const data = []; for (let file of files) { const currentOrder = parseInt(); if (currentOrder > 0) (); } fetch('api/merge/', { method: 'POST', mode: 'cors', cache: 'no-cache', credentials: 'same-origin', headers: { 'Content-Type': 'application/json' }, redirect: 'follow', referrerPolicy: 'no-referrer', body: ify(data) } ) .then(res => ()) .then(res => { (res); refreshFileTable(); }) .catch(err => alert(err)); lastIndex = 0;});将各种⽂档合并为PDF完成准备阶段后,我们可以考虑项⽬的主要部分。.NET库的提供了⼏种合并⽂档的⽅法。您可以在上⼀篇⽂章中学习其中的⼀些内容,但是现在我们将重点介绍⼀下,并讨论影响PDF中任何⽂档的可能性。实际上,如果⽂档为PDF格式,那么我们必须执⾏两个操作,然后合并;如果⽂档不是PDF,则⾸先进⾏转换然后合并。步骤1:实施Web API控制器以将各种⽂档合并为PDFusing ;using g;using ;using g;using System;using c;using g;using ;namespace llers{ [Route("api/[controller]")] [ApiController] public class MergeController : ControllerBase { private readonly ILogger _logger; private readonly string _storageRootFolder; public MergeController(ILogger logger, IWebHostEnvironment env) { _logger = logger; _storageRootFolder = e(tPath, "files"); //var license = new License(); //ense(@""); } // POST: /api/merge

[HttpPost] public IActionResult PostMergeFiles(IEnumerable list) { //TODO: Implement Image to PDF conversion throw new NotImplementedException(); }

}}如您所见,我们的控制器调⽤HTTP-Post⽅法来合并⽂档。现在我们实现此⽅法。我们合并的想法是将所有页⾯从⼀个⽂档添加到另⼀个⽂档。这很简单,因为我们知道Document类包含⼀个Pages集合,⽽最后⼀个具有Add⽅法。// POST: /api/merge

[HttpPost] public IActionResult PostMergeFiles(IEnumerable list) { var document = new Document(); foreach (var item in list) { var filePath = e(_storageRootFolder, item); var pdfDocument = ension(item) switch { ".jpg" => ConvertFromImage(filePath), ".jpeg" => ConvertFromImage(filePath), ".png" => ConvertFromImage(filePath), ".oxps" => new Document(filePath, new XpsLoadOptions()), _ => new Document(filePath) }; (); e(); } var guid = d(); (e(_storageRootFolder, $"{guid}.pdf")); _ormation($"The merge result saved as: {guid}"); return Ok(new { filename = ng() }); } private Document ConvertFromImage(string filePath) { var docStream = new MemoryStream(); var doc = new Document(); var page = (); var image = new { ImageStream = new FileStream(filePath, , ) }; = 0; = 0; = 0; = 0; var imageSize = ream(tream).Size; = ; = ; (image); (docStream); return doc; } }步骤2:实现⽤于将图像转换为PDF的辅助⽅法private Document ConvertFromImage(string filePath) { var docStream = new MemoryStream(); var doc = new Document(); var page = (); var image = new { ImageStream = new FileStream(filePath, , ) }; = 0; = 0; = 0; = 0; var imageSize = ream(tream).Size; = ; = ; (image); (docStream); return doc; }本⽂⽰例演⽰了库在 Core环境中的正常运⾏。该应⽤程序的⽬的是展⽰使⽤.NET Core的合并任何⽂档并将其保存为PDF格式的可能性,并且可能需要对其进⾏改进。例如,此程序不考虑保存具有相同名称的⽂件。该问题的可能解决⽅案是使⽤具有⽣成名称的⽂件夹上载每个⽂档或使⽤数据库存储⽂件。如果您有任何疑问或需求,请随时加⼊Aspose技术交流群(642018183),我们很⾼兴为您提供查询和咨询。

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689309355a228507.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信