Form suddenly unsignable for no obvious reason [duplicate] - pdf

below the code using one text field, two list boxes and one signature field. selecting an entry of listbox domicilation updates the entries of listbox legalForm. The newDateField currently servers as debug field, it contains the last listbox value that was updated. I would like to know why the result cannot be signed. It must be related to the javascript of the list boxes... Kindly help
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.action.PDAnnotationAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
import org.apache.pdfbox.pdmodel.interactive.form.*;
import java.awt.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class AnaCreditForm {
public static void main(String[] args) {
System.out.println("Creating pdf docoument including signature field");
try {
// Create a new document with an empty page.
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
String javaScript = "var now = util.printd('yyyy-mm-dd', new Date());"
+ "var ndf = this.getField('newDateField');"
+ "ndf.value = now;"
// + "this.getField('signatureField').display=display.hidden;"
// + "var formReady = false;"
+ "var anacredit = { '-': [['-', '-']], "
+ " 'Luxembourg': [[ '-', '-'], ['LU01 Entreprise individuelle', 'LU01'],[ 'LU06 Société anonyme', 'LU06'] ,['LU14 Société civile','LU14']] , "
+ " 'Germany': [[ '-', '-'], ['DE201 Aktiengesellschaft', 'DE201'], ['DE602 Eingetragener Verein', 'DE602'], ['DE205 Investmentaktiengesellschaft', 'DE205']], "
+ " 'Greece': [[ '-', '-'], ['GR906 Εταιρία Περιορισμένης Ευθύνης/Etería Periorisménis Euthínis', 'GR906'], ['GR912 Κοινοπραξία/Kinopraxia', 'GR912'], ['GR999 Λοιπά/Lipa', 'GR999']] };";
// Create an action as JavaScript action
PDActionJavaScript jsAction = new PDActionJavaScript();
jsAction.setAction(javaScript);
// Set the action to be executed when the document is opened
document.getDocumentCatalog().setOpenAction(jsAction);
// Adobe Acrobat uses Helvetica as a default font and
// stores that under the name '/Helv' in the resources dictionary
PDFont font = PDType1Font.HELVETICA;
PDResources resources = new PDResources();
resources.put(COSName.getPDFName("Helv"), font);
PDDocumentCatalog pdCatalog = document.getDocumentCatalog();
PDAcroForm pdAcroForm = new PDAcroForm(document);
pdCatalog.setAcroForm(pdAcroForm);
pdAcroForm.setDefaultResources(resources);
String defaultAppearanceString = "/Helv 0 Tf 0 g";
pdAcroForm.setDefaultAppearance(defaultAppearanceString);
PDTextField newDateField = new PDTextField(pdAcroForm);
newDateField.setPartialName("newDateField");
defaultAppearanceString = "/Helv 12 Tf 0 g";
newDateField.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(newDateField);
PDAnnotationWidget widget = newDateField.getWidgets().get(0);
PDRectangle rect = new PDRectangle(50, 450, 500, 15);
widget.setRectangle(rect);
widget.setPage(page);
// make sure the annotation is visible on screen and paper
widget.setPrinted(true);
// Add the annotation to the page
page.getAnnotations().add(widget);
//newDateField.setValue("value in newly created text field");
//textBox.setActions(fieldActions);
PDListBox domicilation = new PDListBox(pdAcroForm);
domicilation.setPartialName("domicilation");
List<String> displayList = Arrays.asList("-", "Germany", "Luxembourg", "Greece");
List<String> exportList = Arrays.asList("-", "Germany", "Luxembourg", "Greece");
domicilation.setOptions(exportList, displayList);
defaultAppearanceString = "/Helv 12 Tf 0 g";
domicilation.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(domicilation);
String jsListBox0 =
"var f = this.getField('domicilation');"
+ "var r = this.getField('legalForm');"
+ " console.println('domicilation ' + f.value + 'legalForm' + r.value);"
+ "f.setAction('Keystroke', 'fft();');"
+ "function fft() { if (event.willCommit)"
+ "{ console.println('domiciliation' + event.change + ' ' + event.value); "
+ "r.setItems( anacredit[event.value] );"
+ "f.value=event.value) ; ndf.value= event.value;"
+ " }}";
// + "r.value='-'; formReady=false; }}";
PDFormFieldAdditionalActions fieldActions = new PDFormFieldAdditionalActions();
PDActionJavaScript jsKeystrokeAction = new PDActionJavaScript();
//jsKeystrokeAction.setAction("app.alert(\"On 'keystroke' action\")");
jsKeystrokeAction.setAction(jsListBox0);
fieldActions.setK(jsKeystrokeAction);
domicilation.setActions(fieldActions);
PDAnnotationWidget widget2 = domicilation.getWidgets().get(0);
PDRectangle rect2 = new PDRectangle(50, 380, 500, 50);
widget2.setRectangle(rect2);
widget2.setPage(page);
// make sure the annotation is visible on screen and paper
widget2.setPrinted(true);
//PDAnnotationAdditionalActions annotationActions = new PDAnnotationAdditionalActions();
// Add the annotation to the page
page.getAnnotations().add(widget2);
domicilation.setValue("-");
PDListBox legalForm = new PDListBox(pdAcroForm);
legalForm.setPartialName("legalForm");
List<String> displayList2 = Arrays.asList("-");
List<String> exportList2 = Arrays.asList(" ");
legalForm.setOptions(exportList2, displayList2);
defaultAppearanceString = "/Helv 12 Tf 0 g";
legalForm.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(legalForm);
PDAnnotationWidget widget3 = legalForm.getWidgets().get(0);
PDRectangle rect3 = new PDRectangle(50, 310, 500, 50);
widget3.setRectangle(rect3);
widget3.setPage(page);
// make sure the annotation is visible on screen and paper
widget3.setPrinted(true);
String jsListBox2 = "var lb = this.getField('legalForm'); "
+ "console.println('in legalForm action ' + lb.value);"
+ "lb.setAction('Keystroke', 'fft2();');"
+ "function fft2() { if (event.willCommit)"
+ "{ console.println('in legalForm action ' + event.change + ' ' + event.value);"
+ "lb.value=event.value; ndf.value= event.value;}}";
// + "console.println(formReady);"
// + "lb.setAction('Keystroke', 'flb();');"
// + "function flb() { if (event.willCommit)"
// + "{ console.println('in listbox action'); console.println(event.value); "
// + "if (lb.value == '-') formReady= false; else formReady=true; "
// + "if (formReady) this.getField('signatureField').display=display.visible; "
// + "else this.getField('signatureField').display=display.hidden; }}" +
// + " lb.value=event.value; ndf.value=event.value; }}" ;
// "f2.setAction('Keystroke', 'fft2();');function fft2() { if (!event.willCommit) { console.println(event.change); r2.value = event.change; }}";
PDFormFieldAdditionalActions fieldActions2 = new PDFormFieldAdditionalActions(); // usable only for .setK, not for .setU
//PDAnnotationAdditionalActions annotationActions = new PDAnnotationAdditionalActions();
PDActionJavaScript jsKeyStrokeAction = new PDActionJavaScript();
//jsKeystrokeAction.setAction("app.alert(\"On 'keystroke' action\")");
jsKeyStrokeAction.setAction(jsListBox2);
fieldActions2.setK(jsKeyStrokeAction);
legalForm.setActions(fieldActions2);
//widget3.setActions(annotationActions);*/
//PDAnnotationAdditionalActions annotationActions = new PDAnnotationAdditionalActions();
PDFormFieldAdditionalActions listboxAction2 = new PDFormFieldAdditionalActions();
// Add the annotation to the page
page.getAnnotations().add(widget3);
legalForm.setValue("-");
PDRectangle rect4 = new PDRectangle(50, 150, 200, 50);
PDAppearanceDictionary appearanceDictionary = new PDAppearanceDictionary();
PDAppearanceStream appearanceStream = new PDAppearanceStream(document);
appearanceStream.setBBox(rect4.createRetranslatedRectangle());
appearanceStream.setResources(resources);
appearanceDictionary.setNormalAppearance(appearanceStream);
PDPageContentStream contentStream = new PDPageContentStream(document, appearanceStream);
contentStream.setStrokingColor(Color.BLACK);
contentStream.setNonStrokingColor(Color.LIGHT_GRAY);
contentStream.setLineWidth(2);
contentStream.addRect(0, 0, rect4.getWidth(), rect4.getHeight());
contentStream.fill();
contentStream.moveTo(1 * rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.lineTo(2 * rect4.getHeight() / 4, 3 * rect4.getHeight() / 4);
contentStream.moveTo(1 * rect4.getHeight() / 4, 3 * rect4.getHeight() / 4);
contentStream.lineTo(2 * rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.moveTo(3 * rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.lineTo(rect4.getWidth() - rect4.getHeight() / 4, 1 * rect4.getHeight() / 4);
contentStream.stroke();
contentStream.setNonStrokingColor(Color.DARK_GRAY);
contentStream.beginText();
contentStream.setFont(font, rect4.getHeight() / 5);
contentStream.newLineAtOffset(3 * rect4.getHeight() / 4, -font.getBoundingBox().getLowerLeftY() * rect4.getHeight() / 5000);
contentStream.showText("Customer");
contentStream.endText();
contentStream.close();
PDSignatureField signatureField = new PDSignatureField(pdAcroForm);
signatureField.setPartialName("signatureField");
PDAnnotationWidget widget4 = signatureField.getWidgets().get(0);
widget4.setAppearance(appearanceDictionary);
widget4.setRectangle(rect4);
widget4.setPage(page);
page.getAnnotations().add(widget4);
pdAcroForm.getFields().add(signatureField);
document.save("anacreditForm.pdf");
for (PDField pdField : pdAcroForm.getFields()) {
System.out.println(pdField.getFullyQualifiedName() + " " + pdField.getFieldType() + " " + pdField.getValueAsString());
}
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Adobe Reader apparently does reject signing attempts for documents in which by means of JavaScript an event handler has been changed.
Your code actually is an example why that is good: As soon as the original domicilation event handler is executed, it is set to 'fft();' but the code of fft() is only in the Adobe Reader's memory, not in the PDF anymore. Thus, a thereafter signed version of the PDF would behave differently as it would be missing that code.
As an aside, there is one unwanted closing round bracket in
+ "f.value=event.value) ; ndf.value= event.value;"
in jsListBox0.

Related

How to use PDF Sharp objects in my Migradoc document

I have an application that generates PDFs using the MigraDoc framework, however I have a requirement to add in a text driven watermark. I have found some examples of this being done using PDF Sharp here, however I just cant seem t be able to figure out how this will integrate with my Migradoc Document() object I am rendering.
I have the following code:
public byte[] render()
{
PdfDocument document = new PdfDocument();
CreateWaterMarks(document);
// *****************************
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = this.document;
renderer.RenderDocument();
byte[] pdfContents = null;
using (MemoryStream stream = new MemoryStream())
{
renderer.PdfDocument.Save(stream, true);
pdfContents = stream.ToArray();
}
return pdfContents;
}
This method is what is called to render the MigraDoc document and pass it out as a byte array. The second line of code in here calls the following method which is not doing what I am looking for:
void CreateWaterMarks(PdfDocument document)
{
PdfPage page = document.AddPage();
Document doc = this.document;
MigraDoc.Rendering.DocumentRenderer docRenderer = new DocumentRenderer(doc);
docRenderer.PrepareDocument();
XRect A4Rect = new XRect(0, 0, pageActiveWidth, pageActiveHeight);
int pageCount = docRenderer.FormattedDocument.PageCount;
for (int idx = 0; idx < pageCount; idx++)
{
XFont font = new XFont("Verdana", 13, XFontStyle.Bold);
XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
XSize size = gfx.MeasureString("Watermark", font);
gfx.TranslateTransform(pageActiveWidth / 2, pageActiveHeight / 2);
gfx.RotateTransform(-Math.Atan(pageActiveHeight / pageActiveWidth) * 180 / Math.PI);
gfx.TranslateTransform(-pageActiveWidth / 2, -pageActiveHeight / 2);
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Near;
XBrush brush = new XSolidBrush(XColor.FromArgb(128, 255, 0, 0));
gfx.DrawString("Watermark", font, brush, new XPoint((pageActiveWidth - size.Width) / 2, (pageActiveHeight - size.Height) / 2), format);
docRenderer.RenderPage(gfx, idx + 1);
}
}
I was hoping that this would magically make these PDFSharp watermarks appear but alas I get nothing!
I have this working using the following code:
public byte[] render()
{
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true);
renderer.Document = this.document;
renderer.RenderDocument();
renderer.PrepareRenderPages();
CreateWatermarks(renderer);
byte[] pdfContents = null;
using (MemoryStream stream = new MemoryStream())
{
renderer.PdfDocument.Save(stream, true);
pdfContents = stream.ToArray();
}
return pdfContents;
}
private void CreateWatermarks(PdfDocumentRenderer renderer)
{
int pages = renderer.DocumentRenderer.FormattedDocument.PageCount;
for (int i = 0; i < pages; ++i)
{
var page = renderer.PdfDocument.Pages[i];
XFont font = new XFont("Verdana", 27, XFontStyle.Bold);
XGraphics gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Prepend);
XSize size = gfx.MeasureString("Watermark", font);
gfx.TranslateTransform(pageActiveWidth / 2, pageActiveHeight / 2);
gfx.RotateTransform(-Math.Atan(pageActiveHeight / pageActiveWidth) * 180 / Math.PI);
gfx.TranslateTransform(-pageActiveWidth / 2, -pageActiveHeight / 2);
XStringFormat format = new XStringFormat();
format.Alignment = XStringAlignment.Near;
format.LineAlignment = XLineAlignment.Near;
XBrush brush = new XSolidBrush(XColor.FromArgb(128, 255, 0, 0));
gfx.DrawString("Watermark", font, brush, new XPoint((pageActiveWidth - size.Width) / 2, (pageActiveHeight - size.Height) / 2), format);
}
}

How to create a table using PDFsharp?

Just started using PDFsharp and it works fine, but now I want to create tables in my PDF, but tried other sources and found nothing.
So far I know how to use graph.drawString().
I could not find any clear and simple example of a basic table-template.
pdfSharp is a very powerful but extremely low level library, so it's difficult to draw rectangles and text with fixed positions. Anyway, here is a little complete example that shows how to draw a table:
protected void ExportGraf_Click(object sender, EventArgs e)
{
PdfDocument document = new PdfDocument();
document.Info.Title = "Table Example";
for (int p=0; p<1; p++)
{
// Page Options
PdfPage pdfPage = document.AddPage();
pdfPage.Height = 842;//842
pdfPage.Width = 590;
// Get an XGraphics object for drawing
XGraphics graph = XGraphics.FromPdfPage(pdfPage);
// Text format
XStringFormat format = new XStringFormat();
format.LineAlignment = XLineAlignment.Near;
format.Alignment = XStringAlignment.Near;
var tf = new XTextFormatter(graph);
XFont fontParagraph = new XFont("Verdana", 8, XFontStyle.Regular);
// Row elements
int el1_width = 80;
int el2_width = 380;
// page structure options
double lineHeight = 20;
int marginLeft = 20;
int marginTop = 20;
int el_height = 30;
int rect_height = 17;
int interLine_X_1 = 2;
int interLine_X_2 = 2 * interLine_X_1;
int offSetX_1 = el1_width;
int offSetX_2 = el1_width + el2_width;
XSolidBrush rect_style1 = new XSolidBrush(XColors.LightGray);
XSolidBrush rect_style2 = new XSolidBrush(XColors.DarkGreen);
XSolidBrush rect_style3= new XSolidBrush(XColors.Red);
for (int i = 0; i < 30; i++)
{
double dist_Y = lineHeight * (i + 1);
double dist_Y2 = dist_Y - 2;
// header della G
if (i == 0)
{
graph.DrawRectangle(rect_style2, marginLeft, marginTop, pdfPage.Width-2* marginLeft, rect_height);
tf.DrawString("column1", fontParagraph, XBrushes.White,
new XRect(marginLeft, marginTop, el1_width, el_height), format);
tf.DrawString("column2", fontParagraph, XBrushes.White,
new XRect(marginLeft + offSetX_1 + interLine_X_1, marginTop , el2_width, el_height), format);
tf.DrawString("column3", fontParagraph, XBrushes.White,
new XRect(marginLeft + offSetX_2 + 2 * interLine_X_2, marginTop, el1_width, el_height), format);
// stampo il primo elemento insieme all'header
graph.DrawRectangle(rect_style1, marginLeft, dist_Y2 + marginTop, el1_width, rect_height);
tf.DrawString("text1", fontParagraph, XBrushes.Black,
new XRect(marginLeft, dist_Y + marginTop, el1_width, el_height), format);
//ELEMENT 2 - BIG 380
graph.DrawRectangle(rect_style1, marginLeft + offSetX_1 + interLine_X_1, dist_Y2 + marginTop, el2_width, rect_height);
tf.DrawString(
"text2",
fontParagraph,
XBrushes.Black,
new XRect(marginLeft + offSetX_1 + interLine_X_1, dist_Y + marginTop, el2_width, el_height),
format);
//ELEMENT 3 - SMALL 80
graph.DrawRectangle(rect_style1, marginLeft + offSetX_2 + interLine_X_2, dist_Y2 + marginTop, el1_width, rect_height);
tf.DrawString(
"text3",
fontParagraph,
XBrushes.Black,
new XRect(marginLeft + offSetX_2 + 2 * interLine_X_2, dist_Y + marginTop, el1_width, el_height),
format);
}
else {
//if (i % 2 == 1)
//{
// graph.DrawRectangle(TextBackgroundBrush, marginLeft, lineY - 2 + marginTop, pdfPage.Width - marginLeft - marginRight, lineHeight - 2);
//}
//ELEMENT 1 - SMALL 80
graph.DrawRectangle(rect_style1, marginLeft, marginTop + dist_Y2, el1_width, rect_height);
tf.DrawString(
"text1",
fontParagraph,
XBrushes.Black,
new XRect(marginLeft, marginTop + dist_Y, el1_width, el_height),
format);
//ELEMENT 2 - BIG 380
graph.DrawRectangle(rect_style1, marginLeft + offSetX_1 + interLine_X_1 , dist_Y2 + marginTop, el2_width, rect_height);
tf.DrawString(
"text2",
fontParagraph,
XBrushes.Black,
new XRect(marginLeft + offSetX_1 + interLine_X_1, marginTop + dist_Y, el2_width, el_height),
format);
//ELEMENT 3 - SMALL 80
graph.DrawRectangle(rect_style1, marginLeft + offSetX_2 + interLine_X_2, dist_Y2 + marginTop, el1_width, rect_height);
tf.DrawString(
"text3",
fontParagraph,
XBrushes.Black,
new XRect(marginLeft + offSetX_2 + 2 *interLine_X_2, marginTop + dist_Y, el1_width, el_height),
format);
}
}
}
const string filename = "C:\\Users\\Desktop\\test\\HelloWorld.pdf";
document.Save(filename);
//byte[] bytes = null;
//using (MemoryStream stream = new MemoryStream())
//{
// document.Save(stream, true);
// bytes = stream.ToArray();
//}
//SendFileToResponse(bytes, "HelloWorld_test.pdf");
}
Notice you can print more pages within the document; just change the first "for".
It should render like this:
.
With PDFsharp: draw text, draw lines around it.
With MigraDoc (you already added that tag): add a Table to your document and add the columns, rows, and borders you need.
The MigraDoc samples that come with MigraDoc are all C#, but a VB.NET sample can be found on the forum.
VB.NET sample on official PDFsharp/MigraDoc forum:
http://forum.pdfsharp.net/viewtopic.php?f=8&t=3207
C# sample on official site that shows usage of tables:
http://pdfsharp.net/wiki/Invoice-sample.ashx
This example creates a table, but also shows you how to insert text, draw lines, squares, and set up margins. Still a work in progress.
//PdfSharpUtilities.cs
//*******************************************************************/
/* Usage example
private void buttonRunExample_Click(object sender, EventArgs e)
{
PdfSharpUtilities pdf = new PdfSharpUtilities("test.pdf", true);
pdf.drawSquare(new DPoint(0, 0), 3, 2, XBrushes.Purple);
pdf.addText("Username", new DPoint(0, 4.5), 16);
pdf.addText("Invoice", new DPoint(12.15, 1.5), 14);
pdf.addText("Account: 69696969", new DPoint(0, 6));
pdf.addText("Period: 2022-11", new DPoint(0, 7));
pdf.addText("E-mail: mail#gmail.com", new DPoint(0, 8));
pdf.addText("Inventory:", new DPoint(0, 10));
//Example table: to fill with example data leave contents = null
pdf.drawTable(0, 11, 15.7, 3, XBrushes.LightGray, null);
pdf.saveAndShow();
}*/
//******************************************************************/
public class PdfSharpUtilities
{
private double topMargin = 0;
private double leftMargin = 0;
private double rightMargin = 0;
private double bottomMargin = 0;
private double cm;
private PdfDocument document;
private PdfPage page;
private XGraphics gfx;
private XFont font;
private XPen pen;
private String outputPath;
public PdfSharpUtilities(String argOutputpath, Boolean argAddMarginGuides = false)
{
this.outputPath = argOutputpath;
//You’ll need a PDF document:
this.document = new PdfDocument();
//And you need a page:
this.page = document.AddPage();
this.page.Size = PageSize.Letter;
//Define how much a cm is in document's units
this.cm = new Interpolation().linearInterpolation(0, 0, 27.9, page.Height, 1);
Console.WriteLine("1 cm:" + cm);
//Drawing is done with an XGraphics object:
this.gfx = XGraphics.FromPdfPage(page);
this.font = new XFont("Arial", 12, XFontStyle.Bold);
this.pen = new XPen(XColors.Black, 0.5);
//Sugested margins
topMargin = 2.5 * cm;
leftMargin = 3 * cm;
rightMargin = page.Width - (3 * cm);
bottomMargin = page.Height - (2.5 * cm);
if (argAddMarginGuides)
{
gfx.DrawString("+", font, XBrushes.Black, rightMargin, topMargin);
gfx.DrawString("+", font, XBrushes.Black, leftMargin, topMargin);
gfx.DrawString("+", font, XBrushes.Black, rightMargin, bottomMargin);
gfx.DrawString("+", font, XBrushes.Black, leftMargin, bottomMargin);
}
Console.WriteLine("Page Width in cm:" + page.Width * cm);
Console.WriteLine("Page Height in cm:" + page.Height * cm);
Console.WriteLine("Top Margin in cm:" + topMargin);
Console.WriteLine("Left Margin in cm:" + leftMargin);
Console.WriteLine("Right Margin in cm:" + rightMargin);
Console.WriteLine("Bottom Margin in cm:" + bottomMargin);
}
public void drawTable(double initialPosX, double initialPosY, double width, double height, XBrush xbrush, List<String[]> contents = null)
{
drawSquare(new DPoint(initialPosX, initialPosY), width, height, xbrush);
if (contents == null)
{
contents = new List<String[]>();
contents.Add(new string[] { "Type", "Size", "Weight", "Stock", "Tax", "Price" });
contents.Add(new string[] { "Obo", "1", "45", "56", "16.00", "6.50" });
contents.Add(new string[] { "Crotolamo", "2", "72", "63", "16.00", "19.00" });
}
int columns = contents[0].Length;
int rows = contents.Count;
double distanceBetweenRows = height / rows;
double distanceBetweenColumns = width / columns;
/*******************************************************************/
// Draw the row lines
/*******************************************************************/
DPoint pointA = new DPoint(initialPosX, initialPosY);
DPoint pointB = new DPoint(initialPosX + width, initialPosY);
for (int i = 0; i <= rows; i++)
{
drawLine(pointA, pointB);
pointA.y = pointA.y + distanceBetweenRows;
pointB.y = pointB.y + distanceBetweenRows;
}
/*******************************************************************/
// Draw the column lines
/*******************************************************************/
pointA = new DPoint(initialPosX, initialPosY);
pointB = new DPoint(initialPosX, initialPosY + height);
for (int i = 0; i <= columns; i++)
{
drawLine(pointA, pointB);
pointA.x = pointA.x + distanceBetweenColumns;
pointB.x = pointB.x + distanceBetweenColumns;
}
/*******************************************************************/
// Insert text corresponding to each cell
/*******************************************************************/
pointA = new DPoint(initialPosX, initialPosY);
foreach (String[] rowDataArray in contents)
{
foreach (String cellText in rowDataArray)
{
this.gfx.DrawString(cellText, this.font, XBrushes.Black, new XRect(leftMargin + (pointA.x * cm), topMargin + (pointA.y * cm), distanceBetweenColumns * cm, distanceBetweenRows * cm), XStringFormats.Center);
pointA.x = pointA.x + distanceBetweenColumns;
}
pointA.x = initialPosX;
pointA.y = pointA.y + distanceBetweenRows;
}
}
public void addText(String text, DPoint xyStartingPosition, int size = 12)
{
this.gfx.DrawString(text, this.font, XBrushes.Black, leftMargin + (xyStartingPosition.x * cm), topMargin + (xyStartingPosition.y * cm));
}
public void drawSquare(DPoint xyStartingPosition, double width, double height, XBrush xbrush)
{
Console.WriteLine("Drawing square starting at: " + xyStartingPosition.x + "," + xyStartingPosition.y + " width: " + width + " height: " + height);
this.gfx.DrawRectangle(xbrush, new XRect(leftMargin + (xyStartingPosition.x * cm), topMargin + (xyStartingPosition.y * cm), (width * cm), (height * cm)));
}
public void drawLine(DPoint fromXyPosition, DPoint toXyPosition)
{
this.gfx.DrawLine(this.pen, leftMargin + (fromXyPosition.x * cm), topMargin + (fromXyPosition.y * cm), leftMargin + (toXyPosition.x * cm), topMargin + (toXyPosition.y * cm));
}
public void saveAndShow(Boolean argShowAfterSaving = true)
{
document.Save(this.outputPath);
if (argShowAfterSaving)
{
Process.Start(this.outputPath);
}
}
}
//DPoint.cs
public class DPoint
{
public double x { get; set; }
public double y { get; set; }
public DPoint(double x, double y)
{
this.x = x;
this.y = y;
}
}
//Interpolation.cs
public double linearInterpolation(double x0, double y0, double x1, double y1, double xd)
{
/*******************************************************************/
//
// x0 -------> y0
// given x -------> what is y?
// x1 -------> y1
/*******************************************************************/
return (y0 + ((y1 - y0) * ((xd - x0) / (x1 - x0))));
}
This work example, with MigroDoc. I changed a little from that example
static Table table;
static Document document;
static TextFrame addressFrame;
public static void Main()
{
const PdfFontEmbedding embedding = PdfFontEmbedding.Always;
PdfDocumentRenderer render = new PdfDocumentRenderer(true, embedding);
Document doc = CreateDocument();
render.Document = doc;
render.DocumentRenderer = render.DocumentRenderer;
render.RenderDocument();
render.PdfDocument.Save(#"D:\PDF1.pdf");
Process.Start(#"D:\PDF1.pdf");
}
public static Document CreateDocument()
{
// Create a new MigraDoc document
document = new Document();
document.Info.Title = "A sample invoice";
document.Info.Subject = "Demonstrates how to create an invoice.";
document.Info.Author = "Stefan Lange";
DefineStyles();
CreatePage();
FillContent();
return document;
}
static void DefineStyles()
{
// Get the predefined style Normal.
Style style = document.Styles["Normal"];
// Because all styles are derived from Normal, the next line changes the
// font of the whole document. Or, more exactly, it changes the font of
// all styles and paragraphs that do not redefine the font.
style.Font.Name = "Arial";
style = document.Styles[StyleNames.Header];
style.ParagraphFormat.AddTabStop("16cm", TabAlignment.Right);
style = document.Styles[StyleNames.Footer];
style.ParagraphFormat.AddTabStop("8cm", TabAlignment.Center);
// Create a new style called Table based on style Normal
style = document.Styles.AddStyle("Table", "Normal");
style.Font.Name = "Arial";
style.Font.Size = 9;
// Create a new style called Reference based on style Normal
style = document.Styles.AddStyle("Reference", "Normal");
style.ParagraphFormat.SpaceBefore = "5mm";
style.ParagraphFormat.SpaceAfter = "5mm";
style.ParagraphFormat.TabStops.AddTabStop("16cm", TabAlignment.Right);
}
static void CreatePage()
{
Section section = document.AddSection();
// Create footer
Paragraph paragraph = section.Footers.Primary.AddParagraph();
paragraph.AddText("PowerBooks Inc · Sample Street 42 · 56789 Cologne · Germany");
paragraph.Format.Font.Size = 9;
paragraph.Format.Alignment = ParagraphAlignment.Center;
// Create the text frame for the address
addressFrame = section.AddTextFrame();
addressFrame.Height = "3.0cm";
addressFrame.Width = "7.0cm";
addressFrame.Left = ShapePosition.Left;
addressFrame.RelativeHorizontal = RelativeHorizontal.Margin;
addressFrame.Top = "5.0cm";
addressFrame.RelativeVertical = RelativeVertical.Page;
// Put sender in address frame
paragraph = addressFrame.AddParagraph("PowerBooks Inc · Sample Street 42 · 56789 Cologne");
paragraph.Format.Font.Name = "Arial";
paragraph.Format.Font.Size = 7;
paragraph.Format.SpaceAfter = 3;
// Add the print date field
paragraph = section.AddParagraph();
paragraph.Format.SpaceBefore = "8cm";
paragraph.Style = "Reference";
paragraph.AddFormattedText("INVOICE");
paragraph.AddTab();
paragraph.AddText("Hello World");
paragraph.AddDateField("dd.MM.yyyy");
// Create the item table
table = section.AddTable();
table.Style = "Table";
table.Borders.Color = Colors.Black;
table.Borders.Width = 0.25;
table.Borders.Left.Width = 0.5;
table.Borders.Right.Width = 0.5;
table.Rows.LeftIndent = 0;
// Before you can add a row, you must define the columns
Column column = table.AddColumn("1cm");
column.Format.Alignment = ParagraphAlignment.Center;
column = table.AddColumn("2.5cm");
column.Format.Alignment = ParagraphAlignment.Right;
column = table.AddColumn("3cm");
column.Format.Alignment = ParagraphAlignment.Right;
column = table.AddColumn("3.5cm");
column.Format.Alignment = ParagraphAlignment.Right;
column = table.AddColumn("2cm");
column.Format.Alignment = ParagraphAlignment.Center;
column = table.AddColumn("4cm");
column.Format.Alignment = ParagraphAlignment.Right;
// Create the header of the table
Row row = table.AddRow();
row.HeadingFormat = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Shading.Color = Colors.Red;
row.Cells[0].AddParagraph("Item");
row.Cells[0].Format.Font.Bold = false;
row.Cells[0].Format.Alignment = ParagraphAlignment.Left;
row.Cells[0].VerticalAlignment = VerticalAlignment.Bottom;
row.Cells[0].MergeDown = 1;
row.Cells[1].AddParagraph("Title and Author");
row.Cells[1].Format.Alignment = ParagraphAlignment.Left;
row.Cells[1].MergeRight = 3;
row.Cells[5].AddParagraph("Extended Price");
row.Cells[5].Format.Alignment = ParagraphAlignment.Left;
row.Cells[5].VerticalAlignment = VerticalAlignment.Bottom;
row.Cells[5].MergeDown = 0;
row = table.AddRow();
row.HeadingFormat = true;
row.Format.Alignment = ParagraphAlignment.Center;
row.Format.Font.Bold = true;
row.Shading.Color = Colors.Blue;
row.Cells[1].AddParagraph("Quantity");
row.Cells[1].Format.Alignment = ParagraphAlignment.Left;
row.Cells[2].AddParagraph("Unit Price");
row.Cells[2].Format.Alignment = ParagraphAlignment.Left;
row.Cells[3].AddParagraph("Discount (%)");
row.Cells[3].Format.Alignment = ParagraphAlignment.Left;
row.Cells[4].AddParagraph("Taxable");
row.Cells[4].Format.Alignment = ParagraphAlignment.Left;
table.SetEdge(0, 0, 6, 2, Edge.Box, BorderStyle.Single, 0.75, Color.Empty);
}
static void FillContent()
{
Paragraph paragraph = addressFrame.AddParagraph();
// Iterate the invoice items
double totalExtendedPrice = 0;
double quantity = 200;
double price = 40;
double discount = 5;
for (int i = 0; i < 10; i++)
{
// Each item fills two rows
Row row1 = table.AddRow();
Row row2 = table.AddRow();
row1.TopPadding = 1.5;
row1.Cells[0].Shading.Color = Colors.Gray;
row1.Cells[0].VerticalAlignment = VerticalAlignment.Center;
row1.Cells[0].MergeDown = 1;
row1.Cells[1].Format.Alignment = ParagraphAlignment.Left;
row1.Cells[1].MergeRight = 3;
row1.Cells[5].Shading.Color = Colors.Gray;
row1.Cells[5].MergeDown = 1;
row1.Cells[0].AddParagraph("Hello World 300");
paragraph = row1.Cells[1].AddParagraph();
paragraph.AddFormattedText("Hello World 234", TextFormat.Bold);
paragraph.AddFormattedText(" by ", TextFormat.Italic);
paragraph.AddText("Hello World 200");
row2.Cells[1].AddParagraph("Hello World 125");
row2.Cells[2].AddParagraph(price.ToString("0.00") + " €");
row2.Cells[3].AddParagraph(discount.ToString("0.0"));
row2.Cells[4].AddParagraph();
row2.Cells[5].AddParagraph(price.ToString("0.00"));
double extendedPrice = quantity * price;
extendedPrice = extendedPrice * (100 - discount) / 100;
row1.Cells[5].AddParagraph(extendedPrice.ToString("0.00") + " €");
row1.Cells[5].VerticalAlignment = VerticalAlignment.Bottom;
totalExtendedPrice += extendedPrice;
table.SetEdge(0, table.Rows.Count - 2, 6, 2, Edge.Box, BorderStyle.Single, 0.75);
}
}

selenium webdriver: upload file by drag and drop

On a web page I'm trying to test, we implemented drag and drop file upload. I've looked at the drag and drop API for selenium action chain API. It looks like it supports only dragging and dropping between 2 elements on a page. How to emulate dragging from a file manager?
To perform an HTML5 file drop with Selenium:
static final String JS_DROP_FILE =
"var tgt=arguments[0],e=document.createElement('input');e.type='" +
"file';e.addEventListener('change',function(event){var dataTrans" +
"fer={dropEffect:'',effectAllowed:'all',files:e.files,items:{},t" +
"ypes:[],setData:function(format,data){},getData:function(format" +
"){}};var emit=function(event,target){var evt=document.createEve" +
"nt('Event');evt.initEvent(event,true,false);evt.dataTransfer=da" +
"taTransfer;target.dispatchEvent(evt);};emit('dragenter',tgt);em" +
"it('dragover',tgt);emit('drop',tgt);document.body.removeChild(e" +
");},false);document.body.appendChild(e);return e;";
WebDriver driver = new FirefoxDriver();
driver.get("http://html5demos.com/file-api");
WebElement drop_area = driver.findElement(By.id("holder"));
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(JS_DROP_FILE, new Object[] {
drop_area
}).sendKeys("C:\\image.png");
AutoIt has the DLL wrapper. I use it directly from C#/Selenium code.
Drop file using jsExecutor
public void dropFile(File filePath, WebElement target) {
if (!filePath.exists())
throw new WebDriverException("File not found: " + filePath.toString());
JavascriptExecutor jse = (JavascriptExecutor) getDriver();
String JS_DROP_FILE =
"var target = arguments[0]," +
" offsetX = arguments[1]," +
" offsetY = arguments[2]," +
" document = target.ownerDocument || document," +
" window = document.defaultView || window;" +
"" +
"var input = document.createElement('INPUT');" +
"input.type = 'file';" +
"input.style.display = 'none';" +
"input.onchange = function () {" +
" var rect = target.getBoundingClientRect()," +
" x = rect.left + (offsetX || (rect.width >> 1))," +
" y = rect.top + (offsetY || (rect.height >> 1))," +
" dataTransfer = { files: this.files };" +
"" +
" ['dragenter', 'dragover', 'drop'].forEach(function (name) {" +
" var evt = document.createEvent('MouseEvent');" +
" evt.initMouseEvent(name, !0, !0, window, 0, 0, 0, x, y, !1, !1, !1, !1, 0, null);" +
" evt.dataTransfer = dataTransfer;" +
" target.dispatchEvent(evt);" +
" });" +
"" +
" setTimeout(function () { document.body.removeChild(input); }, 25);" +
"};" +
"document.body.appendChild(input);" +
"return input;";
WebElement input = (WebElement) jse.executeScript(JS_DROP_FILE, target, 0, 0);
input.sendKeys(filePath.getAbsoluteFile().toString());
waitFor(ExpectedConditions.stalenessOf(input));
}
Use AWT Robot class for performing drag and drop:
Robot robot=new Robot();
// drag
robot.mouseMove(x1, y1);
robot.mousePress(InputEvent.BUTTON1_MASK);
// drop
robot.mouseMove(x2, y2);
robot.mouseRelease(InputEvent.BUTTON1_MASK);

javax.script package: How to import JavaScript files?

I'm using javax.script package for running external JavaScript files within Java application.
How can I import one JavaScript file into another JavaScript file, without using Java code?
When you say without using java code, I am not completely sure what you mean, but this is a pure javascript that works (although it is calling java):
importPackage(java.io);
function loadJs(name, user) {
println("Loading " + name);
var f = new File(name);
var br = new BufferedReader(new FileReader(f));
var line = null;
var script = "";
while((line = br.readLine())!=null) {
script += line;
}
println(script);
eval(script);
hello(user);
}
...proivided, of course, that I have the file named (say c:/temp/hellouser.js) with something like:
function hello(name) { print('Hello, ' + name); }
I tested the script using a groovy script:
import javax.script.*;
sem = new ScriptEngineManager();
engine = sem.getEngineByExtension("js");
script1 = """
importPackage(java.io);
function loadJs(name, user) {
println("Loading " + name);
var f = new File(name);
var br = new BufferedReader(new FileReader(f));
var line = null;
var script = "";
while((line = br.readLine())!=null) {
script += line;
}
println(script);
eval(script);
hello(user);
}
""";
engine.eval(script1);
Object obj = engine.get("obj");
Invocable inv = (Invocable) engine;
inv.invokeFunction("loadJs", "c:/temp/hellouser.js", "Nicholas");
and the output was:
Loading c:/temp/hellouser.js
function hello(name) { print('Hello, ' + name); }
Hello, Nicholas
I hope this is approximately what you were looking for....
=========================== UPDATE ===========================
Here's a cleaned up version that extends the Rhino script engine factory (because the engine itself is final):
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import com.sun.script.javascript.RhinoScriptEngineFactory;
/**
* <p>Title: LoadEnabledRhinoEngineFactory</p>
* <p>Description: Adding a loadJs function to the standard JS engine</p>
* <p>Company: Helios Development Group LLC</p>
* #author Whitehead (nwhitehead AT heliosdev DOT org)
* <p><code>org.helios.apmrouter.js.LoadEnabledRhinoEngineFactory</code></p>
*/
public class LoadEnabledRhinoEngineFactory extends RhinoScriptEngineFactory {
/** The load script source */
public static final String LOAD_JS =
"importPackage(java.io); " +
"var script = ''; " +
"var ctx = null; " +
"function loadScript(name) { " +
"var f = new File(name); " +
"var br = new BufferedReader(new FileReader(f)); " +
"var line = null; " +
"while((line = br.readLine())!=null) { " +
" script += line; " +
"} " +
"_e_ngine.eval(script);" +
"} ";
/**
* {#inheritDoc}
* #see com.sun.script.javascript.RhinoScriptEngineFactory#getScriptEngine()
*/
#Override
public ScriptEngine getScriptEngine() {
ScriptEngine se = super.getScriptEngine();
Bindings b = se.createBindings();
b.put("_e_ngine", se);
se.setBindings(b, ScriptContext.GLOBAL_SCOPE);
try {
se.eval(LOAD_JS);
} catch (ScriptException e) {
throw new RuntimeException(e);
}
return se;
}
Now, loadScript(fileName) is part of the engine and you can cleanly call it with JS like:
loadScript('c:/temp/hellouser.js');
hello('Nicholas');"
or as I tested in Java:
ScriptEngine se = new LoadEnabledRhinoEngineFactory().getScriptEngine();
try {
se.eval("loadScript('c:/temp/hellouser.js'); hello('Nicholas');");
} catch (Exception e) {
e.printStackTrace(System.err);
}
Cheers.

PDF to bytearrayoutpustream whitespace

I've a java code to create a PDF temporary file and save it into a BLOB field DB. PDF is generated correctly, and BLOB is saved into DB. When I recreate PDF this is returned without whitespace char! Probably the problem is codification Base64 of bytearrayoutputstream. This is my code
public ByteArrayOutputStream generaFatturaStampaPDF(Fattura fattura) {
try {
Document document = new Document(PageSize.A4, 72, 72, 120, 90);
String tempdir = System.getProperty("java.io.tmpdir");
if ( !(tempdir.endsWith("/") || tempdir.endsWith("\\")) )
tempdir = tempdir + System.getProperty("file.separator");
File tempFattura = File.createTempFile("fattura",".pdf", new File(tempdir));
tempFattura.deleteOnExit();
setFileTempFattura(tempFattura.toString());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(tempFattura));
writer.setPdfVersion(PdfWriter.VERSION_1_7);
writer.setPageEvent(new HeaderFooter());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter docWriter = null;
docWriter = PdfWriter.getInstance(document, baos);
docWriter.setPdfVersion(PdfWriter.VERSION_1_7);
docWriter.setPageEvent(new HeaderFooter());
document.open();
addMetaDataFattura(document);
Font catFont = new Font(Font.FontFamily.TIMES_ROMAN, 18, Font.BOLD, BaseColor.BLACK);
Paragraph paragrafoFattura = new Paragraph();
paragrafoFattura.setAlignment(Element.ALIGN_CENTER);
Chunk c = new Chunk("Fattura");
c.setFont(catFont);
paragrafoFattura.add(c);
document.add(paragrafoFattura);
intestazioneFatturaStampa(writer, fattura);
intestazioneFatturaStampa(docWriter, fattura);
addEmptyLine(document, 7);
float[] widths = { 8f, 2f };
PdfPTable table = new PdfPTable(widths);
table.setHorizontalAlignment(Element.ALIGN_CENTER);
table.setWidthPercentage(100);
table.setHeaderRows(1);
addCenterTableHeaderBold(table, "Descrizione", true, 12);
addCenterTableHeaderBold(table, "Totale", true, 12);
Double somma = 0.0;
Iterator<FatturaDettaglio> iterator = fattura.getFatturaDettaglios().iterator();
while (iterator.hasNext()) {
FatturaDettaglio fatturaDettaglio = iterator.next();
somma += fatturaDettaglio.getPrezzo();
}
addCenterTableHeaderBoldAllignLeft(table, fattura.getFatturaDettaglios().size()
+ " Richieste di Preventivo ", false, 12);
addCenterTableHeaderBold(table, "€ " + arrotonda(somma), false, 12);
Iterator<CreditoDebito> iterator2 = fattura.getCreditoDebitos().iterator();
while (iterator2.hasNext()) {
CreditoDebito creditoDebito = iterator2.next();
addCenterTableHeaderBoldAllignLeft(table, creditoDebito.getNote(), false, 12);
String segno = "";
if (creditoDebito.getTipo().equals("C")) {
segno = "-";
somma = somma - creditoDebito.getImporto();
}
if (creditoDebito.getTipo().equals("D")) {
segno = "";
somma = somma + creditoDebito.getImporto();
}
addCenterTableHeaderBold(table, "€ " + segno
+ arrotonda(creditoDebito.getImporto()), false, 12);
}
document.add(table);
addEmptyLine(document, 2);
float[] widths1 = { 2f, 1f };
PdfPTable table1 = new PdfPTable(widths1);
table1.setHorizontalAlignment(Element.ALIGN_RIGHT);
table1.setWidthPercentage(60);
addCenterTableHeader(table1, "Totale Imponibile netto", true);
addCenterTableHeader(table1, "€ " + arrotonda(somma), false);
addCenterTableHeader(table1, "IVA", true);
addCenterTableHeader(table1, "€ " + arrotonda(somma * 20 / 100), false);
addCenterTableHeader(table1, "Totale Fattura", true);
addCenterTableHeader(table1, "€ " + arrotonda(somma + somma * 20 / 100), false);
document.add(table1);
addEmptyLine(document, 2);
paragrafoFattura.setAlignment(Element.ALIGN_LEFT);
Chunk datiPagamento =
new Chunk("Dettagli pagamento:\nMetodo: "
+ fattura.getAzienda().getMetodoPagamento()
+ "\nIBAN: IT xx X xxxxx xxxxx xxxxxxxxxxx");
document.add(datiPagamento);
addEmptyLine(document, 5);
Chunk dettagliEstrattoContoTesto =
new Chunk(
"Per maggiori dettagli sulle richieste di preventivo e eventuali promozioni consultare l'estratto conto allegato");
dettagliEstrattoContoTesto.setFont(new Font(Font.FontFamily.TIMES_ROMAN, 10,
Font.NORMAL, BaseColor.BLACK));
document.add(dettagliEstrattoContoTesto);
document.close();
docWriter.close();
return baos;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Try compressing the string containing the PDF first, then putting it into the DB compressed, then uncompress it when pulling it out. This will ensure that nothing is changed and the string is handled as binary.