Getting WorkbookPart from row - openxml

I am writing and extension for OpenXML like shown in the sample. I would like to avoid having to pass the WorkbookPart as parameter. Is there any way to get the WorkbookPart directly from the row?
public static string GetCellTextValue(this Row row, WorkbookPart workbookPart, string column)
{
var cells = row.Elements<Cell>();
var cell = cells.Where(p => p.CellReference == column + row.RowIndex.ToString()).FirstOrDefault();
if (cell.DataType != null)
{
if (cell.DataType == CellValues.SharedString)
{
int id = -1;
if (Int32.TryParse(cell.InnerText, out id))
{
SharedStringItem item = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(id);
if (item.Text != null)
{
return item.Text.Text;
}
else if (item.InnerText != null)
{
return item.InnerText;
}
else if (item.InnerXml != null)
{
return item.InnerXml;
}
}
}
}
return string.Empty;
}

Unfortunately, none of the strongly-typed classes of the Open XML SDK (e.g., Workbook, Worksheet, Row) have properties pointing back to the OpenXmlPart (e.g., WorkbookPart, WorksheetPart) in which they are contained or any other part related to their immediate container. Unless you amend your API in other ways, you will have to pass that WorkbookPart.

Related

How to get list from docx file?

How to determine whether a list is bulleted or numbered? I use OpenXML
In general, what will be the list determines NumberingDefinitionsPart, I thought to find out the Numbering of a certain element, but this method did not work
I am processing the list in the recommended way, but I need to know which way it is
`public void ParagraphHandle(Elements.Paragraph paragraph, StringBuilder text)
{
var docPart = paragraph.DocumentPart;
var element = paragraph.Element;
var r = element.Descendants<Numbering>().ToArray();
var images = GetImages(docPart, element);
if (images.Count > 0)
{
foreach (var image in images)
{
if (image.Id != null)
{
string filePath = _saveResources.SaveImage(image);
_handler.ImageHandle(filePath, text);
}
}
return;
}
var paragraphProperties = element.GetFirstChild<ParagraphProperties>();
var numberingProperties = paragraphProperties?.GetFirstChild<NumberingProperties>();
if (numberingProperties != null)
{
var numberingId = numberingProperties.GetFirstChild<NumberingId>()?.Val?.Value;
if (numberingId != null && !paragraph.IsList)
{
text.AppendLine("<ul>");
paragraph.IsList = true;
paragraph.List = new List();
_htmlGenerator.GenerateList(paragraph, text);
}
else
{
_htmlGenerator.GenerateList(paragraph, text);
}
}
else
{
if (paragraph.IsList)
{
text.AppendLine("</ul>");
paragraph.IsList = false;
}
_handler.ParagraphHandle(element, text);
}
}`

telerik mvc Create CompositeFilterDescriptor and append it to existing datasource request filter

I am having some issues creating a CompositeFilterDescriptor from scratch.
The scenario: We have date filters on the grid, but are showing date time fields.
When Someone filters to a specific date, we show all records for that day.
when someone filters greater than that day, we edit the filterDescriptor for that filter and add one day to it.
when someone filters to less than or equal to that day, we edit the filterdescriptor for that filter and add one day to it.
Here is the problem: when someone selects "not equal to", the solution would be to create a compositeFilterDescriptor containing two filters. One for less than that day, one for greater than that day.
I may ore may not be doing this part properly. I can not figure out how to add the new compositeFilterDescriptor to the existing dataSourceRequest.
Here is what I have:
static public DataSourceRequest FixDateFilters(DataSourceRequest request, string[] optionalFields = null)
{
if (request?.Filters != null)
{
List<string> matchingFields = new List<string> { "utc", "time" };
List<FilterDescriptor> newDescriptors = new List<FilterDescriptor>();
//if any fields specific to a page have been passed in, append them to the list.
if (optionalFields != null)
{
foreach (string field in optionalFields)
matchingFields.Append(field);
}
foreach (string matchingField in matchingFields)
{
List<FilterDescriptor> descriptors = new List<FilterDescriptor>();
FilterDescriptor descriptor1 = FindFirstFilterByMember(request.Filters, matchingField, true, null);
//there could be up to two filters on a matching field. Get the 2nd one if it exists.
FilterDescriptor descriptor2 = FindFirstFilterByMember(request.Filters, matchingField, true, descriptor1);
//turn the matches into a list for iterating
if (descriptor1 != null)
descriptors.Add(descriptor1);
if (descriptor2 != null)
descriptors.Add(descriptor2);
if (descriptors.Count != 0)
{
foreach (FilterDescriptor descriptor in descriptors)
{
DateTime? utcDate = (DateTime?)descriptor?.Value;
if (utcDate.HasValue)
{
utcDate = Core.DateHelper.ToUTC(utcDate.Value, HttpContext.Current); //make sure date ranges are one day ranges in local time
}
if (utcDate != null)
{
if (descriptor.Operator == FilterOperator.IsLessThanOrEqualTo)
{
utcDate = ((DateTime)utcDate).AddDays(1);
descriptor.Value = utcDate;
}
else if (descriptor.Operator == FilterOperator.IsGreaterThan)
{
utcDate = utcDate.Value.AddDays(1);
descriptor.Value = utcDate;
}
else if (descriptor.Operator == FilterOperator.IsEqualTo)
{
descriptor.Operator = FilterOperator.IsGreaterThanOrEqualTo;
newDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsLessThan, utcDate.Value.AddDays(1)));
}
else if (descriptor.Operator == FilterOperator.IsNotEqualTo)
{
CompositeFilterDescriptor cfd = new CompositeFilterDescriptor();
cfd.LogicalOperator = FilterCompositionLogicalOperator.Or;
cfd.FilterDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsLessThan, utcDate.Value;));
cfd.FilterDescriptors.Add(new FilterDescriptor(descriptor.Member, FilterOperator.IsGreaterThan, utcDate.Value.AddDays(1)));
newDescriptors.Add( cfd);
}
}
}
}
}
//equals matches add a new descriptor so add them after the foreach is done so they don't affect the foreach.
foreach (FilterDescriptor newDescriptor in newDescriptors)
{
if (newDescriptor.Member != "") //a blank descriptor has a emptry string for member
{
request.Filters.Add(newDescriptor);
}
}
}
return request;
}
}
static public FilterDescriptor FindFirstFilterByMember(IEnumerable<IFilterDescriptor> filters, string findMember, bool partialMatch = false, FilterDescriptor previous = null)
{
FilterDescriptor ret = null;
foreach (var filter in filters)
{
var descriptor = filter as FilterDescriptor;
if (descriptor != null
&& (descriptor.Member == findMember || (partialMatch == true && descriptor.Member.ToLower().Contains(findMember.ToLower())))
&& (previous == null || previous != descriptor))
{
ret = descriptor;
break;
}
else if (filter is CompositeFilterDescriptor)
{
ret = FindFirstFilterByMember(((CompositeFilterDescriptor)filter).FilterDescriptors, findMember, partialMatch, previous);
if (ret != null)
break;
}
}
return ret;
}
The second function is a recursive one for getting the filters by string.
The problem section is the "isNotEqualTo" comparison. I don't know how to save the composite filter into the existing request. It gives me a casting error.
Ok it turns out all i needed to do was create a new list of CompositeFilterDescriptor type and append that when necessary. The .add function took both. Sigh.
foreach (CompositeFilterDescriptor newCompositeDescriptor in newCompositeDescriptors)
{
request.Filters.Add(newCompositeDescriptor);
}

how can I write generic queries in entity framework?

I have 3 methods these are same methods only some parameters will be change I want to write one method how can i write
public string method1(int id)
{
var getAllStudents = rep.Students.Where(e => e.StudentId == id).ToList();
foreach (var item in getAllStudents)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
public string method2(int id)
{
var getAllTeachers = rep.Teachers.Where(e => e.TeacherId == id).ToList();
foreach (var item in getAllTeachers)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
public string method3(int id)
{
var getAllClasses = rep.Classes.Where(e => e.ClassId == id).ToList();
foreach (var item in getAllClasses)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
I think there is very easy way to write 1 method. the think is where parameter has different id..
Thanks.
Avoid conditional logic based on arguments. This leads to fragile code because every parameter combination has to be tested to be considered reliable. This leads to complex code that is easily prone to bugs. Having simpler single-purpose methods are typically much more reliable and easier to understand and maintain.
For instance given your example and assuming that "rep" was your instance's DbContext...
public bool IsActiveStudent(int id)
{
bool result = rep.Students.Any(x => x.StudentId == id && x.IsActive);
return result;
}
public bool IsActiveTeacher(int id)
{
bool result = rep.Teachers.Any(x => x.TeacherId == id && x.IsActive);
return result;
}
public bool IsActiveClass(int id)
{
bool result = rep.Classes.Any(x => x.ClassId == id && x.IsActive);
return result;
}
These can be essentially one-liners by simply returning the .Any() result. I tend to favour selecting the result into a variable first and returning it on a separate line since it makes it easier to breakpoint and inspect.
If you need to return a string for "Ok" vs. "Error" then:
return result ? "OK" : "Error";
Methods should strive to do one thing, and do it well. Easy to understand and troubleshoot if need be. Adding parameters and conditional code inside the method merely makes the code more volatile and leaves openings for bugs. In the end it doesn't make the code much shorter when the initial method could be simplified.
You can not overload methods if they signatures are the same.
You have two methods with the same signature:
public string checkexist(int id)
What you can do is to rename your methods, like this:
public interface WriteSomethingHere {
public boolean isStudentExist(int id);
public boolean isTeacherExist(int id);
public boolean isClassExist(int id);
}
I just found answer using generic repo
public T GetEntity<T>(int Id)
where T : class
{
using (MyEntities rpContext = new MyEntities())
{
return rpContext.Set<T>().Find(e => e.Id == Id);
}
}
after calling
var entityStudent = GetEntity<Student>(1);
var entityTeacher = GetEntity<Teacher>(1);
var entityClasses = GetEntity<Classes>(1);
You have Create Enumeration
Public Enum ParameterStaus:short
{
Student=1,
Teacher=2,
Classess=3
}
public string method2(int id.ParameterStatus status)
{
if(status==ParameterStatus.Teacher)
{
var getAllTeachers = rep.Teachers.Where(e => e.TeacherId == id).ToList();
foreach (var item in getAllTeachers )
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
}
Else if(status==ParameterStatus.Student)
{
var getAllStudents = rep.Students.Where(e => e.StudentId == id).ToList();
foreach (var item in getAllStudents)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
Else
{
var getAllClasses = rep.Classes.Where(e => e.ClassId == id).ToList();
foreach (var item in getAllClasses)
{
if (item.isActive != true)
return "Error";
}
return "OK";
}
}

Pagination not working for a Lazy Loaded Data Table on First Loading

I am using JPA named queries for Loading a Lazy Loaded DataTable. and setting first and Max results as shown below.
Query query = entityManager.createNamedQuery("StudyplanCategory.findByStatusAndLimit");
int end=(start*pageNumber);
query.setParameter("status", status);
query.setParameter("start", start);
query.setParameter("end", end);
query.setMaxResults(end - start);
The load method is given below:
public List<StudyplanCategory> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
List<StudyplanCategory> data = new ArrayList<StudyplanCategory>();
//System.out.println("Page First Value:"+first+"PageSize Value:"+pageSize);
datasource=categoryService.findDynaEditStudyPlan("NOT_USER_SPECIFIC",first,pageSize);
//filter
for(StudyplanCategory studyplanCategory : datasource) {
boolean match = true;
for(Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
String filterValue = filters.get(filterProperty).toLowerCase();
String fieldValue = String.valueOf(studyplanCategory.getClass().getDeclaredField(filterProperty).get(studyplanCategory)).toLowerCase();
//System.out.println("fieldValue............."+fieldValue);
if(filterValue == null || fieldValue.startsWith(filterValue)) {
match = true;
}
else {
match = false;
break;
}
} catch(Exception e) {
match = false;
System.out.println("The Exception occured at"+e);
}
}
if(match) {
data.add(studyplanCategory);
}
}
//sort
if(sortField != null) {
Collections.sort(data, new LazySorter(sortField, sortOrder));
}
//rowCount
int dataSize = data.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
}
else {
return data;
}
}
But when the table is loaded Next Buttons are not active because I am loading only those data required to load the first page. How can I Solve this.
You need to fire another query which sets the total rowcount. Basically, in LazyDataModel#load():
public List<StudyplanCategory> load(...) {
setRowCount(studyplanCategoryService.count());
return studyplanCategoryService.list(...);
}
Unrelated to the concrete problem, you should actually be using Query#setFirstResult() to set the first record index.

How to calculate the color based on given fgColor indexed

I am working on Open XML,
<x:fill>
<x:patternFill patternType="solid">
<x:fgColor indexed="46" />
<x:bgColor indexed="64" />
</x:patternFill>
</x:fill>
Above is a office 2007 document that converted from office 2003.
According to http://msdn.microsoft.com/en-us/library/documentformat.openxml.spreadsheet.foregroundcolor.aspx
Indexed attributes only used for backward compatibility purposes.
Above is my code, how to calculate the #Hex Color Code for indexed = 46?
I made this class for myself. Hope I save someone some trouble
public class IndexedColours
{
static Dictionary<string, string> Data;
IndexedColours()
{
if(Data == null || Data.Count == 0)
{
Data = new Dictionary<string, string>();
Data.Add("0", "000000");
Data.Add("1", "FFFFFF");
Data.Add("2", "FF0000");
Data.Add("3", "00FF00");
Data.Add("4", "0000FF");
Data.Add("5", "FFFF00");
Data.Add("6", "FF00FF");
Data.Add("7", "00FFFF");
Data.Add("8", "000000");
Data.Add("9", "FFFFFF");
Data.Add("10", "FF0000");
Data.Add("11", "00FF00");
Data.Add("12", "0000FF");
Data.Add("13", "FFFF00");
Data.Add("14", "FF00FF");
Data.Add("15", "00FFFF");
Data.Add("16", "800000");
Data.Add("17", "008000");
Data.Add("18", "000080");
Data.Add("19", "808000");
Data.Add("20", "800080");
Data.Add("21", "008080");
Data.Add("22", "C0C0C0");
Data.Add("23", "808080");
Data.Add("24", "9999FF");
Data.Add("25", "993366");
Data.Add("26", "FFFFCC");
Data.Add("27", "CCFFFF");
Data.Add("28", "660066");
Data.Add("29", "FF8080");
Data.Add("30", "0066CC");
Data.Add("31", "CCCCFF");
Data.Add("32", "000080");
Data.Add("33", "FF00FF");
Data.Add("34", "FFFF00");
Data.Add("35", "00FFFF");
Data.Add("36", "800080");
Data.Add("37", "800000");
Data.Add("38", "008080");
Data.Add("39", "0000FF");
Data.Add("40", "00CCFF");
Data.Add("41", "CCFFFF");
Data.Add("42", "CCFFCC");
Data.Add("43", "FFFF99");
Data.Add("44", "99CCFF");
Data.Add("45", "FF99CC");
Data.Add("46", "CC99FF");
Data.Add("47", "FFCC99");
Data.Add("48", "3366FF");
Data.Add("49", "33CCCC");
Data.Add("50", "99CC00");
Data.Add("51", "FFCC00");
Data.Add("52", "FF9900");
Data.Add("53", "FF6600");
Data.Add("54", "666699");
Data.Add("55", "969696");
Data.Add("56", "003366");
Data.Add("57", "339966");
Data.Add("58", "003300");
Data.Add("59", "333300");
Data.Add("60", "993300");
Data.Add("61", "993366");
Data.Add("62", "333399");
Data.Add("63", "333333");
}
}
public static string GetIndexColour(string Index)
{
var d = new IndexedColours();
var res = "";
var exist = Data.TryGetValue(Index, out res);
if (exist)
return res;
else return "000000";
}
}
Method to use the above code:
public static string GetCellColour(this Cell cell, SpreadsheetDocument d)
{
if (cell != null && cell.StyleIndex != null)
{
var valcell = cell;
var styles = d.WorkbookPart.WorkbookStylesPart;
var ss = styles.Stylesheet;
var formats = ss.CellFormats;
var cf = (CellFormat)formats.ElementAt((int)valcell.StyleIndex.Value);
var fill = (Fill)styles.Stylesheet.Fills.ChildElements[(int)cf.FillId.Value];
var fgc = fill.PatternFill.ForegroundColor;
var cl = fgc == null || fgc.Rgb == null ? "FFFFFF" : fgc.Rgb.Value.Remove(0, 2);
if (fgc != null && fgc.Indexed != null && fgc.Indexed.HasValue)
{
cl = IndexedColours.GetIndexColour(fgc.Indexed.Value.ToString());
}
return cl;
}
else return "FFFFFF";
}
Solved my problem, there is color indexes online. just search for it.