I am trying to export a report to excel. When I export my report to Excel I am getting blank rows between each detail section. I assume this is because I have a context menu in form of a normal text element which overlies the "normal" text elements.
Does anybody have any advice on how I can stop the blank rows occurring? Is it possible to suppress a text element only when it is exported to Excel?
Thanks!
Try to make it compact.
It should be no space between each object. You should set every object on the same row has the same height and every object on column has the same width.
When there's a space between objects, it will create a cell on excel.
There are 2 articles from Ken Hamady that might be helpfull:
http://kenhamady.com/cru/archives/231
http://www.kenhamady.com/news0506.shtml (scroll to the bottom of the page)
Another option , if you are working with tabular data is to use a report extension like it is shown in this video: https://www.youtube.com/watch?v=3hk6FJ1dvb4
This approach will use the Crystal report as a datasource and will export the data from a grid with much better formatting. The video is using a 3rd party tool, but it is free - http://www.r-tag.com/Pages/CommunityEdition.aspx
Use This Code:
Public Shared Sub ExportDataSetToExcel(ByVal ds As DataTable, ByVal filename As String)
Dim response As HttpResponse = HttpContext.Current.Response
response.Clear()
response.Buffer = True
response.Charset = ""
response.ContentType = "application/vnd.ms-excel"
Using sw As New StringWriter()
Using htw As New HtmlTextWriter(sw)
Dim dg As New DataGrid()
dg.DataSource = ds
dg.DataBind()
dg.RenderControl(htw)
response.Charset = "UTF-8"
response.ContentEncoding = System.Text.Encoding.UTF8
response.BinaryWrite(System.Text.Encoding.UTF8.GetPreamble())
response.Output.Write(sw.ToString())
response.[End]()
End Using
End Using
End Sub
Finally I've solved this issue, after a long time researching. Make the fields inside the details section fill the whole height of the section... no spaces between fields and top and bottom edges.
instead of this
Related
I am currently working on a project that will import data from multiple different sources in a variety of formats and structures - e.g., CSV, fixed-length, other-delimited (tab, pipe, etc.) plain-text, and Excel worksheets/workbooks. For this, I'm attempting to build "generic" readers for these files which will throw the files' contents into a DataTable/DataSet I can use in other methods. The plain-text files are pretty simple as I've created a large SCHEMA.INI file which contains field definitions for each of the files the system will handle. That SCHEMA.INI resides in a "processing folder" where the files are temporarily stored until their data has been integrated with other systems. A defined text files' data can be easily extracted using this method:
Private Function TextFileToDataTable(ByVal TextFile As IO.FileInfo) As DataTable
Dim TextFileData As New DataTable("TextFileData")
Using TapeFileConnect As New OleDb.OleDbConnection("Provider=Microsoft.Jet.OleDb.4.0;Data Source='" + TextFile.DirectoryName + "';Extended Properties='Text';")
Using TapeAdapter As New OleDb.OleDbDataAdapter(String.Format("SELECT * FROM {0};", TextFile.Name), TapeFileConnect)
Try
TapeAdapter.Fill(TextFileData)
Catch ex As Exception
TextFileData = Nothing
End Try
End Using
End Using
Return TextFileData
End Function
This works well because a plain-text file isn't terribly complex in its data structure. A single file generally (at least for my requirements) contains, at most, one single table's worth of data - unless, of course, it's some sort of complex XML or JSON structure file, which can/should be handled completely differently anyway - so there's no need to go iterating through different elements beyond this.
NOTE: The code above is dependent on the SCHEMA.INI file being present in the same directory as the plain-text file being read and there being a section within that SCHEMA.INI defined with the same name as that plain-text file.
EXAMPLE:
[EXAMPLE_TEXT_FILE.TXT]
CharacterSet=ANSI
Format=FixedLength
ColNameHeader=FALSE
DateTimeFormat="YYYYMMDD"
COL1=CUSTOMER_NUMBER TEXT WIDTH 20
COL2=CUSTOMER_FIRSTNAME TEXT WIDTH 30
COL3=CUSTOMER_LASTNAME TEXT WIDTH 40
COL4=CUSTOMER_ADDR1 TEXT WIDTH 40
COL5=CUSTOMER_ADDR2 TEXT WIDTH 40
COL6=CUSTOMER_ADDR3 TEXT WIDTH 40
...
Excel workbooks, however, can be a bit trickier. Several of the workbooks I have to process contain multiple worksheets worth of data that I want to consolidate into a single DataSet with a DataTable for each worksheet. The basic functionality is, again, fairly straightforward and I've come up with the following method to read any and all sheets into a DataSet:
Private Function ExcelFileToDataSet(ByVal ExcelFile As IO.FileInfo, ByVal HasHeaderRow As Boolean) As DataSet
Dim ExcelFileData As New DataSet("ExcelFileData")
Dim ExcelConnectionString As String = String.Empty
Dim UseHeaders As String = "NO"
Select Case ExcelFile.Extension.ToUpper.Trim
Case ".XLS"
ExcelConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1}'"
Case ".XLSX"
ExcelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1}'"
End Select
If HasHeaderRow Then
UseHeaders = "YES"
End If
ExcelConnectionString = String.Format(ExcelConnectionString, ExcelFile.FullName, UseHeaders)
Try
Using ExcelConnection As New OleDb.OleDbConnection(ExcelConnectionString)
Dim ExcelSchema As New DataTable
ExcelConnection.Open()
ExcelSchema = ExcelConnection.GetOleDbSchemaTable(OleDb.OleDbSchemaGuid.Tables, Nothing)
For Each ExcelSheet As DataRow In ExcelSchema.Rows
Dim SheetTable As New DataTable
Using ExcelAdapter As New OleDb.OleDbDataAdapter
Dim SheetName As String = ExcelSheet("TABLE_NAME").ToString
Dim ExcelCommand As New OleDb.OleDbCommand
SheetTable.TableName = SheetName.Substring(0, SheetName.Length - 1)
ExcelCommand.Connection = ExcelConnection
ExcelCommand.CommandText = String.Format("SELECT * FROM [{0}]", SheetName)
ExcelAdapter.SelectCommand = ExcelCommand
ExcelAdapter.Fill(SheetTable)
End Using
ExcelFileData.Tables.Add(SheetTable)
Next ExcelSheet
End Using
Catch ex As Exception
ExcelFileData = Nothing
End Try
Return ExcelFileData
End Function
The above code will work in a majority of the cases I deal with, but my "difficulty" is that there may be some worksheets that have header rows and some that don't within the same workbook. Also, for those worksheets that do not have a header row, I'd like to be able to define the field names and data types similar to how I can with the plain-text SCHEMA.INI. The only thing I have going for me in these cases is that the "client" provides me with a data map to help me identify what data elements are in each field.
What I'd like to know is if there is a way similar to the text file's SCHEMA.INI to define the structure of an Excel workbook and the worksheet(s) it contains - including column data types to avoid the OleDb driver from "misinterpreting" a column's data - ahead of time. I imagine this could be any sort of structured file such as INI, XML, or whatever, but it would need to be capable of identifying whether or not a particular sheet contains a header row or, in lieu of such a row, the (expected) column definitions. Does any such "standard definition" file exist for Excel workbooks?
One thing to note: As you may have noticed in the code for the ExcelFileToDataSet() method, I may be dealing with the older .XLS (97-03) format or the .XLSX (07+) format, so I can't necessarily rely on the workbook being Open XML compliant. I suppose I could try breaking the methods out to one for each extension, but I'd rather find something that I can use regardless of which file format the Excel file is using.
I'm heaving problems with a specific task on Lotus Notes. I have to copy a rich text field edit it and paste inside another rich text field. But when I edit the content the text style disappears. I've tried to use this solution:
http://www.bobzblog.com/tuxedoguy.nsf/dx/geek-o-terica-15-easy-conversion-of-notes-documents-to-mime-format-part-1
to copy the html and then edit the content. But I got another problem with this:
java.lang.ClassCastException: lotus.domino.local.Item incompatible with lotus.domino.RichTextItem
Can anyone help me with my task?
Thank you.
You don't specify how you want to edit the richtext data. But if you by "edit" mean "programatically make changes to", you can do that in regular Lotusscript using the NotesRichTextItem class.
I wrote a mail-merge class a while back, and it is replacing content in a rich text field with other values, keeping the formatting. If you look at the code you can probably figure it out.
http://blog.texasswede.com/code-mail-mergeform-letters-in-lotuscript/
The relevant code is here:
Public Function MergedRichText() As NotesRichTextItem
Dim range As NotesRichTextRange
Dim cnt As Integer
Set tempbody = sourcefield
Set range = tempbody.CreateRange
Forall p In placeholder
Call p.ProcessPlaceHolder(sourcedoc, maindoc)
If p.text = "" Then
p.text = " -- "
End If
cnt = range.FindAndReplace(p.placeholderstring, p.text, 1+4+8+16)
End Forall
Call tempbody.Compact
Call tempbody.Update
Set targetfield = tempbody
Set MergedRichText = tempbody
End Function
I have a spreadsheet that has a number of check boxes in various cells on the sheet that I need to get the value of (checked/unchecked) from within a c# program.
I'm using the OpenXML SDK v2.5 and the associated toolbox.
Using the toolbox I can see the check box controls as part of the AlternateControlParts collection. These are not ActiveX checkboxes but are form controls added via the developer tab in Excel.
When I use the SDK I can also see the WorkSheetPart which has a ControlPropertiesParts collection on it which lists all the checkboxes.
My problem is, how do I find which checkbox is in which cell or at least related to which cell?
I have also found the collection
wsPart.ControlPropertiesParts.First().DrawingsPart
.WorkSheetDrawing.DrawingsPart.WorkSheetDrawing
This collection appears to have the alternate content of each of the checkboxes and if I drill down further I can find the anchor points which appear to give the location of the checkboxes relative to the cells on the sheet. However, the col and row Id’s don’t appear to exactly match up and I suspect that the Offset values may also have something to do with it.
If someone can point me in the right direction on how to map the checkboxes to the correct row/cells I would be very grateful.
Thank you for any help.
Regards
Paul
I have a solution, it contains only the logic (The property FormControlProperties is available since Office 2010:
SpreadsheetDocument document;
string sheetName = "sheetName";
string controlName = "Option Button 5";
...
var wbPart = document.WorkbookPart;
var theSheet = wbPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName);
var wsPart = (WorksheetPart)wbPart.GetPartById(theSheet.Id);
var control = wsPart.Worksheet.Descendants<DocumentFormat.OpenXml.Spreadsheet.Control>().FirstOrDefault(c => c.Name == controlName);
var controlProperies = (ControlPropertiesPart)wsPart.GetPartById(control.Id);
bool isChecked = controlProperies.FormControlProperties.Checked == "Checked";
But it is simplier to map the FormControl value to a cell and read the cell value if the you can edit the excel file.
While I'm trying to open excel file a message box is prompting like "We found a problem with some content in file name. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes.". What actually done is i have a excel template designed and copying the file to another file and created temp file I'm inserting data to temp file using OPEN XML and data is getting from the database.
i have tried the solutions provided in the net but those fixes are not resolving my issue.My excel is 2010
Anyone solution provided is much appreciated.
I had this problem. It was caused by the way I was storing numbers and strings in cells.
Numbers can be stored simply using cell.CellValue = new CellValue("5"), but for non-numeric text, you need to insert the string in the SharedStringTable element and get the index of that string. Then change the data type of the cell to SharedString, and set the value of the cell to the index of the string in the SharedStringTable.
// Here is the text I want to add.
string text = "Non-numeric text.";
// Find the SharedStringTable element and append my text to it.
var sharedStringTable = document.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First().SharedStringTable;
var item = sharedStringTable.AppendChild(new SharedStringItem(new Text(text)));
// Set the data type of the cell to SharedString.
cell.DataType = new EnumValue<CellValues>(CellValues.SharedString);
// Set the value of the cell to the index of the SharedStringItem.
cell.CellValue = new CellValue(item.ElementsBefore().Count().ToString());
This is explained in the documentation here: http://msdn.microsoft.com/en-us/library/office/cc861607.aspx
Another few cases that can cause this type of error:
Your sheet name is longer than 31 characters
You have invalid characters in sheet name
You have cells with values longer than 32k
The issue is due to using
package.Save();
and
package.GetAsByteArray();
at the same time
when we call
package.GetAsByteArray();
it will do following operations
this.Workbook.Save();
this._package.Close();
this._package.Save(this._stream);
Hence, removing
package.Save();
will solve this problem "We found a problem with some content in file name. Do you want us to try to recover as much as we can? If you trust the source of this workbook, click Yes."
Another possible cause could be exceeded maximum number of cell styles.
You can define:
up to 4000 styles in a .xls workbook
up to 64000 styles in a .xlsx workbook
In this case you should re-use the same cell style for multiple cells, instead of creating a new cell style for every cell.
I added the right cellReference and fixed this issue for me:
string alpha = "ABCDEFGHIJKLMNOPQRSTUVQXYZ";
for (int colInx = 0; colInx < reader.FieldCount; colInx++)
{
AppendTextCell(alpha[colInx] + "1", reader.GetName(colInx), headerRow);
}
private static void AppendTextCell(string cellReference, string cellStringValue, Row excelRow)
{
// Add a new Excel Cell to our Row
Cell cell = new Cell() { CellReference = cellReference, DataType = new EnumValue<CellValues>(CellValues.String) };
CellValue cellValue = new CellValue();
cellValue.Text = cellStringValue.ToString();
cell.Append(cellValue);
excelRow.Append(cell);
}
Same warning but the problem with me was that I was using a client input (name of wave) as sheet name for the file and when date was presented within the name, the character '/' used as date part separator was causing the issue.
I think Microsoft need to provide a better error log to save people time investigate such minor issues. Hope my answer will save someone else's time.
The issue was due to storing a string in the cell directly using cell.CellValue = new CellValue("Text"). It is possible to store numbers like this but not string. For string, define data type as string before assigning the text using Cell.DataType = CellValues.String;
I have used automation to insert values into a cell, however I have never seen any documentation, for example, that demonstrate inserting anything other than text and/or formula's.
Has anybody been able to insert an image from an external application?
Dim FileName as string
FileName="c:\text.jpg"
Set NewPic = ActiveSheet.Pictures.Insert(FileName)
NewPic.top=100
NewPic.left=100
If you want to position the picture to a specific cell then select that cell as a range and use that ranges top/left/with to position the picture.
Samples: http://exceltip.com/st/Insert_pictures_using_VBA_in_Microsoft_Excel/486.html
Note: In Excel cells cannot contain pictures. The pictures live on an invisible drawing layer that floats about the cells. They can be positioned based on the cell coordinates, which makes it feel like they are living "in" the cells.
I see it's already been answered, but see my post here.
Basically rather than use the Worksheet.Pictures.Insert method (which the MSDN recommends you don't use directly, and which returns a raw COM object), try the Worksheet.Shapes.AddPicture method instead.
Dim range As Microsoft.Office.Interop.Excel.Range
Dim pic as Microsoft.Office.Interop.Excel.Shape
Dim filePath as String
range = ...
filePath = ...
pic = range.Worksheet.Shapes.AddPicture(filePath, Microsoft.Office.Core.MsoTriState.msoFalse, Microsoft.Office.Core.MsoTriState.msoCTrue, range.Left, range.Top, 300, 300)
It's not quite as straightforward because you have to specify the exact position and dimensions, but otherwise, pretty cool!
Sure, the following code gives a good example using the Microsoft Interop libraries:
string excelfilename = #"C:\excelfile.xlsx";
string picturename = #"C:\image.jpg";
object missing = Type.Missing;
Microsoft.Office.Interop.Excel.Application app = new ApplicationClass();
Workbook book = app.Workbooks.Add(missing);
Worksheet sheet = (Worksheet)book.ActiveSheet;
Pictures pics = (Pictures)sheet.Pictures(missing);
pics.Insert(picturename, missing);
book.SaveAs(excelfilename, missing, missing, missing, missing, missing, XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);
app.Quit();
app = null;