I am printing Avery labels generated from using iTextSharp. The last column of the three column sheet had to be moved over a little so I added some spaces:
case 3:
case 6:
case 9:
case 12:
case 15:
//fmp first
iTextSharp.text.Chunk chunkFmp1 = new iTextSharp.text.Chunk(string.Format(" {0}\n", patient.FmpSsn));
chunkFmp1.Font.SetFamily("Arial");
chunkFmp1.Font.Size = fontsize;
contents.Add(chunkFmp1);
//name
iTextSharp.text.Chunk chunkName1 = new iTextSharp.text.Chunk(string.Format(" {0}\n", patient.PatientName));
chunkName1.Font.SetFamily("Arial");
chunkName1.Font.Size = fontsize;
contents.Add(chunkName1);
//data
iTextSharp.text.Chunk chunkData1 = new iTextSharp.text.Chunk(string.Format(" {0} {1} {2}\n", "SEX:" + patient.PatientSex.Substring(0, 1), "DOB:" + patient.PatientDobString, "AGE:" + patient.PatientAge));
chunkData1.Font.SetFamily("Arial");
chunkData1.Font.Size = fontsize;
contents.Add(chunkData1);
//data2
iTextSharp.text.Chunk chunkBranch1 = new iTextSharp.text.Chunk(string.Format(" {0} {1} {2} {3}\n", patient.BranchOfService, patient.BillingCode, patient.Rank, patient.ReligionName));
chunkBranch1.Font.SetFamily("Arial");
chunkBranch1.Font.Size = fontsize;
contents.Add(chunkBranch1);
break;
And that results in the following:
You can see how all of the text is moved over a little but not the barcode. How do I align the barcode with the text?
I guess I didn't realize there is a setting for placement of the barcode:
contents.Add(new iTextSharp.text.Chunk(image39, 28, 0));
This pushes the code over 28 pixels (?) I think.
Related
I am currently stuck on a bit of program, I'm sure there is a way to do it but just can't think of it, so here it goes. so I am using eclipse window viewer and I made a GUI to how I want and I got a Ccombo with a few options to select from, and what I want to do is when a button is clicked I want the program to be able to see what they selected and then depending on what they selected have a different outcome put into another text field
OptionsOptimizer = new Shell();
OptionsOptimizer.setSize(450, 340);
OptionsOptimizer.setText("Options Optimizer");
Label lblSpread = new Label(OptionsOptimizer, SWT.NONE);
lblSpread.setAlignment(SWT.CENTER);
lblSpread.setBounds(10, 10, 213, 15);
lblSpread.setText("Type Of Spread");
CCombo combo = new CCombo(OptionsOptimizer, SWT.BORDER);
combo.setItems(new String[] {"Put Credit Spread", "Short Naked Put", "Put Broken Wing Butterfly", "Custom Naked Put", "Call Debit Spread", "Call Calander", "Call Ratio Backspread", "Put Diagonal", "Short Straddle", "Short Strangle", "Short Iron Condor", "Short Iron Butterfle"});
combo.setBounds(10, 31, 213, 21);
Button Enter = new Button(OptionsOptimizer, SWT.NONE);
Enter.addMouseListener(new MouseAdapter() {
public void mouseDoubleClick(MouseEvent e) {
double profit = Double.parseDouble(Profit.getText());
double margin = Double.parseDouble(Margin.getText());
double roi = profit/margin;
double roundroi = Math.round(roi*10000)/100.0;
ROI.setText("Your return on investment is " + roundroi + "%");
double percent = Double.parseDouble(ITM.getText());
double OTM = ((100 - percent)/100);
int day = Integer.parseInt(Days.getText());
double roc = (roi/day)*OTM;
double roundroc = Math.round(roc*10000)/100.0;
ROC.setText("Your return on capital per day is " + roundroc + "%");
double annual = roc*365*.4;
double roundannual = Math.round(annual*10000)/100.0;
Annual.setText("Your annual return is " + roundannual + "% if you invested 40% of your total equity");
Point spread = combo.getSelection();
if(spread.toString() == "Put Credit Spread")
{
Volitility.setText("A fall in implied volitility will help your position");
}
});
Enter.setBounds(159, 108, 75, 25);
Enter.setText("Evaluate");
}
I can see one problem with your code: Your are comparing the text of the Button using ==, but you should be using spread.toString().equals("Put Credit Spread").
See How do I compare strings in Java? for more information.
As a bit of advice: CCombo has a getSelectionIndex function that returns a integer value of the selected item beginning at 0, or -1 if no item is selected. Using this function would have the benefit of beeing able to change the Item text without needing to change the logic aswell.
Using iTextSharp version 5.5.8 (same bug existed in 5.5.7), there's an unpleasant bug when you add images to Chapters and Sections - the images and the section headings start out OK but quickly become offset relative to each other.
The PDF generated from the following code starts out correctly, it says "Section 1" and below it is the image. The next section ("Section 2") has a little of the image overlapping the section text, the next section is even worse, etc. I think it's the text that's mal-positioned, not the image.
Is this a known iTextSharp bug?
static Document m_doc = null;
static BaseFont m_helvetica = null;
static Font m_font = null;
static PdfWriter m_writer = null;
static Image m_image = null;
static void Main(string[] args)
{
m_doc = new Document(PageSize.LETTER);
m_helvetica = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
m_font = new Font(m_helvetica, 10.0f);
m_writer = PdfWriter.GetInstance(m_doc, new FileStream("Output.pdf", FileMode.Create));
m_writer.StrictImageSequence = true;
m_doc.Open();
m_doc.Add(new Chunk("Created by iTextSharp version " + new iTextSharp.text.Version().GetVersion, m_font));
Chapter chapter = new Chapter("Chapter 1", 1);
chapter.TriggerNewPage = false;
if (m_image == null)
{
m_image = Image.GetInstance(new Uri("https://pbs.twimg.com/profile_images/2002307628/Captura_de_pantalla_2012-03-17_a_la_s__22.14.48.png"));
m_image.ScaleAbsolute(100, 100);
}
for (int i = 0; i < 5; i++)
{
Section section = chapter.AddSection(18, "Section " + (i + 1));
section.Add(new Chunk(" ", m_font));
section.Add(m_image);
}
m_doc.Add(chapter);
m_doc.Close();
}
From the documentation for the Java version:
A Section is a part of a Document containing other Sections, Paragraphs, List and/or Tables.
Further looking at the Add() method in the C# source we see:
Adds a Paragraph, List, Table or another Section
Basically, instead of a Chunk use a Paragraph. So instead of this
section.Add(new Chunk(" ", m_font));
Use this:
section.Add(new Paragraph(new Chunk(" ", m_font)));
Or even just this:
section.Add(new Paragraph(" ", m_font));
I am using the iText library to generate text. I am loading the Arial Unicode MS font which does not contain a bold style so iText is simulating the bold. This works fine, but the weight of the bold font appears too heavy compared with text generated using the Java API or even using Microsoft Word.
I tried to get the weight from the FontDescriptor, but the value returned is always 0.0
float weight = font.getBaseFont().getFontDescriptor(BaseFont.FONT_WEIGHT, fontSize);
Is there a way I can change the weight of a simulated bold font?
As an addendum to #Chris' answer: You do not need to construct those Object[]s as there is a Chunk convenience method:
BaseFont arialUnicodeMs = BaseFont.createFont("c:\\Windows\\Fonts\\ARIALUNI.TTF", BaseFont.WINANSI, BaseFont.EMBEDDED);
Font arial12 = new Font(arialUnicodeMs, 12);
Paragraph p = new Paragraph();
for (int i = 1; i < 100; i++)
{
Chunk chunk = new Chunk(String.valueOf(i) + " ", arial12);
chunk.setTextRenderMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, i/100f, null);
p.add(chunk);
}
document.add(p);
results in
EDIT
Sorry, I just realized after posting this that you're using iText but my answer is for iTextSharp. You should, however, be able to use most of the code below. I've updated the source code link to reference the appropriate Java source.
Bold simulation (faux bold) is done by drawing the text with a stroke. When iText is asked to draw bold text with a non-bold font it defaults to applying a stroke with a width of of the font's size divided by 30. You can see this in the current source code here. The magic part is setting the chunk's text rendering mode to a stroke of your choice:
//.Net code
myChunk.Attributes[Chunk.TEXTRENDERMODE] = new Object[] { PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, MAGIC_NUMBER_HERE, null };
//Java code
myChunk.attributes.put(Chunk.TEXTRENDERMODE, new Object[]{Integer.valueOf(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE), MAGIC_NUMBER_HERE, null});
Knowing that you can just apply the same logic but using your weight preference. The sample below creates four chunks, the first normal, the second faux-bold, the third ultra-heavy faux-bold and the fourth ultra-lite faux-bold.
//.Net code below but should be fairly easy to convert to Java
//Path to our PDF
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "test.pdf");
//Path to our font
var ff = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "ARIALUNI.TTF");
//Normal document setup, nothing special here
using (var fs = new FileStream(testFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
//Register our font
FontFactory.Register(ff, "Arial Unicode MS");
//Declare a size to use throughout the demo
var size = 20;
//Get a normal and a faux-bold version of the font
var f = FontFactory.GetFont("Arial Unicode MS", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size, iTextSharp.text.Font.NORMAL);
var fb = FontFactory.GetFont("Arial Unicode MS", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, size, iTextSharp.text.Font.BOLD);
//Create a normal chunk
var cNormal = new Chunk("Hello ", f);
//Create a faux-bold chunk
var cFauxBold = new Chunk("Hello ", fb);
//Create an ultra heavy faux-bold
var cHeavy = new Chunk("Hello ", f);
cHeavy.Attributes = new Dictionary<string, object>();
cHeavy.Attributes[Chunk.TEXTRENDERMODE] = new Object[] { PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, size / 10f, null };
//Create a lite faux-bold
var cLite = new Chunk("Hello ", f);
cLite.Attributes = new Dictionary<string, object>();
cLite.Attributes[Chunk.TEXTRENDERMODE] = new Object[] { PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE, size / 50f, null };
//Add to document
var p = new Paragraph();
p.Add(cNormal);
p.Add(cFauxBold);
p.Add(cHeavy);
p.Add(cLite);
doc.Add(p);
doc.Close();
}
}
}
We want to add a water mark with user email & name on top of our pdf before we send it. I've written code that does that and it is working great. I want to check if this is the best way of doing this. We want the water mark to be split into two lines at the top of the pdf.
, I used "ShowTextAligned()" twice with different "y" coordinates to achieve that.
private MemoryStream StampPdf(string pdfPath, string name, string email)
{
var memoryStream = new MemoryStream();
var reader = new PdfReader(pdfPath);
var pageCount = reader.NumberOfPages;
var stamper = new PdfStamper(reader, memoryStream);
var textAngle = 0;
var fontSize = 14;
var font = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.WINANSI, BaseFont.EMBEDDED);
var watermarkLine1 = "Personal use only for " + name;
var watermarkLine2 = "at " + email;
using (stamper)
{
for (var i = 1; i <= pageCount; i++)
{
var mediaBox = reader.GetPageSize(i);
var overContent = stamper.GetOverContent(i);
overContent.BeginText();
overContent.SetColorFill(BaseColor.RED);
overContent.SetFontAndSize(font, fontSize);
overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, watermarkLine1, 10, mediaBox.Top - 20, textAngle);
overContent.ShowTextAligned(PdfContentByte.ALIGN_LEFT, watermarkLine2, 10, mediaBox.Top - 40, textAngle);
overContent.EndText();
}
}
reader.Close();
stamper.Close();
return memoryStream;
}
I want to confirm two things:
"Is it possible to use ShowTextAligned() to wrap text that reaches the end of the line?"
"Does ShowTextAligned() honor carriage return/newline?"
Thanks,
-Samah
Answer to question 1.: No, you need the ColumnText object to do that.
Answer to question 2.: No, showTextAligned() ignores newline characters.
I am quite new to iText and trying to accomplish the following:
read a list of text files from local hd
arrange the texts of the files in a 2-column layout pdf file
add a consecutively numbered index before each text
I started with the MovieColumns1 example (http://itextpdf.com/examples/iia.php?id=64) and ended up with the following code:
final float[][] COLUMNS_COORDS = { { 36, 36, 296, 806 }, { 299, 36, 559, 806 } };
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(document, resultFile);
document.open();
ColumnText ct = new ColumnText(writer.getDirectContent());
ct.setSimpleColumn(COLUMNS_COORDS[0][0], COLUMNS_COORDS[0][1],
COLUMNS_COORDS[0][2], COLUMNS_COORDS[0][3]);
File textDir = new File("c:/Users/raddatz/Desktop/123/texts/");
File[] files = textDir.listFiles();
int i = 1;
int column = 0;
for (File file : files) {
String text = FileUtils.readFileToString(file, "UTF-8");
float yLine = ct.getYLine();
System.out.println("adding '" + file.getName() + "'");
PdfPCell theText = new PdfPCell(new Phrase(text, new Font(Font.HELVETICA, 10)));
theText.setBorder(Rectangle.NO_BORDER);
theText.setPaddingBottom(10);
PdfPCell runningNumber = new PdfPCell(new Phrase(new DecimalFormat("00").format(i++), new Font(
Font.HELVETICA, 14, Font.BOLDITALIC,
new Color(0.7f, 0.7f, 0.7f))));
runningNumber.setBorder(Rectangle.NO_BORDER);
runningNumber.setPaddingBottom(10);
PdfPTable table = new PdfPTable(2);
table.setWidths(new int[] { 12, 100 });
table.addCell(runningNumber);
table.addCell(theText);
ct.addElement(table);
int status = ct.go(true);
if (ColumnText.hasMoreText(status)) {
column = Math.abs(column - 1);
if (column == 0) {
document.newPage();
System.out.println("inserting new page with size :" + document.getPageSize());
}
ct.setSimpleColumn(
COLUMNS_COORDS[column][0], COLUMNS_COORDS[column][1],
COLUMNS_COORDS[column][2], COLUMNS_COORDS[column][3]);
yLine = COLUMNS_COORDS[column][3];
System.out.println("correcting yLine to: " + yLine);
} else {
ct.addElement(table);
}
ct.setYLine(yLine);
System.out.println("before adding: " + ct.getYLine());
status = ct.go(false);
System.out.println("after adding: " + ct.getYLine());
System.out.println("--------------------------------");
}
document.close();
Here you can see the result:
http://d.pr/f/NEmx
Looking at the first page of the resulting PDF I assumed everything was working out fine.
But on second page you can see the problem(s):
text #31 is not displayed completely (first line + index is cut / not in visible area)
text #46 is not displayed completely (first three lines + index is cut / not in visible area)
On page 3 everything seems to be ok again. I am really lost here.
-- UPDATE (2013-03-14) --
I have analyzed the contents of the PDF now. The problem is not that content is show in non-visible areas but that the content is not present in the pdf at all. The missing part of the content is exactly the one which would have fit in the previous column / page. So it seems like ColumnText.go(true) is manipulating the object passed by addElement() before. Can someone confirm this? If so: what can I do about it?
-- end UPDATE (2013-03-14) --
Looking forward to your reply
regards,
sven
Solved! As soon as ColumnText indicates a table will not fit the current column I reinitialize ct with a new instance of ColumnText and add the table again.
In other words:
Each instance of ColumnText is exactly dealing one column of my document.
if (ColumnText.hasMoreText(status) || mediaPoolSwitch) {
column = Math.abs(column - 1);
if (mediaPoolSwitch) {
currentMediaPool = mediapool;
column = 0;
}
if (column == 0) {
document.newPage();
writeTitle(writer.getDirectContent(), mediapool.getName());
}
ct = new ColumnText(writer.getDirectContent());
ct.addElement(table);
ct.setSimpleColumn(
COLUMNS_COORDS[column][0], COLUMNS_COORDS[column][1],
COLUMNS_COORDS[column][2], COLUMNS_COORDS[column][3]);
yLine = COLUMNS_COORDS[column][3];
LOG.debug("correcting yLine to: " + yLine);
} else {
ct.addElement(table);
}
ct.setYLine(yLine);
ct.go();