Ok, so I have a RichTextBox user control in which the user can enter any number of Rich Text elements which then converts the contents to HTML. At the moment, I am working on tables specifically. For the most part, they work pretty easily, but when I try to save the RTF to a file and then load it again, the \trautofit1 control word disappears and the table width is reduced.
To save to an RTF file, I'm using: TextRange.Save(fileStream, DataFormats.Rtf);
I'm pretty sure the issue comes with how the RTF is saved, because the file that results from this has the shrunken table as well.
Here is the table before the save:
Here is the table after the save and load:
So the question: Is there anyway in which to counter this behavior, or is there a better way to get the RTF, or should I be using a different control word to autosize the width of the table?
Ok, well I found a solution but it isn't exactly what I was looking for. What brought about the decision to go this route was that this is how Word does it. When you go to create the table, I find the size of the RichTextBox, then divide it by the number of columns, then I explicitly set the width of each column with \cellx. Not the pretty solution I was looking for, but it works.
I used another hack solution, before saving data I change columns width:
if (table != null && table.Columns.Count == 2)
{
table.Columns[0].Width = new GridLength(200);
table.Columns[1].Width = new GridLength(200);
document.Blocks.Add(table);
}
Related
I am working on a program that generates an output document in Excel xlsx format. I wrote the functionality and was getting the expected output/result using Excel Interop, originally, but it was taking quite awhile to complete a single output so I am trying to duplicate the same functionality using OpenXML (currently using the ClosedXML library to simplify the conversion from the Excel Interop but I'm open to any other libraries or methods...)
The basic process is opening the template file (which has the initial print area [A1:M27] and print settings are already set up and defined) and then populating the template with the data. The first row of data starts in cell A11 with additional rows are inserted below this, as needed. (There is additional stuff on the template that is below this table of data, so the last row that is inserted is not the bottom of the actual print area.)
After inserting the second row of data, I have a function that will check if the value of the given cell and the value of the cell located immediately above it are the same. If so, then it checks to make sure that there aren't any page breaks located there before merging them.
Here's that section of relevant code:
For Each HBreak In outputSheet.PageSetup.RowBreaks
If HBreak = FirstCell.CellAbove.WorksheetRow.RowNumber Then Exit Sub
Next HBreak
When I generate the output, however, it still ends up merging cells across page breaks. I stepped through the code and found that outputSheet.PageSetup.RowBreaks is always empty... yet when I open the output file in Excel, there will be an automatic page break going right through the middle of the cells it merged.
I did a test and inserted a horizontal page break right where the data rows are inserted into the template to see if it would correctly detect manually-placed page breaks and then the check for a page break worked as intended... but only for the manually inserted break.
So it seems my issue is with the page break locations that are determined automatically based on the existing printing and page setup.
Is it possible to determine where the automatic page breaks are with OpenXML (or anything other than Excel Interop)?
Any help or advice would be greatly appreciated.
Edit/Update:
I managed to come up with a way to work-around this for the current situation, but it doesn't work very well after inserting the first initial page break.
I took the template and incrementally increased the row height until I found the point where increasing any row heights by one additional point caused the automatic page-break to shift. I wrote a function that summed the row heights before that pagebreak, giving me a value of 943.
Then, before checking for any page breaks, I call this procedure:
Private Sub InsertPageBreaks(outputSheet As IXLWorksheet)
Dim TotalHeight As Double = 0
Dim PageBreakHeight As Double = 943.5 ' Worksheet/Page Layout-specific value
' Reset/clear all of the horizontal row breaks
outputSheet.PageSetup.RowBreaks.Clear()
For x = 1 To (outputSheet.LastRowUsed(True).RowNumber)
TotalHeight += outputSheet.Row(x).Height
If TotalHeight > PageBreakHeight Then
' If the total height exceeds the page break point, insert a new
' new page break at this point and then reset TotalHeight
outputSheet.PageSetup.AddHorizontalPageBreak(x - 1)
TotalHeight = 0
End If
Next x
End Sub
The downside is that I will need to use a variation of this procedure for each different output template I use because of the differences in page layouts, scaling, page orientation, etc., so it isn't a very practical solution beyond this one specific application. Additionally, there appears to be a bit of "drift" that occurs after the first page break is inserted, and the pagebreaks no longer fit where Excel's automatic pagebreaks are inserted by the third page.
So... still looking for a better solution.
I load some texts from a database with different lengths into a textbox. (From 1 character to 1000 words...)
I use TextWrapping="Wrap", so if the text is to big for the width of the textbox, it will create a new line....
By saving the text, the added paragraph from TextWrapping="Wrap" will also be saved. But I don't want this. The original text shouldn't be changed in any way...
How can I display the text on a new line in the textbox without adding a "real" paragraph?
Is there a way I can determine if the paragraph was added from TextWrapping="Wrap" or if it belong to the original text?
Thanks
As #StevenRands mentioned, the source text won't be changed in any way by using TextWrapping.
It only affects the display of the text inside the TextBox.
Normally if you used text Wrapping,it wont affect the original source text.But anyways Before saving back to database you can remove the new line constants from your text box text which will give you the original text loaded from db.
I have an excel file(VSTO), which will be uploaded with data.
However I want to make one cell invisible, as it contains one of the ID's which should not be revealed to the user.
I use Excel.Range.Value2 property to set the value.
Now I want to make the value inside it invisible
I am using C#, how do I accomplish the above.
This will make cell content invisible, untill you click on them then you can change the data. Here
Microsoft.Office.Interop.Excel.Range descriptionRange31 = xlApp.get_Range("A18,A25,B18,B25");
descriptionRange31.NumberFormat = ";;;";
I am not sure how to make it invisible. However, you can just copy and save the value in a variable in memory and replace it by string.Empty.
Declare the variable in your plug-ins application object in such a way that it stays alive as long as Excel is open.
If you want to persist it even when Excel application is closed, then either write it to disk or save it in the properties of the Excel workbook (the same place that is visible in Properties page of the workbook) after encoding it.
I have worked on the VSTO Excel applications.
In my project i have used specials Ids to identify each column uniquely..
So, i would suggest rather than getting into coding you can do following 2 actions to make it invisible.
Go to ur visual studio, open design mode of the workbook.
Enter ur ids in columns or rows , wherever u want to (lets assume in column C and Row 5,6)
1.You can see the horizontal / vertical strips at the top and left side of excel which we use to resize the columns n rows ..just adjust it in a such a way that that particular column will be hidden
as u can see the image, i adjusted columns to Hide Column "C" and Rows to hide row no 5 and 6.
2.Now open excel (not from Visual stodio, from windows explorer) pres Alt+T+P+P
and protect the sheet using a perticular password and your are done.
Now user can not make any changes in columns or rows and date remains invisible.
Regards,
Sangram Nandkhile
I'm not sure you can make the contents of a cell "invisible." However, you could go a long way toward that goal by:
Placing the hidden information within a hidden column in a separate worksheet
Password protecting the worksheet structure to prevent unhiding of that hidden column
Hiding the protected worksheet
Password protecting the workbook's VBA project from editing
The security of this approach is not 100% because Excel protection is not exceedingly difficult to break. However, the combination of obscurity (since the worksheet tab is not even visible to the user) and protection of the VBA Project from editing (so even if someone knows the hidden sheet is there, it won't be as easy to code the unhide method) and password protection of the worksheet structure (so it won't be easy to unhide the protected column) should prevent all but the most determined peekers from seeing what you're hiding.
I have not worked with VSTO, so I can't code this for you. The approach is valid though, and all API hooks to achieve it are probably available.
I'm not sure if this answer match your level of question, but this if I would into your problem description. I would just make the font color same as the background and lock the cell from editing (which you of course handle from code, while write/change the value) and go for locking the excel sheet except the cells/regions that explicitly marked as opened.
m trying to break one large Excel spreadsheet into several. I've made good progress, but I'm running into some problems. Specifically, the values that get copied over don't retain their format (for instance, 40322 instead of 5/24/2010 and -101 instead of (101.00) ). I've tried using the style (see below) but that doesn't even get me the font, let alone the number format. Any help or a poke in the right direction would be appreciated.
There are 2 loops, one for row, one for column.
destinationSheet.Cells[i, j].Style = sourceSheet.Cells[i, j].Style;
Instead of looping for each cell, you can copy/paste the entire range of cells using the pastespecial method.
http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.namedrange.pastespecial(VS.80).aspx
I am using PDFsharp / MigraDoc to write tables and charts to PDF files. This worked great so far, however MigraDoc will always split my tables (vertically) when it should move the whole table to the next page in the document. How do I make sure the table will stay in one piece?
Table class of MigraDoc.DocumentObjectModel.Tables has a bool KeepTogether property however it seems to have no effect (either set to true or false).
Is there a way to do it manually? Is there any way to "measure" the distance from the end of the page and compare it to tables height? (Or any other way of knowing wether the table will be split or not)
Please note that I am using PDFsharp / MigraDoc for the first time. If there are any best practices I ought to know, please let me know. If there are some good examples out there (I saw those on PDFSharp's home page, but that's about it) I'd love to know about them!
You can set the KeepWith property of a Table Row to specify blocks that must be kept together.
If you know the table fits on one page, you can set the KeepWith property of the first row to (table.Rows.Count - 1) when the table is finished.