How to add under line under a spacebar. It is not adding space under the empty spaces.
I tried with 2-3 example and it failed to add underline under space.
1.
para = New Paragraph(New Chunk("abc. ", underlined_font))
cell = New PdfPCell(para)
cell.Border = 0
cell.BorderWidthBottom = 0
document.Add(cell)
Dim str_required_space As New String(" "c, 20)
para = New Paragraph(New Chunk(str_required_space, underlined_font))
cell = New PdfPCell(para)
cell.Border = 0
cell.BorderWidthBottom = 0
document.Add(cell)
I can't use border of cell as the length of the input string is uncertain. So I am using underline.
Please help to add spaces under space.
My Requirement image
Thanks
[Edit]
If I follow answer 1 then result would be like below
asdasd asdsad scasdnk kjashdk kasbas ckasbd ascuasc ksajcasc
asdansjdnasjakjsnasndasdmlaskdm
________________________________________________________________
But I need Below result.
asdasd asdsad scasdnk kjashdk kasbas ckasbd ascuasc ksajcasc
________________________________________________________________
asdansjdnasjakjsnasndasdmlaskdm
________________________________________________________________
I tried with Ansii Code. Not working for me :(
Dim str_required_space As New String(ChrW(32), (119 - (str_synopsis.Length Mod 119)))
para = New Paragraph(str_required_space)
cell = New PdfPCell(para)
cell.Border = 0
doc.Add(cell)
Please read chapter 2 of my book, more specifically the section about vertical position marks, separators, and tabs (section 2.2.6).
Looking at your image (ignoring the soft porn images on that site, please avoid such links in the future), I think you need a line as shown in figure 2.9 (the line under the names of the directors). The code that results in the PDF shown in that screen shot can be found here.
This is how it's done in Java:
Paragraph p = new Paragraph("abc.");
LineSeparator line = new LineSeparator(1, 100, null, Element.ALIGN_CENTER, -2);
p.add(line);
document.add(p);
It should be a no-brainer to adapt this code to C#. If you do experience problems, then you can find the ported versions of the book samples here.
What did you do wrong in your code?
This doesn't make sense:
para = New Paragraph(New Chunk("abc. ", underlined_font))
The content of the Chunk is trimmed, which explains why the spaces disappear. An alternative would be to use non-breaking space characters (ASCII code 160) instead of regular space characters (ASCII code 32).
Update
My previous answer was based on your image and it was the correct answer to your initial question. However: you have now changed your question (instead of creating a new question).
You can meet your requirement by using a page event, more specifically, by implementing the OnGenericTag() method. This method is described in chapter 5 of my book.
In Java, the implementation would look like this:
public void onGenericTag(PdfWriter writer, Document pdfDocument,
Rectangle rect, String text) {
Rectangle page = pdfDocument.getPageSize();
float x1 = page.getRight(pdfDocument.rightMargin());
float x2 = page.getLeft(pdfDocument.leftMargin());
float y = rect.getBottom() - 3;
PdfContentByte canvas = writer.getDirectContent();
canvas.moveTo(x1, y);
canvas.lineTo(x2, y);
canvas.stroke();
}
You need to create an instance of the page event with that implementation (e.g. a class that you wrote and that you named MyPageEvent) and declare that page event to the PdfWriter using the setPageEvent() method:
writer.setPageEvent(new MyPageEvent());
You can now declare you Chunk and Paragraph like this:
Chunk chunk = new Chunk(long_text);
chunk.setGenericTag("");
Paragraph p = new Paragraph(chunk);
document.add(p);
It is important that you construct your paragraph with only one Chunk object. If you have more than one Chunk in the paragraph, parts of the line will look thicker.
Related
So I am going off memory here because I cannot see the code I am trying to figure this out for at the moment, but I am working with some old VB Script code where there is a data connection that is set like this:
set objCommand = Server.CreateObject("ADODB.command")
and I have a field from the database that is being stored in a variable like this:
Items = RsData(“Item”).
This specific field in the database is a long string of
text:
(i.e. “This is part of a string of text…Header One: Here is text after header one… Header Two: Here is more text after header two”).
There are certain parts of the text that I wish to store as a variable that are between two index positions in the long string of text within that field. They are separated by headers that are stored in the text field above like this: “Header One:” and “Header Two:”, and I want to capture all text that occurs in between those two headers of text and store them into their own variable (i.e. “Here is text after header one…”).
How do I achieve this? I have tried to use the InStr method to set the index but from how I understand how this works it will only count the beginning of where a specific part of the string occurs. Am I wrong in my thinking of this? Since that is the case, I am also having trouble getting the Mid function to work. Can some one please show me an example of how this is supposed to work? Remember, I am only going off of memory so please forgive me that I am unable to provide better code examples now. I hope my question makes sense!
I am hopeful that someone can help me with an answer tonight so I can try this out tomorrow when I am near the code again! Thank you for your efforts and any help offered!
You can extract all the substrings starting with the text Header and ending just before either the next Header or end-of-string. I have used regular expression to implement that and it is working for me. Have a look at the code below. If I get a simpler(non-regex solution), I will update the answer.
Code:
strTest = "Header One: Some random text Header Two: Some more text Header One: Some random textwerwerwefvxcf234234 Header Three: Some more t2345fsdfext Header Four: Some randsdfsdf3w42343om text Header Five: Some more text 123213"
set objReg = new Regexp
objReg.Global = true
objReg.IgnoreCase = false
objReg.pattern = "Header[^:]+:([\s\S]*?)(?=Header|$)" '<---Regex Pattern. Explained later.
set objMatches = objReg.Execute(strTest)
Dim arrHeaderValues() '<-----This array contains all the required values
i=-1
for each objMatch in objMatches
i = i+1
Redim Preserve arrHeaderValues(i)
arrHeaderValues(i) = objMatch.subMatches.item(0) '<---item(0) indicates the 1st group of each match
next
'Displaying the array values
for i=0 to ubound(arrHeaderValues)
msgbox arrHeaderValues(i)
next
set objReg = Nothing
Regex Explanation:
Header - matches Header literally
[^:]+: - matches 1+ occurrences of any character that is not a :. This is then followed by matching a :. So far, keeping the above 2 points in mind, we have matched strings like Header One:, Header Two:, Header blabla123: etc. Now, whatever comes after this match is relevant to us. So we will capture that inside a Group as shown in the next breakup.
([\s\S]*?)(?=Header|$) - matches and captures everything(including newlines) until either the next Header or the end-of-the-string(represented by $)
([\s\S]*?) - matches 0+ occurrences of any character and capture the whole match in Group 1
(?=Header|$) - match and capture the above thing until another instance of the string Header or end of the string
Click for Regex Demo
Alternative Solution(non-regex):
strTest = "Header One: Some random text Header Two: Some more text Header One: Some random textwerwerwefvxcf234234 Header Three: Some more t2345fsdfext Header Four: Some randsdfsdf3w42343om text Header Five: Some more text 123213"
arrTemp = split(strTest,"Header") 'Split using the text Header
j=-1
Dim arrHeaderValues()
for i=0 to ubound(arrTemp)
strTemp = arrTemp(i)
intTemp = instr(1,strTemp,":") 'Find the position of : in each array value
if(intTemp>0) then
j = j+1
Redim preserve arrHeaderValues(j)
arrHeaderValues(j) = mid(strTemp,intTemp+1) 'Store the desired value in array
end if
next
'Displaying the array values
for i=0 to ubound(arrHeaderValues)
msgbox arrHeaderValues(i)
next
If you don't want to store the values in an array, you can use Execute statement to create variables with different names during run-time and store the values in them. See this and this for reference.
I am using OpenOffice Calc spreadsheet formulas with psuedo-random numbers to generate arrays of arithmetic problems which I can easily update to creating new worksheets (I'm a teacher)
Problems are output as formula mark-ups in string form. OOo Math formulas use these string commands typed into the editor to display nicely formatted maths expressions.
I can do this next step manually:
1) go to source cell and copy string mark-up to clipboard
2) select target cell and clear existing contents and objects
3) create new Math object anchored to target cell
4) open Math editor window and paste in mark-up string
5) exit Math editor window and return cursor to source cell
Result: a nice maths expression of given arithmetic problem.
I need to be able to do this for entire columns of source cells on various sheets.
...even better, to then add a listener to dynamically update as sources are updated.
I found code here: Cell content inside formula that achieves this for a fixed pair of cells, but despite all my best efforts, I have had to admit defeat - generalising this code is simply beyond my expertise!
The absolute ideal would be a macro function that I could call like a spreadsheet function; with input arguments (sourceCell, targetCell, listenerON/OFF) that could run the above algorithm and dynamically update if required.
Can anybody help me? A solution like this, or any kind of workaround would be immensely helpful.
UPDATE 2016/10/27
Thank you Jim K, that did work, but use of the dispacher comes with a whole host of difficulties I hadn't foreseen.
I just found Charlie Young's post in the OpenOffice forum which makes use of the API. I have included my adaptation of his code below.
Can anybody help me to integrate it into a function in a similar way as I've described? I don't know how to solve placement of the Math object in to the target cell.
The API code is great as it will create a new Math object each time the code is updated. Existing ones do need to be deleted though.
I think the limitation of not being able to delete existing objects from within a function is going to persist. Would this be the case even if done by a subroutine called by the function?
function InsertFormula(paraFromCell, paraToCell)
Dim oDoc As Object
Dim oSheet As Object
Dim oShape As Object
oDoc = ThisComponent
oSheet = oDoc.Sheets(0)
oShape = oDoc.createInstance("com.sun.star.drawing.OLE2Shape")
oShape.CLSID = "078B7ABA-54FC-457F-8551-6147e776a997"
oSheet.Drawpage.Add(oShape)
oShape.Model.Formula = paraFromCell
oShape.setSize(oShape.OriginalSize)
end function
NEXT UPDATE
I've been managing to solve my own problems quite quickly now...
I've decided to go with a sub, not a function, so I can access the sheet to delete existing objects. Code is attached - Source cells are in Column C and target cells in matching rows of Column A. So far I am only able to send objects to $A$1.
How do I anchor each new object to a specific cell?
REM ***** BASIC *****
Sub InsertThisFormula
Dim oDoc As Object
Dim oSheet As Object
Dim oShape As Object
Dim sourceCell As Object
Dim targetCell As Object
oDoc = ThisComponent
oSheet = oDoc.Sheets(1)
Dim n As Integer
n = 1 'number of rows of formulas
for i = 0 To n-1
rem loop through cells
sourceCell = oSheet.getCellByPosition(2, i)
targetCell = oSheet.getCellByPosition(0, i)
rem clear target cell object/s
targetCell.ClearContents(128)
oShape = oDoc.createInstance("com.sun.star.drawing.OLE2Shape")
oShape.CLSID = "078B7ABA-54FC-457F-8551-6147e776a997"
oSheet.Drawpage.Add(oShape)
oShape.Model.Formula = sourceCell.string
oShape.setSize(oShape.OriginalSize)
Next i
End Sub
Starting from Mifeet's example, add this to My Macros:
rem ----------------------------------------------------------------------
rem Creates a math formula from text
Function InsertFormulaFromCell(paramCellFrom, paramCellTo)
dim document as object
dim dispatcher as object
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem go to cell containing markup and copy it
dim fromCellArgs(0) as new com.sun.star.beans.PropertyValue
fromCellArgs(0).Name = "ToPoint"
fromCellArgs(0).Value = paramCellFrom
dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, fromCellArgs())
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())
rem go to cell where I want the formula displayed
dim toCellArgs(0) as new com.sun.star.beans.PropertyValue
toCellArgs(0).Name = "ToPoint"
toCellArgs(0).Value = paramCellTo
dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, toCellArgs())
rem open Star.Math
oDesk = createUnoService ("com.sun.star.frame.Desktop")
dispatcher.executeDispatch(document, ".uno:InsertObjectStarMath", "", 0, Array())
document = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
rem paste clipboard using Array() as place-holder for variable name
dispatcher.executeDispatch(document, ".uno:Paste", "", 0, Array())
rem exit Star.Math
dispatcher.executeDispatch( _
document, ".uno:TerminateInplaceActivation", "", 0, Array())
InsertFormulaFromCell = "Math Formula updated " & Now()
End Function
To run it, put this formula in cell C5:
=INSERTFORMULAFROMCELL("$C$3","$C$20")
Now when the values get updated, it creates another formula.
Note: I could not get the .uno:Delete section of Mifeet's code to work, perhaps because functions are not supposed to access other cells. This may require manually deleting the formulas before creating new ones.
(Posted solution on behalf of the OP).
This is now solved. After a lot of searching, I found what I needed! Simple really. Future improvements might be to resize cells appropriately. Happy for now. Thanks to Jim K and the rest of the Stack Overflow community!
Complete macro below:
REM ***** BASIC *****
Sub InsertThisFormula
Dim oDoc As Object
Dim oSheet As Object
Dim oShape As Object
Dim sourceCell As Object
Dim targetCell As Object
oDoc = ThisComponent
oSheet = oDoc.Sheets(1)
Dim n As Integer
n = 6 'number of rows of formulas
for i = 0 To n-1
rem loop through cells
sourceCell = oSheet.getCellByPosition(2, i)
targetCell = oSheet.getCellByPosition(3, i)
rem clear target cell object/s
targetCell.ClearContents(128)
oShape = oDoc.createInstance("com.sun.star.drawing.OLE2Shape")
oShape.CLSID = "078B7ABA-54FC-457F-8551-6147e776a997"
oSheet.Drawpage.Add(oShape)
oShape.Model.Formula = sourceCell.string
oShape.setSize(oShape.OriginalSize)
oShape.Anchor = targetCell
oShape.MoveProtect = True
Next i
End Sub
I have three part in my PDF generating document using iTextSharp library.
The Header and footer I am printing using OnEndPage() of PdfPageEventHelper class. The header and footer printing well in all pages.But problem in printing large table content from middle of the page.
Now, I am facing problem when I have more that 100 table rows content to print on middle of the page.
On first page (middle of the page) I am printing table with more than 100 rows, but in this case it leave the first page empty and start printing table content on second page. Here is my table that I am trying to print on first page
PdfPTable table = new PdfPTable(5);
table.HeaderRows = 1;
table.SplitLate = false;
table.SplitRows = false;
table.SetTotalWidth(new float[] { 100, 75, 75, 75, 75 });
table.LockedWidth = true;
for (int i = 0; i < 150; i++)
{
PdfPCell cell = new PdfPCell(new phrase());
cell.Colspan = 5;
table.AddCell(cell);
}
I am using iTextSharp version: 5.4.5.0
Is there any configuration need to do, that will prevent page break?
But I am getting actual result in this format
Allow me to comment on these two lines:
table.SplitLate = false;
table.SplitRows = false;
The first line tells iTextSharp what it should do if a row doesn't fit a page. If you set this value to false, rows will be split late. For instance: you have a big row that doesn't fit the current page. In that case, the row will be forwarded to the next page. If it still doesn't fit the page, then another decision needs to be made: should the row be split or not?
The second line gives iTextSharp the answer to that question. If the value of SplitRows is true, then the row will be split. If the value is false, the row will be dropped. Allow me to quote the official documentation (p115 of "iText in Action - Second Edition"):
Ths is a dangerous line, because now not one row will be split. Rows that are too high to fit on a page will be dropped from the table!
I have the feeling that you want all the rows to show up in the table, so I suggest that you change the two lines I mentioned to:
table.SplitLate = true;
table.SplitRows = true;
Actually: why don't you just remove those two lines? The default value of SplitLate and of SplitRows is true.
Same thing happened to me using nested tables.
I solved this problem using .SplitLate = false; in the first table :)
What I want is shown in the docs in the picture http://doc.qt.io/qt-4.8/qactiongroup.html#details, but I cannot figure out how to do it. I can create a separator by
QAction * separator = new QAction("This is ignored", actionGroup);
separator->setSeparator(true);
but then it is just a line. How is the "Alignment" text added to the action in the example?
Following your link, then to the "Menus" example link (where your example is excerpted from) and then to mainwindow.cpp (which is one of the source files for that example), I reach: http://doc.qt.io/qt-4.8/qt-mainwindows-menus-mainwindow-cpp.html
The last function in that source file is createMenus which contains the following:
formatMenu = editMenu->addMenu(tr("&Format"));
formatMenu->addAction(boldAct);
formatMenu->addAction(italicAct);
formatMenu->addSeparator()->setText(tr("Alignment"));
formatMenu->addAction(leftAlignAct);
formatMenu->addAction(rightAlignAct);
formatMenu->addAction(justifyAct);
formatMenu->addAction(centerAct);
formatMenu->addSeparator();
formatMenu->addAction(setLineSpacingAct);
formatMenu->addAction(setParagraphSpacingAct);
The important bit is the fourth line in: setText on the separator added by addSeparator()
This can be done using a QLabel with a QWidgetAction (e.g. in python):
label = QtGui.QLabel("<b>At least it is rich text!</b>")
label_action = QtGui.QWidgetAction(self)
label_action.setDefaultWidget(label)
menu.addAction(label_action)
i have a page in which i am displaying the name of all the users i want to filter their names on the basis of first character for that i want to show A B C D ....X Y Z filters on the top on clicking of which it will filter the names accordingly my problem is not the query part but how to add these letters do i have to add 26 link buttons separately or there is some work around for example you might have seen such type of behavior in some music sites for filtering the songs with starting character.
These are few useful links how to do alphabetical paging
1. http://www.highoncoding.com/Articles/209_GridView_Alphabet_Paging.aspx
2. http://aspdotnetcodebook.blogspot.com/2008/03/how-to-add-alphabet-paging-in-gridview.html
Use ASCII characters codes to do this, for example:
var letters = new List<string>()
for(int i = 65; i < 91; i++)
letters.Add(Convert.ToChar(i).ToString());
Display it by adding links to page:
foreach(letter in letters)
{
var hyperlink = new Hyperlink()
{
NavigateUrl = string.Format("Filter.aspx?letter={0}", letter),
Text = letter
}
Page.Controls.Add(hyperlink);
}
Of course instead of Page you can use any other container you want, you just need to add those hyperlinks to controls collection.
Also take care to run this code in proper method, for example by overriding CreateChildControls method.
Regards