Consider this simple block of code that reproduces a simple text with a web hyperlink to a file located in the user's file-system.
Document doc = new Document();
Page page1 = doc.Pages.Add();
TextFragment textFragment = new TextFragment();
TextSegment textSegment = new TextSegment("foo#boo.net");
textSegment.Hyperlink = new Aspose.Pdf.WebHyperlink("Images/foo#boo.net");
textFragment.Segments.Add(textSegment);
page1.Paragraphs.Add(textFragment);
doc.Save(dataDir);
The file name is foo#boo.net and therefor the PDF recognizes it as an Email and automatically adds a mailto: prefix, so instead of opening the file (with some default program) its being opened with Outlook.
This question is followed by my previous question regarding this issue, after many attempts like trying using the new Aspose.Pdf.FileHyperlink("Images/foo#boo.net"); but then it does not open any of the files whatever its name is.
Is it possible to add a TextSegment with a valid mail text so the PDF reader won't add the mailto: prefix?
For example (tested in Chrome):
Solved by escaping the text with zero-width-whitespace (definition) like:
internal static string SafeEscapeMailtoPrefix(this string value)
{
if (string.IsNullOrEmpty(value))
return value;
return value.Replace("#", "\u200B#");
}
So the TextSegment will be like:
TextSegment textSegment = newTextSegment("foo#boo.net".SafeEscapeMailtoPrefix());
Related
How can I find and then hide (or delete) specific text phrase?
For example, I have created a PDF file containing all sorts of data such as images, tables, text etc.
Now, I want to find a specific phrase like "Hello World" wherever it is mentioned in the file and somehow hide it, or -better even- delete it from the PDF.
And finally get the PDF after deleting this phrase.
I have tried iTextSharp and Spire, but couldn't find anything that worked.
Try the following code snippets to hide the specifc text phrase on PDF using Spire.PDF.
using Spire.Pdf;
using Spire.Pdf.General.Find;
using System.Drawing;
namespace HideText
{
class Program
{
static void Main(string[] args)
{
//load PDF file
PdfDocument doc = new PdfDocument();
doc.LoadFromFile(#"C:\Users\Administrator\Desktop\Example.pdf");
//find all results where "Hello World" appears
PdfTextFind[] finds = null;
foreach (PdfPageBase page in doc.Pages)
{
finds = page.FindText("Hello World").Finds;
}
//cover the specific result with white background color
finds[0].ApplyRecoverString("", Color.White, false);
//save to file
doc.SaveToFile("output.pdf");
}
}
}
Result
The following snippet from here let you find and black-out the text in pdf document:
PdfDocument pdf = new PdfDocument(new PdfReader(SRC), new PdfWriter(DEST));
ICleanupStrategy cleanupStrategy = new RegexBasedCleanupStrategy(new Regex(#"Alice", RegexOptions.IgnoreCase)).SetRedactionColor(ColorConstants.PINK);
PdfAutoSweep autoSweep = new PdfAutoSweep(cleanupStrategy);
autoSweep.CleanUp(pdf);
pdf.Close();
Pay attention to the license. It is AGPL, if you don't buy license.
I want to copy the content of a document file to another keeping it formatted. I found a way to copy the whole document to a new one using File.Copy(file, newFile, true); but I need to append the content to another existing one.
Here is a quick code sample that should get you on your way:
using Word = Microsoft.Office.Interop.Word;
var wdApp = new Word.Application();
var documents = wdApp.Documents;
var doc = documents.Open(newFile);
doc.Content.Collapse(Word.WdCollapseDirection.wdCollapseEnd);
doc.Content.InsertFile(file);
I have problems with editing fields inside of an PDF document.
I created a simple invoice with OpenOffice and added some fields via the form creation tool. I exported it as PDF with forms after that.
One of the fields I want to change is named "{Firma}" and I want to fill this field with a string.
Below is a short example-code which doesnt seem to work, the field "{Firma}" in the output-file is still empty.
public static void ReplacePdfForm()
{
string fileNameExisting = #".\template\templaterechnung.pdf";
string fileNameNew = #".\rechnung.pdf";
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
// Open existing PDF
var pdfTemplate = new PdfReader(existingFileStream);
// PdfStamper, (PDF to be changed)
var pdfInvoice = new PdfStamper(pdfTemplate, newFileStream);
AcroFields fields = pdfInvoice.AcroFields;
// set form fields
fields.SetField("{Firma}", "Test1");
pdfInvoice.FormFlattening = true;
pdfInvoice.FreeTextFlattening = true;
pdfInvoice.Close();
pdfTemplate.Close();
}
}
(I have some more fields which also don't change but I deleted them from code because they behave the same way.)
Thanks in advance.
EDIT:
Here's my PDF: http://www.file-upload.net/download-11071404/templaterechnung.pdf.html
EDIT2:
This is how I set the property in OpenOffice:
When creating a form with Open Office, Open Office adds a parameter to the PDF instructing software processing the PDF not to create any appearance streams, but to leave it up to the PDF viewer to create those appearances.
This works as long as the form remains interactive, but as soon as you flatten the form, no appearances are created at all.
You can work around this problem by adding the following line:
fields.GenerateAppearances = true;
This way, you force iTextSharp to generate the appearances.
I have been trying to get my MVC application te create pdf files based on MVC Views. I got this working with plain html. But i would also like to iclude my css files that i use for the browser. Now some of them work but with one i get the following error:
An exception of type 'System.FormatException' occurred in mscorlib.dll but was not handled in user code
Additional information: Input string was not in a correct format.
I am using the following code:
var data = GetHtml(new IndexModel(Context), "~\\Views\\Home\\Index.cshtml", "");
using (var document = new iTextSharp.text.Document())
{
//define output control HTML
var memStream = new MemoryStream();
TextReader xmlString = new StringReader(data);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream("c:\\tmp\\my.pdf", FileMode.OpenOrCreate));
//open doc
document.Open();
// register all fonts in current computer
FontFactory.RegisterDirectories();
// Set factories
var htmlContext = new HtmlPipelineContext(null);
htmlContext.SetTagFactory(Tags.GetHtmlTagProcessorFactory());
// Set css
ICSSResolver cssResolver = XMLWorkerHelper.GetInstance().GetDefaultCssResolver(false);
cssResolver.AddCssFile(HttpContext.Server.MapPath("~/Content/elements.css"), true);
cssResolver.AddCssFile(HttpContext.Server.MapPath("~/Content/style.css"), true);
cssResolver.AddCssFile(HttpContext.Server.MapPath("~/Content/jquery-ui.css"), true);
// Export
IPipeline pipeline = new CssResolverPipeline(cssResolver, new HtmlPipeline(htmlContext, new PdfWriterPipeline(document, writer)));
var worker = new XMLWorker(pipeline, true);
var xmlParse = new XMLParser(true, worker);
xmlParse.Parse(xmlString);
xmlParse.Flush();
document.Close();
}
the string "data" is correct and has no issues, the problem lies with the AddCssFile().
If i create the pdf without and css files everything works, but including the css files triggers the error.
Help will be very much appreciated.
I don't know the exact answer, but by looking at the error you are getting back, I would try two different approaches.
Move the
cssResolver.AddCssFile(HttpContext.Server.MapPath("~/Content/elements.css"), true);
To something like
var cssPath = HttpContext.Server.MapPath("~/Content/elements.css"), true);
cssResolver.AddCssFile(cssPath);
Then set a breakpoint and look at the values being returned for cssPath. Make sure they are accurate and do not contain any odd characters.
Second approach... If all else fails, try giving an absolute URL to the CSS resource such as http://yourdomain.com/cssPath instead of a file system path.
If either of those two appraoches help you, then you can use it to determine the actual problem and then refactor it to your hearts content after that.
UPDATE ------------------------------------------------------------------>
According to the documentation, you need an absolute URL for the file, so Server.MapPath won't work.
addCssFile
void addCssFile(String href,
boolean isPersistent)
throws CssResolverException
Add a
Parameters:
href - the link to the css file ( an absolute uri )
isPersistent - true if the added css should not be deleted on a call to clear
Throws:
CssResolverException - thrown if something goes wrong
In that case, I would try using something like :
public string AbsoluteContent(string contentPath)
{
var path = Url.Content(contentPath);
var url = new Uri(HttpContext.Current.Request.Url, path);
return url.AbsoluteUri;
}
and use it like such :
var cssPath = AbsoluteContent("~/Content/embeddedCss/yourcssfile.css");
In an ASP.NET MVC I have a database table. I want to have a button on some view page, if some user clicks that button I my application will generate XML file containing all rows in the database. Then the file containing XML should be sent to the client so that the user will see a download pop-up window.
Similarly I want to allow user to upload an XML file whose content will be added to the database.
What's the simplest way to let the user upload and download file ?
Thanks for all the answers
EDIT:
This is my approach:
public FileContentResult Download() {
if(model.Series.Count() < 1) {
byte[] content = new byte[0];
return new FileContentResult(content, "Series");
}
XmlSerializer serializer = new XmlSerializer(model.Series.FirstOrDefault().GetType());
MemoryStream xmlStream = new MemoryStream();
foreach (Series s in model.Series) {
serializer.Serialize(xmlStream, s);
}
byte[] content2 = new byte[xmlStream.Length];
xmlStream.Position = 0;
xmlStream.Read(content2, 0, (int) xmlStream.Length);
return File(content2, "Series");
}
Where model is DataContext. Howewer this does not work. When I try to download the data I get this error:
XML Parsing Error: junk after document element
Location: http://localhost:1399/Xml/Download
Line Number 7, Column 10:</Series><?xml version="1.0"?>
---------^
for download part, you could use FileStreamResult
This page has examples for upload and download; check it out.
An XML document can only have one top level element. After the end of the element, you cannot have anything else. It looks like after the "</Series>" element you have "<?xml version="1.0>", which is invalid.