I have tried and searched for this question but with no luck.
This is what I have tried.
using (PdfDocument doc = new PdfDocument(new PdfReader(template), new
PdfWriter(newPath)))
{
PdfAcroForm form = PdfAcroForm.GetAcroForm(doc, true);
// Replace form fields with correct data
form.GetField("Greet").SetValue("Hello world!");
// I have tried this to with no luck
form.GetField("Greet").SetJustification(1).SetValue("Hello World");
form.FlattenFields();
}
Pdf does not support justification for acro-forms.
So this is not an iText problem. The spec simply doesn't allow it.
Related
I'm attempting to add form fields to an existing PDF in a .NET 7.0.0 app using iText7 7.2.4 on Mac and I cannot get multiline text fields to honor wrapping without doing a weird hack.
The following code illustrates the issue:
using iText.Forms;
using iText.Forms.Fields;
using iText.IO.Font.Constants;
using iText.Kernel.Colors;
using iText.Kernel.Font;
using iText.Kernel.Geom;
using iText.Kernel.Pdf;
// Create a new PDF document
PdfDocument pdf = new PdfDocument(new PdfWriter("my_document.pdf"));
// Create a page and add it to the document
PdfPage page = pdf.AddNewPage();
// Create an AcroForm and add it to the document
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdf, true);
// Create a multiline text field that should wrap but does not.
PdfTextFormField nonWrapping = PdfFormField.CreateText
(pdf,
new Rectangle(25, 727, 100, 100),
"multiline-field-without-wrapping",
String.Concat(Enumerable.Repeat("Hello World ", 10)),
PdfFontFactory.CreateFont(StandardFonts.HELVETICA),
9.0F);
nonWrapping.SetMultiline(true);
form.AddField(nonWrapping);
// Create a multiline text field that DOES wrap but
// only because we set a background color.
PdfTextFormField wrapping = PdfFormField.CreateText
(pdf,
new Rectangle(150, 727, 100, 100),
"multiline-field-with-wrapping",
String.Concat(Enumerable.Repeat("Hello World ", 10)),
PdfFontFactory.CreateFont(StandardFonts.HELVETICA),
9.0F);
wrapping.SetMultiline(true);
wrapping.SetBackgroundColor(new DeviceRgb(0.9F, 0.9F, 0.99F));
form.AddField(wrapping);
// Close the document
pdf.Close();
It will result in a PDF that looks like this in Preview:
The only way I can get wrapping to work is by including background color. I don't want to do this but it's the only thing that works.
If I could set the opacity of the background color, that might also be acceptable but so far, I've been unable to find anything in the code or docs that would support this.
In C# I'm trying to pass in a simple HTML string and have the string parsed and added to a PDF document. In the below examples, I'm adding the string to an iText7 Paragraph.
I read this article and managed to write the below code.
https://itextpdf.com/en/resources/books/itext-7-converting-html-pdf-pdfhtml/chapter-1-hello-html-pdf
The first paragraph (p1), Example 1, renders the correct font face, Helvetica. Of course, I'm using the SetAction method, which is completely a different approach than the article. This is for demo purposes only.
The second paragraph (p2), Example 2, converts the HTML just fine but the font for the word "link" is rendered differently than Helvetica. It seems that when HTML is rendered, it ignores the font face of the document.
Sample Screenshot
How can I get the font face of "link" to be Helvetica and use the approach in Example 2? I think I'm missing something minor here. Do I need to define a CSS class since we're in HTML land?
Thank you for any suggestions.
class Program
{
static void Main(string[] args)
{
var pdfWriter = new PdfWriter(#"c:\temp\test.pdf");
var pdfDocument = new PdfDocument(pdfWriter);
var document = new Document(pdfDocument);
// Example 1
var p1 = new Paragraph("p1: this is a test url")
.SetFont(PdfFontFactory.CreateFont(StandardFonts.HELVETICA))
.SetFontSize(12f)
.SetFontColor(new DeviceCmyk(1f, .31f, 0, 0))
.SetFixedPosition(35, 600, UnitValue.CreatePercentValue(100f))
.SetAction(PdfAction.CreateURI("www.google.com"));
document.Add(p1);
// Example 2
var html = #"p2: this is a test url";
var elements = HtmlConverter.ConvertToElements(html);
var p2 = new Paragraph()
.SetFont(PdfFontFactory.CreateFont(StandardFonts.HELVETICA))
.SetFontSize(12f)
.SetFontColor(new DeviceCmyk(1f, .31f, 0, 0))
.SetFixedPosition(35, 550, UnitValue.CreatePercentValue(100f));
foreach (var element in elements)
{
p2.Add((IBlockElement)element);
}
document.Add(p2);
document.Close();
pdfDocument.Close();
pdfWriter.Close();
}
}
The default font-family in pdfHTML is Times, and you are overriding it only for the top-level elements while (almost) all the elements at all nesting levels have their font family explicitly specified after ConvertToElements invocation. To change the font family the easiest solution is indeed apply some CSS to your initial HTML. You can set font-family in style declaration directly:
var html = #"<p style=""font-family: Helvetica"">p2: this is a test url</p>";
Then you don't even have to set font to your paragraph and the paragraph creation code simplifies to
var p2 = new Paragraph()
.SetFontSize(12f)
.SetFontColor(new DeviceCmyk(1f, .31f, 0, 0))
.SetFixedPosition(35, 550, UnitValue.CreatePercentValue(100f));
foreach (var element in elements)
{
p2.Add((IBlockElement)element);
}
I wrote a script to add an image from my Google Drive and some custom text to a Google Doc. (I got the image insertion code from here).
The resulting document is created ok, but my image is added twice for some reason...
function myFunction(e) {
var doc = DocumentApp.create('fileTest');
var body = doc.getBody();
var matchedFiles = DriveApp.getFilesByName('logo.png');
if (matchedFiles.hasNext()) {
var image = matchedFiles.next().getBlob();
var positionedImage = body.getParagraphs()[0].addPositionedImage(image);
}
body.appendParagraph('Test line of text for testing');
doc.saveAndClose();
}
However, if I get rid of my appendParagraph code (body.appendParagraph(t1);) I only get one image (but obviously without the paragraph of text I want)
What's going on here? And how do I add both one picture and my paragraph of text?
I have not even the slightest clue as to why, but I found a way to make this work.
Switching the order of my code seemed to do the trick. I simply moved the image-insertion code to the end (i.e., after the appendParagraph code), and it worked fine. No duplicate image!
function myFunction(e) {
var doc = DocumentApp.create('fileTest');
var body = doc.getBody();
body.appendParagraph('Test line of text for testing');
var matchedFiles = DriveApp.getFilesByName('logo.png');
if (matchedFiles.hasNext()) {
var image = matchedFiles.next().getBlob();
var positionedImage = body.getParagraphs()[0].addPositionedImage(image);
}
doc.saveAndClose();
}
I use Helvetica font and 14 px size for text. The problem is that if a page does not have any image on it the text is very clear, but in a page with at least 1 image the text is getting a little bold. You can see what I mean in images below:
* Without image on page
* With image on page
The correct font is the one that appear in picture #1. How to make all pages have the same font even if the page contains an image or not?
Thanks.
Sample code:
Document document = new Document(PageSize.LETTER);
document.SetMargins(docMargin, docMargin, docMargin, 25);
writer = PdfWriter.GetInstance(document, new FileStream(filename, FileMode.Create));
document.Open();
Font defaultFont = FontFactory.GetFont("Helvetica", 7.8, Font.NORMAL, new Color(75, 75, 75));
document.Add(new Paragraph("Lorem ipsum lorem ipsum lorem ipsum", defaultFont));
document.Add(Chunk.NEWLINE);
Image img = Image.GetInstance("my png image path");
document.Add(img);
document.Close();
I was finally able to reproduce your problem. The first PNG that I tested with which didn't reproduce your problem I created from Photoshop and used the Save For Web command. The second PNG that I tested and was able to reproduce your problem I created from MSPAINT.EXE. I tried various combinations within Save For Web and none of them have the same problem as Paint.
According to this thread from the official iText mailing list it appears to be something about the color profile of the image.
What are you seeing is the impact of newly placed transparency into a
PDF that had not previously contained it, when consideration isn't
given for the blending colorspace of the final output document.
You have an RGB document that upon adding transparency is forced into
CMYK due to lack of explicit blending space. If you were to specify
RGB as your explicit blending space at the same time you added your
transparency, all would be well.
One thing they recommend is setting the following property on your PdfWriter before adding anything:
writer.RgbTransparencyBlending = true;
When I do it I still see a very minor shift but no where near as pronounced as without it.
This isn't an answer, I just need to be able to post code.
I'm unable to reproduce your results but if I were to guess it has something to do with your PDF renderer. You can confirm this by zooming in on the text, does it look the same when zoomed in? If so, that's your renderer trying to apply visual hints to a print document. If not, can you post a simplified version of your code that does this? Does this do this for all images or just one specific one? How are you creating your text, with Paragraphs, Tables, HTML parsing or something else? What version of iTextSharp are you using?
Below is a full working WinForms C# 2010 targeting iTextSharp 5.1.2.0 that creates a two page PDF. The first page has just text and the second page has text followed by an image loaded from the desktop. On my machine, using Adobe Acrobat Pro 9.1.3 I don't see any difference in fonts when I view it on screen.
using System;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
string pdfFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");
string imgFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.png");
using (FileStream fs = new FileStream(pdfFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (Document doc = new Document(PageSize.LETTER)) {
using (PdfWriter writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, BaseFont.NOT_EMBEDDED);
iTextSharp.text.Font f = new iTextSharp.text.Font(bf, 14);
doc.NewPage();
doc.Add(new Paragraph("This is a test", f));
doc.NewPage();
doc.Add(new Paragraph("This is a test", f));
iTextSharp.text.Image img = iTextSharp.text.Image.GetInstance(imgFile);
img.ScaleAbsolute(100, 100);
doc.Add(img);
doc.Close();
}
}
}
this.Close();
}
}
}
I am updating some legacy code to support CKEditor up from FCKEditor, in classic asp. I am not a classic asp designer by trade so I am flying by the seat of my pants here. We previously used Javascriptspellcheck to to the spell checking. The problem I am having relates to this old code:
function doSpellCheck() {
var oSpell = new JavaScriptSpellCheck();
oSpell.callBack = function() {
oEditor.SetHTML($('POST_MESSAGE').value);
}
oEditor.UpdateLinkedField();
oSpell.spellCheckWindow('POST_MESSAGE');
}
oEditor is an instance of FCKEditor defined in a fckeditor_oncomplete() function. The new code I am trying to use is as follows:
function doSpellCheck() {
oSpellEditor = CKEDITOR.instances['POST_MESSAGE'].getData();
var oSpell = new JavaScriptSpellCheck();
oSpell.callBack = function() {
CKEDITOR.instances['POST_MESSAGE'].Setdata(oSpellEditor);
}
oSpell.spellCheckWindow('POST_MESSAGE');
}
The problem I seem to be facing is that JavaScriptSpellCheck(); needs the textarea id of the ckeditor instance. I attempted to follow the directions in This Post and nemisj's answer but I am having trouble with the code. I am not really understanding the DOM or how to manipulate it in this case. I know that this is not asp, to create the ckeditor instance I am using a custom asp sub to create it, but this is the area that I am having trouble with.
*EDIT: Found the answer. Where I am creating new CKEditor I needed to add text area attributes like so:
Set pageEditorTop = New CKEditor
' Change default textarea attributes
set textareaAttributes = CreateObject("Scripting.Dictionary")
textareaAttributes.Add "id", "POST_MESSAGE"
Set pageEditorTop.textareaAttributes = textareaAttributes
That code that you are trying to use doesn't make sense.
This is a straight port of the original code to CKEditor:
function doSpellCheck() {
var oEditor = CKEDITOR.instances['POST_MESSAGE'];
var oSpell = new JavaScriptSpellCheck();
oSpell.callBack = function() {
oEditor.setData($('POST_MESSAGE').value);
}
oEditor.updateElement();
oSpell.spellCheckWindow('POST_MESSAGE');
}