This demo illustrates how you can find text and add markup to it with the help of the PDF Document API.
@model AspNetCoreDemos.OfficeFileAPI.PdfPreviewModel
<img id="previewImage" src="@Url.Action(Model.PreviewDocumentAction, Model.ControllerName)" class="preview-image-bordered @(Model.IsViewWithoutSidePanel ? "preview-image-without-side-panel" : "preview-image-with-side-panel")" />
<script type="text/javascript">
PdfPreview = {
basePath: '@Url.Action(Model.PreviewDocumentAction, Model.ControllerName)',
Update: function (param) {
var iframeElement = document.getElementById("previewImage");
if (!iframeElement)
return;
var additionalParams = "&" + new Date().valueOf();
if (param)
additionalParams = param;
iframeElement.src = this.basePath + "?" + additionalParams;
}
};
</script>
@model AspNetCoreDemos.OfficeFileAPI.PdfTextMarkupAnnotationsModel
@using DevExtreme.AspNet.Mvc
@{ Html.BeginForm("PdfTextMarkupAnnotationsUploadFiles", "ContentManipulation", FormMethod.Post); }
@Html.HiddenFor(model => model.DocumentUrl)
<script type="text/javascript">
function FindAndMarkup() {
$.ajax({
type: "POST",
url: '@Url.Action("PdfFindAndMarkup", "ContentManipulation")',
data: {
text: $("#Find").dxTextBox('instance').option('value'),
markupType: $("#MarkupType").dxSelectBox('instance').option('value')
},
success: function () { PdfPreview.Update(); }
});
}
function fileUploader_valueChanged(e) {
var files = e.value;
if (files.length > 0) {
$("#selected-files .selected-item").remove();
$.each(files, function (i, file) {
var $selectedItem = $("<div />").addClass("selected-item");
$selectedItem.append(file.name);
$selectedItem.appendTo($("#selected-files"));
});
$("#selected-files").show();
$('#DocumentUrl').val(files[0].name);
}
else
$("#selected-files").hide();
}
function UpdatePreview() {
var params = "DocumentUrl=" + $('#DocumentUrl').val();
PdfPreview.Update(params);
}
</script>
<div class="demo-view-container">
<div style="margin-left: -8px">
@(Html.DevExtreme().FileUploader()
.ID("file-uploader")
.Name("myFile")
.Multiple(false)
.ShowFileList(false)
.Accept(".pdf")
.AllowedFileExtensions(new List<string> { ".pdf" })
.MaxFileSize(10485760)
.LabelText("Maximum file size 10Mb.")
.UploadMode(FileUploadMode.Instantly)
.UploadUrl(Url.Action("DocumentUpload", "ContentManipulation"))
.OnValueChanged("fileUploader_valueChanged")
.OnUploaded("UpdatePreview")
)
</div>
<div class="demo-preview-border">
@(Html.DevExtreme().ScrollView()
.ID("scrollview")
.ScrollByContent(true)
.ScrollByThumb(true)
.ShowScrollbar(ShowScrollbarMode.OnHover)
.Direction(ScrollDirection.Both)
.Height("580px")
.Content(@<text>
<div id="scrollview-content">
@await Html.PartialAsync("PdfFileView", Model.PreviewModel)
</div>
</text>)
)
</div>
</div>
<div class="options">
<div class="caption">Options</div>
<div class="option">
<div class="label">Text to Find</div>
@(Html.DevExtreme().TextBox().ID("Find"))
</div>
<div class="option">
<div class="label">Markup Type</div>
@(Html.DevExtreme().SelectBox()
.ID("MarkupType")
.DataSource(Html.GetEnumSelectList<AspNetCoreDemos.OfficeFileAPI.MarkupType>()
.Select(i => new { Value = int.Parse(i.Value), Text = i.Text }))
.ValueExpr("Value")
.DisplayExpr("Text")
.Value(0)
)
</div>
<div class="option-buttons">
@(Html.DevExtreme().Button()
.Text("Find and Markup")
.Type(ButtonType.Default)
.StylingMode(ButtonStylingMode.Contained)
.OnClick("FindAndMarkup")
)
@(Html.DevExtreme().Button()
.Text("Download")
.Type(ButtonType.Default)
.StylingMode(ButtonStylingMode.Contained)
.UseSubmitBehavior(true)
.ElementAttr("style", "float: right")
)
</div>
</div>
@{ Html.EndForm(); }
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
namespace AspNetCoreDemos.OfficeFileAPI {
public partial class ContentManipulationController : DocumentProcessingController {
public ContentManipulationController(ILogger<ContentManipulationController> logger, IWebHostEnvironment hostingEnvironment)
: base(logger, hostingEnvironment) {
}
}
}
using System.IO;
using Microsoft.AspNetCore.Mvc;
using DevExpress.Pdf;
namespace AspNetCoreDemos.OfficeFileAPI {
public partial class ContentManipulationController {
const string textMarkupDefaultFile = "/Documents/Pdf/TextMarkup.pdf";
protected override string SessionKey => "TextMarkupAnnotationsFileKey";
public IActionResult PdfTextMarkupAnnotations() {
return GetDemoView<PdfTextMarkupAnnotationsModel>("PdfTextMarkupAnnotations", SessionKey, HostingEnvironment.ContentRootPath + textMarkupDefaultFile);
}
public IActionResult DocumentViewPartial(PdfTextMarkupAnnotationsModel textMarkupModel) {
return DocumentViewPartialAnotherDocument(textMarkupModel);
}
public IActionResult PdfTextMarkupAnnotationsUploadFiles() {
using(PdfDocumentProcessor processor = new PdfDocumentProcessor()) {
byte[] data;
if(!HttpContext.Session.TryGetValue(SessionKey, out data))
return new EmptyResult();
using(MemoryStream inputStream = new MemoryStream(data)) {
processor.LoadDocument(inputStream);
MemoryStream resultStream = new MemoryStream();
processor.SaveDocument(resultStream);
return CreateFileStreamResult(resultStream, "application/pdf", "pdf", "Result");
}
}
}
public IActionResult PdfFindAndMarkup(string text, int markupType) {
using(PdfTextMarkupAnnotationsModel model = new PdfTextMarkupAnnotationsModel()) {
byte[] data;
if(HttpContext.Session.TryGetValue(SessionKey, out data)) {
model.LoadDocument(data);
HttpContext.Session.Set(SessionKey, model.FindAndMarkup(text, (PdfTextMarkupAnnotationType)markupType));
}
return new EmptyResult();
}
}
public IActionResult DownloadResult() {
byte[] data;
if(HttpContext.Session.TryGetValue(SessionKey, out data))
return CreateFileStreamResult(new MemoryStream(data), "application/pdf", "pdf", "Result");
return new BadRequestResult();
}
}
}
using System;
using System.Collections.Generic;
using System.IO;
using DevExpress.Pdf;
namespace AspNetCoreDemos.OfficeFileAPI {
public class PdfModelBase : IDisposable {
readonly PdfDocumentProcessor processor;
MemoryStream stream;
List<PdfPageModel> items = new List<PdfPageModel>();
public MemoryStream Stream { get { return stream; } }
protected PdfDocumentProcessor Processor { get { return processor; } }
protected PdfDocument Document { get { return processor.Document; } }
public List<PdfPageModel> Items { get { return items; } }
public string DocumentUrl { get; set; }
public int PageIndex { get; set; }
internal virtual string SessionKey { get; }
public PdfPreviewModel PreviewModel { get; internal set; }
public PdfModelBase() {
processor = new PdfDocumentProcessor();
PreviewModel = new PdfPreviewModel();
}
protected void CreateEmptyDocument() {
stream = new MemoryStream();
Processor.CreateEmptyDocument(stream);
Document.Creator = "PDF Document Processor Demo";
Document.Producer = "Developer Express Inc., " + AssemblyInfo.Version;
Document.Author = "DevExpress Inc.";
}
public virtual void LoadDocument(byte[] data) {
using(MemoryStream stream = new MemoryStream(data))
LoadDocument(stream);
}
protected void LoadDocument(Stream stream) {
processor.LoadDocument(stream, true);
for(int pageNumber = 1; pageNumber <= processor.Document.Pages.Count; pageNumber++)
Items.Add(new PdfPageModel(processor, pageNumber));
}
public void Dispose() {
if(processor != null)
processor.Dispose();
GC.SuppressFinalize(this);
}
}
}
using System.ComponentModel.DataAnnotations;
using System.IO;
using DevExpress.Pdf;
namespace AspNetCoreDemos.OfficeFileAPI {
public enum MarkupType {
Highlight = 0,
Underline = 1,
[Display(Name = "Squiggly underline")]
Squiggly = 2,
Strikeout = 3
}
public class PdfTextMarkupAnnotationsModel : PdfModelBase {
public PdfTextMarkupAnnotationsModel() {
PreviewModel.PreviewDocumentAction = "DocumentViewPartial";
PreviewModel.ControllerName = "ContentManipulation";
}
internal override string SessionKey { get { return "TextMarkupAnnotationsFileKey"; } }
public byte[] FindAndMarkup(string textToFind, PdfTextMarkupAnnotationType markupType) {
PdfDocumentProcessor processor = Processor;
PdfTextSearchResults searchResults = processor.FindText(textToFind);
if(searchResults.Status == PdfTextSearchStatus.Found) {
while(searchResults.Status == PdfTextSearchStatus.Found) {
processor.AddTextMarkupAnnotation(searchResults.PageNumber, searchResults.Rectangles, markupType);
searchResults = processor.FindText(textToFind);
}
}
using (MemoryStream stream = new MemoryStream()) {
processor.SaveDocument(stream);
return stream.ToArray();
}
}
}
}