We are merging a Word template document that contains merge fields using Gembox Document. We noticed when some of the field values contain special characters \t or \n, an exception occurs...
An error occured - Text cannot contain new line (' '), carriage return
(' ') or tab (' ') characters. If you want to break the text or insert
a tab, insert SpecialCharacter instance with specific
SpecialCharacterType to the parent's InlineCollection.
We found this post which describes a solution to the issue, but we are not seeing how to apply that to our scenario.
This is our code which throws the exception...
public static void Merge(DocumentModel word, PricingSummaryModel model)
{
word.MailMerge.FieldMerging += (sender, e) =>
{
if (e.FieldName.Contains("CustomField."))
{
var trove = FindCustomFieldValueTrove(e.FieldName, model);
var value = ProcessCustomField(e.FieldName, e.Field.GetInstructionText(), trove);
e.Inline = new Run(e.Document, value) { CharacterFormat = e.Field.CharacterFormat.Clone() };
e.Cancel = false;
}
};
word.MailMerge.Execute(model);
}
We can fix the problem by removing any special characters first...
But then we lose the special characters of course. For our scenario, how can this be done? We aren't "constructing" a document as referenced in the aforementioned post. Rather we are starting with a Word template and essentially mail merging field values for the fields.
You'll need to handle those special characters and add the appropriate element(s) to the e.Inlines collection.
For example, try this:
var value = ProcessCustomField(e.FieldName, e.Field.GetInstructionText(), trove);
int startIndex = 0, currentIndex = 0, length = value.Length;
for (; currentIndex < length; currentIndex++)
{
char c = value[currentIndex];
if (c == '\t' || c == '\n')
{
e.Inlines.Add(
new Run(e.Document, value.Substring(startIndex, currentIndex - startIndex))
{ CharacterFormat = e.Field.CharacterFormat.Clone() });
e.Inlines.Add(
new SpecialCharacter(e.Document, c == '\t' ? SpecialCharacterType.Tab : SpecialCharacterType.LineBreak)
{ CharacterFormat = e.Field.CharacterFormat.Clone() });
startIndex = currentIndex + 1;
}
else if (currentIndex == length - 1)
e.Inlines.Add(
new Run(e.Document, value.Substring(startIndex, currentIndex - startIndex + 1))
{ CharacterFormat = e.Field.CharacterFormat.Clone() });
}
e.Cancel = false;
Related
This question already has answers here:
how to read all cell value using Apache POI?
(2 answers)
Closed 7 years ago.
I had created my script to validate my actual result and expected result , .
As there is too many link to validated script will get too much of coding m so i need to convert this into Data Driven Case ,.
Where Webdriver will get URL , xpath ,expected value from excel .
But dont know how to proceed , .
A demo code is much appreciated
Here is my current script :
public void test() throws Exception
{
String home_logo_url="158321";
String enough_talk_promo="1057406";
System.out.println("Check for home_logo_url");
driver.get(baseUrl);
String SiteWindow = driver.getWindowHandle(); // get the current window handle
driver.findElement(By.xpath("//*[#id='logo']/a")).click();
for (String PromoWindow : driver.getWindowHandles())
{
driver.switchTo().window(PromoWindow); // switch focus of WebDriver to the next found window handle (that's your newly opened window)
}
String script = "return rlSerial;";
String value = (String) ((JavascriptExecutor)driver).executeScript(script);
Assert.assertEquals(value,home_logo_url);
driver.close();
driver.switchTo().window(SiteWindow);
System.out.println("Pass");
System.out.println("Check for enough_talk_promo");
driver.get(baseUrl + "/category/tournaments/");
driver.findElement(By.xpath("//*[#id='content']/div/div[4]/aside/div/div/p[1]/a")).click();
for (String PromoWindow : driver.getWindowHandles())
{
driver.switchTo().window(PromoWindow); // switch focus of WebDriver to the next found window handle (that's your newly opened window)
}
String sr_enough_talk_promo = (String) ((JavascriptExecutor)driver).executeScript(script);
Assert.assertEquals(sr_enough_talk_promo,enough_talk_promo);
driver.close();
driver.switchTo().window(SiteWindow);
System.out.println("Pass");
}
How to iterated to each rows and get my test case run !!!
It is much helpful , if some one can convert my existing code to work on excel sheet .
Thanks
i was working on a project in Spring that read from an excel (.xls) and this was my code if can help
private List<String> extraire (String fileName) throws IOException {
List<String> liste = new ArrayList();
FileInputStream fis = new FileInputStream(new File(fileName));
HSSFWorkbook workbook = new HSSFWorkbook(fis);
HSSFSheet spreadsheet = workbook.getSheetAt(0);
Iterator < Row > rowIterator = null;
rowIterator = spreadsheet.iterator();
while (rowIterator.hasNext()) {
int i = 0;
row = (HSSFRow) rowIterator.next();
Iterator < Cell > cellIterator = row.cellIterator();
while ( cellIterator.hasNext()) {
Cell cell = cellIterator.next();
i++;
/**
* For verifying if a line is empty
*/
if (i % 29 == 0 || i == 1) {
while ( cellIterator.hasNext() && cell.getCellType() == Cell.CELL_TYPE_BLANK) {
cell = cellIterator.next();
}
}
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
String cellule = String.valueOf(cell.getNumericCellValue());
liste.add(cellule);
break;
case Cell.CELL_TYPE_STRING:
liste.add(cell.getStringCellValue());
break;
case Cell.CELL_TYPE_BLANK:
cellule = " ";
liste.add(cellule);
break;
}
}
}
fis.close();
return liste;
}
in my controller :
List<String> liste = new ArrayList();
liste = extraire(modelnom);
for (int m=0, i=29;i<liste.size();i=i+29) {
if(i % 29 == 0) {
// i=i+29 : begin from the second line first coll
// m is line
m++;
}
String matricule = (String)liste.get(29*m).toString().trim();
float mat = Float.parseFloat(matricul); // From String to float
employe.setMatricule((int)mat); //reading mat as an int
// ... your Code
}
I am parsing big text files and it's working fine for some time but after few minutes it give me exception (An unhandled exception of type 'System.UnauthorizedAccessException' occurred in System.Core.dll
Additional information: Access to the path is denied.)
I get exception on below mention line.
accessor = MemoryMapped.CreateViewAccessor(offset, length, MemoryMappedFileAccess.Read);
Below is my function
public static void CityStateZipAndZip4(string FilePath,long offset,long length,string spName)
{
try
{
long indexBreak = offset;
string fileName = Path.GetFileName(FilePath);
if (fileName.Contains(".txt"))
fileName = fileName.Replace(".txt", "");
System.IO.FileStream file = new System.IO.FileStream(#FilePath, FileMode.Open,FileAccess.Read, FileShare.Read );
Int64 b = file.Length;
MemoryMappedFile MemoryMapped = MemoryMappedFile.CreateFromFile(file, fileName, b, MemoryMappedFileAccess.Read, null, HandleInheritability.Inheritable, false);
using (MemoryMapped)
{
//long offset = 182; // 256 megabytes
//long length = 364; // 512 megabytes
MemoryMappedViewAccessor accessor = MemoryMapped.CreateViewAccessor(offset, length, MemoryMappedFileAccess.Read);
byte byteValue;
int index = 0;
int count = 0;
StringBuilder message = new StringBuilder();
do
{
if (indexBreak == index)
{
count = count + 1;
accessor.Dispose();
string NewRecord = message.ToString();
offset = offset + indexBreak;
length = length + indexBreak;
if (NewRecord.IndexOf("'") != -1)
{ NewRecord = NewRecord.Replace("'", "''"); }
// string Sql = "insert into " + DBTableName + " (ID, DataString) values( " + count + ",'" + NewRecord + "')";
string Code = "";
if (spName == AppConfig.sp_CityStateZip)
{
Code = NewRecord.Trim().Substring(0, 1);
}
InsertUpdateAndDeleteDB(spName, NewRecord.Trim (), Code);
accessor = MemoryMapped.CreateViewAccessor(offset, length, MemoryMappedFileAccess.Read);
message = new StringBuilder();
index = 0;
//break;
}
byteValue = accessor.ReadByte(index);
if (byteValue != 0)
{
char asciiChar = (char)byteValue;
message.Append(asciiChar);
}
index++;
} while (byteValue != 0);
}
MemoryMapped.Dispose();
}
catch (FileNotFoundException)
{
Console.WriteLine("Memory-mapped file does not exist. Run Process A first.");
}
}
Somewhere deep in resource processing code we have something like this:
try {
// Try loading some strings here.
} catch {
// Oops, could not load strings, try another way.
}
Exception is thrown and handled already, it would never show up in your application. The only way to see it is to attach debugger and observe this message.
As you could see from the code, it has nothing to do with your problem. The real problem here is what debugger shows you something you should not see.
Run the solution without debugging mode and it works fine.
This exception means that your program does not get Read access to the file from Windows.
Have you made sure that this file is not locked when your program tries to read it ?
For example, it could be a file that your own program is currently using.
If not, try to run your program as an Administrator and see if it makes a difference.
I've been trying to create a drag and drop style app and have run into a snag. I have a group of movieclips that will be dragged in an array. When I drag them I want them to either,
A) Snap back to original position if there isn't a target when dropped (Working)
B) Snap to target if there is one detected (Not Working)
And if possible this would be nice but isn't necessary right now.
C) Switch positions with target if the target is another drag-able movie clip
I have all of the drag-able movie clips in one array and all of the "target" movie clips in another array. When I drop a MC onto a target it only works if I have specified that target in the code,
(dragBox[0])
or if the target is the last in the array. Here is the code I have currently.
var startX:Number = 0;
var startY:Number = 0;
var dropBoxes:Array = [/*list of dropBoxes*/];
var dragBoxes:Array = [/*list of dragBoxes*/];
for each (var dragBox_mc:MovieClip in dragBoxes){
dragBox_mc.addEventListener(MouseEvent.MOUSE_DOWN, pickIt);
dragBox_mc.addEventListener(MouseEvent.MOUSE_UP, dropIt);
}
function pickIt(evt:MouseEvent):void {
var objTarget = evt.target;
objTarget.parent.addChild(objTarget);
objTarget.startDrag();
startX = objTarget.x;
startY = objTarget.y;
}
function dropIt(evt:MouseEvent):void {
var objTarget = evt.target;
var target = evt.target.dropTarget;
if (target != null && target.parent == (dropBoxes[0])){
trace ("Dropped")
objTarget.x = (dropBoxes[0]).x;
objTarget.y = (dropBoxes[0]).y;
}else{
trace ("Returned")
objTarget.x = startX;
objTarget.y = startY;
}
objTarget.stopDrag();
}
So basically how do I get it to recognize all of the movieclips in the array at once instead of just one at a time?
Thanks
With the help of Kodiak I got this working exactly as I wanted so thanks a lot to him! Here is what I ended up with in case anyone else needs it.
function dropIt(evt:MouseEvent):void {
var objTarget = evt.target;
var target = evt.target.dropTarget;
// Drop dragBox onto dropBox
if (target != null && dropBoxes.indexOf(target.parent) != -1){
trace ("Dropped")
objTarget.x = target.parent.x;
objTarget.y = target.parent.y;
// Switch dragBox with another dragBox
}else if (target != null && dragBoxes.indexOf(target.parent) != -1){
trace ("Switched")
objTarget.x = target.parent.x
objTarget.y = target.parent.y
target.parent.x = startX
target.parent.y = startY
// If no target return to original position
}else{
trace ("Returned")
objTarget.x = startX;
objTarget.y = startY;
}
objTarget.stopDrag();
}
If you want to figure out if an item is in an array or not, you can use the Array.indexOf method.
var objTarget = evt.target;
var target = evt.target.dropTarget;
if (target != null && dropBoxes.indexOf(target.parent) != -1)
{
//...
}
indexOf return -1 if the item is not in the Array or the first index of the item if it is.
Is there a pretty solution of a GetPositionAtOffset() equivalent which only counts text insertion positions instead of all symbols?
Motivation example in C#:
TextRange GetRange(RichTextBox rtb, int startIndex, int length) {
TextPointer startPointer = rtb.Document.ContentStart.GetPositionAtOffset(startIndex);
TextPointer endPointer = startPointer.GetPositionAtOffset(length);
return new TextRange(startPointer, endPointer);
}
Edit: Until now i "solved" it this way
public static TextPointer GetInsertionPositionAtOffset(this TextPointer position, int offset, LogicalDirection direction)
{
if (!position.IsAtInsertionPosition) position = position.GetNextInsertionPosition(direction);
while (offset > 0 && position != null)
{
position = position.GetNextInsertionPosition(direction);
offset--;
if (Environment.NewLine.Length == 2 && position != null && position.IsAtLineStartPosition) offset --;
}
return position;
}
As far as I'm aware, there isn't. My suggestion is that you create your own GetPositionAtOffset method for this purpose. You can check which PointerContext the TextPointer is adjacent to by using:
TextPointer.GetPointerContext(LogicalDirection);
To get the next TextPointer which points to a different PointerContext:
TextPointer.GetNextContextPosition(LogicalDirection);
Some sample code I used in a recent project, this makes sure that the pointer context is of type Text, by looping until one is found. You could use this in your implementation and skip an offset increment if it is found:
// for a TextPointer start
while (start.GetPointerContext(LogicalDirection.Forward)
!= TextPointerContext.Text)
{
start = start.GetNextContextPosition(LogicalDirection.Forward);
if (start == null) return;
}
Hopefully you can make use of this information.
Could not find effective solution to this problem for a long time.
Next piece of code works in my case with the highest performance. Hope it will help somebody as well.
TextPointer startPos = rtb.Document.ContentStart.GetPositionAtOffset(searchWordIndex, LogicalDirection.Forward);
startPos = startPos.CorrectPosition(searchWord, FindDialog.IsCaseSensitive);
if (startPos != null)
{
TextPointer endPos = startPos.GetPositionAtOffset(textLength, LogicalDirection.Forward);
if (endPos != null)
{
rtb.Selection.Select(startPos, endPos);
}
}
public static TextPointer CorrectPosition(this TextPointer position, string word, bool caseSensitive)
{
TextPointer start = null;
while (position != null)
{
if (position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
string textRun = position.GetTextInRun(LogicalDirection.Forward);
int indexInRun = textRun.IndexOf(word, caseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase);
if (indexInRun >= 0)
{
start = position.GetPositionAtOffset(indexInRun);
break;
}
}
position = position.GetNextContextPosition(LogicalDirection.Forward);
}
return start; }
Basically I'm creating an indoor navigation system in J2ME. I've put the location details in a .txt file i.e.
Locations names and their coordinates.
Edges with respective start node and end node as well as the weight (length of the node).
I put both details in the same file so users dont have to download multiple files to get their map working (it could become time consuming and seem complex).
So what i did is to seperate the deferent details by typing out location Names and coordinates first, After that I seperated that section from the next section which is the edges by drawing a line with multiple underscores.
Now the problem I'm having is parsing the different details into seperate arrays by setting up a command (while manually tokenizing the input stream) to check wether the the next token is an underscore.
If it is, (in pseudocode terms), move to the next line in the stream, create a new array and fill it up with the next set of details.
I found a some explanation/code HERE that does something similar but still parses into one array, although it manually tokenizes the input. Any ideas on what to do? Thanks
Text File Explanation
The text has the following format...
<--1stSection-->
/**
* Section one has the following format
* xCoordinate;yCoordinate;LocationName
*/
12;13;New York City
40;12;Washington D.C.
...e.t.c
_________________________ <--(underscore divider)
<--2ndSection-->
/**
* Its actually an adjacency list but indirectly provides "edge" details.
* Its in this form
* StartNode/MainReferencePoint;Endnode1;distance2endNode1;Endnode2;distance2endNode2;...e.t.c
*/
philadelphia;Washington D.C.;7;New York City;2
New York City;Florida;24;Illinois;71
...e.t.c
package filereader;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Vector;
public class FileReader {
String locationSection;
String edgeSection;
Vector locations;
Vector edges;
public FileReader(String fileName) {
// read the contents into the string
InputStream is = getClass().getResourceAsStream(fileName);
StringBuffer sb = new StringBuffer();
int ch;
try {
while ((ch = is.read()) != -1) {
sb.append((char) ch);
}
} catch (IOException e2) {
e2.printStackTrace();
}
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
String text = sb.toString();
// separate locations and edges
String separator = "_________________________";
// read location section, without last end-of-line char
int endLocationSection = text.indexOf(separator) - 1;
locationSection = text.substring(0, endLocationSection);
// read edges section, without end-of-line char after separator
int startEdgeSection = endLocationSection + separator.length() + 3;
edgeSection = text.substring(startEdgeSection, text.length());
// parse locations and edges
locations = getLocationsVector(locationSection);
edges = getEdgesVector(edgeSection);
}
// parse locations section
public Vector getLocationsVector(String section) {
Vector result = new Vector();
int startLine = 0;
int endLine = section.indexOf('\n');
while (endLine != -1) {
String line = section.substring(startLine, endLine);
result.addElement(parseLocationsLine(line, ';'));
startLine = endLine + 1;
if (endLine == section.length() - 1)
break;
endLine = section.indexOf('\n', startLine);
// if no new line found, read to the end of string
endLine = (-1 == endLine) ? section.length() - 1 : endLine;
}
return result;
}
// parse edges section
public Vector getEdgesVector(String section) {
Vector result = new Vector();
int startLine = 0;
int endLine = section.indexOf('\n');
while (endLine != -1) {
String line = section.substring(startLine, endLine - 1);
result.addElement(parseEdgesLine(line, ';'));
startLine = endLine + 1;
if (endLine == section.length() + 1)
break;
endLine = section.indexOf('\n', startLine);
// if no new line found, read to the end of string
endLine = (-1 == endLine) ? section.length() + 1 : endLine;
}
return result;
}
// parse locations line
public Hashtable parseLocationsLine(String value, char splitBy) {
Hashtable result = new Hashtable();
int xCEnd = value.indexOf(splitBy);
int yCEnd = value.indexOf(splitBy, xCEnd + 1);
result.put("x", value.substring(0, xCEnd));
result.put("y", value.substring(xCEnd + 1, yCEnd));
result.put("location", value.substring(yCEnd + 1,
value.length() - 1));
return result;
}
// parse edges line
public Hashtable parseEdgesLine(String value, char splitBy) {
Hashtable result = new Hashtable();
int snEnd = value.indexOf(splitBy);
result.put("startnode", value.substring(0, snEnd));
int n = 1;
int start = snEnd + 1;
int enEnd = value.indexOf(splitBy, snEnd + 1);
int dstEnd = value.indexOf(splitBy, enEnd + 1);
while (enEnd != -1 && dstEnd != -1) {
result.put("endnode" + String.valueOf(n),
value.substring(start, enEnd));
result.put("distance" + String.valueOf(n), value.substring(
enEnd + 1, dstEnd));
start = dstEnd + 1;
enEnd = value.indexOf(splitBy, start);
if (dstEnd == value.length())
break;
dstEnd = value.indexOf(splitBy, enEnd + 1);
// if last endnode-distance pair, read to the end of line
dstEnd = (-1 == dstEnd) ? value.length() : dstEnd;
n++;
}
return result;
}
// getters for locations and edges
public Vector getLocations() {
return locations;
}
public Vector getEdges() {
return edges;
}
}
and somewhere in application screen:
fr = new FileReader("/map.txt");
Vector vct1 = fr.getLocations();
for (int i = 0; i < vct1.size(); i++) {
Hashtable location = (Hashtable) vct1.elementAt(i);
Enumeration en = location.keys();
String fv = "";
while (en.hasMoreElements()) {
String key = (String) en.nextElement();
String value = (String)location.get(key);
fv = fv + value + "-";
}
this.add(new LabelField(fv));
}
Vector vct2 = fr.getEdges();
for (int i = 0; i < vct2.size(); i++) {
Hashtable location = (Hashtable) vct2.elementAt(i);
Enumeration en = location.keys();
String fv = "";
while (en.hasMoreElements()) {
String key = (String) en.nextElement();
String value = (String)location.get(key);
fv = fv + value + "-";
}
this.add(new LabelField(fv));
}
it will be easy to get values from hashtable by keys:
(String)location.get("x")
(String)location.get("y")
(String)location.get("location")
(String)edge.get("startnode")
(String)edge.get("endnode1")
(String)edge.get("distance1")
(String)edge.get("endnode2")
(String)edge.get("distance2")
...