I'm writing a program to display the contents of an Excel worksheet using a Grid. To that end, I'm retrieving the worksheet as one big string full of XML using Office Interop, like so :
// Get the cells Range from Excel:
Range rng = sheet.get_Range(Cell(row1, col1), Cell(row2, col2));
// Get the XML representing that Range:
return rng.get_Value(XlRangeValueDataType.xlRangeValueXMLSpreadsheet);
I could create a FlowDocument from this XML string, and if I do assign it to a control on my GUI then that control will render the XML so that it looks exactly like what Excel shows. But I will have all the cells in the Range rendered onto a single control, which is not what I want : I want to be able to render any given cell onto any given control.
I couldn't find a fast and elegant way to extract the XML for individual cells via Interop : it just takes forever and a week. So I spent a whole day writing a class that parses the big XML string into an array of XML fragments each representing a cell. The strings in that array look like this :
<Cell><ss:Data ss:Type="String" xmlns="http://www.w3.org/TR/REC-html40"><Font html:Color="#000000">Some random text with </Font><B><Font html:Color="#000000">some bold characters</Font></B><Font html:Color="#000000">, and so on and so forth</Font></ss:Data></Cell>
This is actually HTML : from Visual Studio's debugger I can use the HTML viewer and it'll show me this :
Some random text with some bold characters, and so on and so forth
And by the way, this line was rendered correctly by the Stack Overflow website as soon as I pasted it in.
So I felt pretty confident that I could now create, programmatically, FlowDocument objects for each Excel cell, assign them to my GUI controls, and I'd get nice rendering of my Excel cells in any layout I care to program.
Except this doesn't work. When I put the FlowDocument into a control, the control just displays the HTML source code, it does not render it.
Here's how I create the FlowDocument :
FlowDocument tmp = new FlowDocument();
TextRange tr = new TextRange(tmp.ContentStart, tmp.ContentEnd);
byte[] byteArray = Encoding.ASCII.GetBytes(string_full_of_html);
MemoryStream stream = new MemoryStream(byteArray);
tr.Load(stream, DataFormats.Rtf);
(to explain : I allocate a FlowDocument, then create a TextRange through which I'll load the HTML, then turn my string full of HTML into a stream, then feed that stream to the TextRange)
I've tried different "DataFormats" : HTML, oddly, doesn't work. It gives me the exception "'HTML Format' data format not supported". RTF works but, like HTML, only displays the string I fed in, it doesn't render it.
Visual Studio can render my XML strings with its "HTML Visualizer", and I understand it is written with WPF. So I know there's a mechanism in there that does what I need, but I can't find it. That's where you come in, brave code Jedis !
Related
Am trying to achieve certain PDF automation with Acrobat SDK. So far, with the help of examples, I was able to update fillable PDF forms programmatically. However, I am now facing a scenario where I need to number these fillable fields sequentially.
This is easy in case of text fields which accept string values. However, I cannot do the same with checkboxes or radiobuttons etc as they are expecting certain predefined values to make them check/un-check.
ItextSharp has PdfCanvas class which has BeginText method write text on a rectangular bounding box.
Do we have something similar in Adobe?. I have the cordinates from GetRect() method
see code below:
CAcroApp acroApp = new AcroAppClass();
CAcroAVDoc avDoc = new AcroAVDocClass();
CAcroPDDoc pDDoc = new AcroPDDocClass();
CAcroPDPage pDPage;
CAcroPDAnnot pDAnnot;
avDoc.Open("Fillable PDF", "");
pDDoc = (CAcroPDDoc)avDoc.GetPDDoc();// gets PDDoc from AVDoc
pDPage = (CAcroPDPage)pDDoc.AcquirePage(0);// gets the 1st page
pDAnnot = (CAcroPDAnnot)pDPage.GetAnnot(8);// Index 8 is checkbox
var x = pDAnnot.GetRect();// holds the left,right,top,bottom value
Since I couldn't find anything similar for inserting text into checkbox, I was thinking of using an alternate approach where I remove the checkbox from the PDF using RemoveAnnot() method and adding a textbox at the same position.
pDPage = (CAcroPDPage)pDDoc.AcquirePage(0)
pDPage.RemoveAnnot(8);// this removes the fillable checkbox and leaves a square figure in PDF
Now, Any idea on how can I add a textbox in same position?
Or in general, Is it possible to change the field type from checkBox to textbox ?
There are little to no examples on "Creating Fillable forms programmatically with Acrobat SDK"
Any suggestion or guidance will greatly help me .
I dont know how achieve this, I have to create an informative report with images. For this, I use an excell template (It helps me with the format and with the position of the text where to place the respective information). The images are generated perfectly. I convert this XLS to PDF with the property
DocumentToMemoryStream (excelTemplate, XlsxSaveOptions.XlsxDefault);
This report generate blank pages in the PDF. How can I remove these blank pages, before the excel is generated?
Without checking your spreadsheet it's impossible to tell from where do those empty pages come from, so can you upload your XLS?
Anyway, do you perhaps have some explicitly defined horizontal or vertical page breaks?
If yes, can you remove the ones you don't need?
Or, do you perhaps have empty columns at the end which have some kind of styling or formatting?
If yes, then you could try using something like this to remove those empty columns from exporting to PDF:
var workbook = ExcelFile.Load("input.xls");
var worksheet = workbook.Worksheets.ActiveWorksheet;
worksheet.NamedRanges.SetPrintArea(
worksheet.GetUsedCellRange(true));
var options = new PdfSaveOptions();
options.SelectionType = SelectionType.ActiveSheet;
workbook.Save("output.pdf", options);
I had a counter of the rows of the document I was writing on, thanks to the help of #Mario Z, I use this function, before the save and solve my problem of blank pages
wsimgs.NamedRanges.SetPrintArea(wsimgs.Cells.GetSubrange("A1",CellRange.RowColumnToPosition (countRow, 10)));
I am generating a block of text via C# Stringbuilder, with appropriately tab-delimited text (new lines, "\t", etc.) and displaying the text within a tag in my web application. If I copy/paste this to Excel, all the text pastes into the first column on the spreadsheet.
If I copy the outerHTML of the block (Chrome) or copy/paste into Notepad++ and THEN paste to Excel, all the data pastes neatly into individual cells - which is the desired outcome of this effort. Can anyone tell me what I need to do in order to be able to copy the text from my application and paste it into Excel, so that the text pastes into individual cells (ie, keeps the tab-delimited format)?
Unfortunately, it appears an extra step is required.
The default behaviour of paste in Excel (& many other applications) is to use the original format of the contents of the clipboard.
Copying from a web application/HTML page will result in the clipboard contents being flagged as HTML. The clipboard contents will have the tab character, but as HTML renders tabs to whitespace (compacting to a single whitespace if there are multiple tabs) - just using control-V will convert the tabs to spaces & the contents will appear in a single cell when pasting into Excel..
You will need to use the "Paste Special" option & select "Unicode text" to retain the tabs. There is no way to set this by default : https://answers.microsoft.com/en-us/msoffice/forum/msoffice_excel-mso_windows8-mso_365hp/how-to-change-default-paste-behavior-with-ctrl-v/f58da075-8fd5-4c80-a64b-5e71ec8ad38b?auth=1
Copying the outerHTML of Chrome sets the clipboard format to text in the first place, pasting to Notepad++ does paste as text rather than HTML then recopying sets the format to text - which is why these methods work.
I was able to paste to Excel and keep the format by changing the element my text wrote to from a div to textarea. Copy/paste of tsv from textarea to a tab-delimited Excel spreadsheet keeps the data formatted in tabular format when pasted. Thanks all for the help.
Try this ,
Before pasting data set excel's text to column delimiters to space and try to paste your values again.
Old topic but I had this. Need to copy something each day from a programme which outputs to google chrome browser. Whenever it was copied and pasted into excel it was going into 1 cell. Yet if I control all and paste it was ok.
I found you can copy only the lines you want and it will behave as wanted - if you don't drag the cursor all the way down off the page. ie if you highlight down to the last piece of information in the bottom right of screen more carefully, when you past to excel it pastes it as tab separated. Whereas if you drag it right down it pastes it all in 1 cell. Might help someone in the future who has this.
You can use 'text to columns' in Excel to format the data in the way you want it to.
After pasting the data into excel, select the column with your data.
Go to Data - click 'Text to columns'
Choose delimited and hit next
Choose Tab and hit finish.
If you don't want to use this extra step, the following works for Excel 2013:
Go to Home, Paste options and click 'Use text import wizard'
Choose delimited and hit next
Choose Tab and hit finish.
Am writing data in .rtf Format from a RichTextBox using (Text is color coded )
RichTextBox .SaveFile(path);
There is a 'Clear Text' button on the GUI on click of which clears the RichTextBox .
The problem arises when new data is printed on the RichTextBox instead of appending the data the RichTextBox .SaveFile(path) method clears out the previous data and contains only the newly added data.
How can i append the data? StreamWriter is wrtitng the data in plain text i need it in .RTF.
Can anybody help me on this?
You can save the previous data in a variable, set the richTextBox's data to previous+new and then call the SaveFile method.
Seems like saving from the rich text box overwrites the file. You can have a look at this or this for more info.
Some of the solutions suggested are saving to a different file, or reading, concatenating, and saving.
There is no option to append text to RTF file as you have already read from the comments.
What you can do, however, is use 2 RichEdit controls, one that reads the stream in using EM_STREAMIN message (this will preserve the char format) and concatenate the new data to it. For the preservation of the char format of the new data from the other RichEdit control (colors,fonts etc), you have to use EM_GETCHARFORMAT message on the selection of the new data you want to concatenate. And then, you need to use EM_SETCHARFORMAT message with SCF_SELECTION OR SCF_WORD to set the char format on the RichEdit control that will hold all data together. After that, use EM_REPLACESEL message to concatenate all the data together. Finally, use EM_STREAMOUT message to save all of the stream at one go.
My word file containing list of paragraphs and images and shapes.Here, Some pictures(images) are grouped itself. And each group having one text box control with some text.The Shapes are also having the text i mentioned above.
Using Microsoft.Office.Interop.Word.Paragraphs, i can able to get the paragraph text.But Could not able to get the those text.How can i get it.
In Open Xml representation, All text are inside the <w:p>.
Please guide me to get out of this issue...
Saravanan.P
You can use of "HasText" property for this to work.
if (FileDocument.Shapes.Range(1).TextFrame.HasText != 0)
{
Fieldstring.Add(FileDocument.Shapes.Range(1).TextFrame.TextRange.Text.ToString());
}