I want to have my C++ Builder application fill the following Word document form :
http://oesv.at/media/media_vereinsservice/media_formulare/Zuschlagsberechnung-Alpin_06-07.doc
I manage to do this with Ole procedures calling OpenOffice Writer but for users of my application who don't have OpenOffice installed but Microsoft Office instead I want to call Ole procedures with Word.
I tried without success to find and see the structure of this document file: like a tree map with : the document object, the Fields or FormFields objects, their properties "Field", which have properties Result, which is a range object having property Text and the document property Selection which has the procedure "TypeText". But no structure view available, so just guessing in the dark how the document file is structured.
Here below two solutions I tried without success:
first: the commented part consist on selecting the text input field and have this current selection in the document call its procedure "TypeText". This throws an error saying the object I try to modify is in a protected area of the document : "EOleException : Cette méthode ou propriété n'est pas disponible car l'objet fait référence à une zone protégée d'un document.".
second: the code below throws an error "EOleException : Le type ne correspond pas" that can be translated "Type mismatch" on the line "Result.OlePropertySet("Text", vInputText);". I have tried to pass a WideString or directly the default string format for my project without success.
try
{
//---ouverture de Word
vMSWord.OlePropertySet("Visible", false);
//---ouverture du fichier
vFileName = Variant(wFile.c_bstr());
vWDocuments = vMSWord.OlePropertyGet("Documents");
vWDocument = vWDocuments.OleFunction("Open", vFileName);
Variant fields, field;
fields = vWDocument.OlePropertyGet("FormFields");
for (int i=1; i<=fields.OlePropertyGet("Count"); i++)
{
Variant field = fields.OleFunction("Item",(Variant)i);
//field.OleFunction("Select");
//Variant selection = vMSWord.OlePropertyGet("Selection");
//selection.OleProcedure("TypeText",WideString("My input text"));
Variant Result = field.OlePropertyGet("Result"); // result = objet range
Variant vInputText = Variant(WideString("My input text").c_bstr());
Result.OlePropertySet("Text", vInputText);
}
//---sauvegarde en fichier texte
vFileName = Variant(wNewFile.c_bstr());
ShowMessage("Saveas :");
vWDocument.OleProcedure("Saveas", vFileName);
}
catch(Exception &e)
{
ShowMessage(AnsiString(e.ClassName())+ e.Message);
}
I do it so:
...
String FieldName = "SomeFormFieldName"; // Try WideString
String Text = "SomeText"; // Try WideString
Variant Field = Document.OlePropertyGet("FormFields").OleFunction("Item", (OleVariant)FieldName);
Field.OlePropertyGet("Range").OlePropertySet("Text", Text);
...
But you must be shure that the Document contains fields is exactly of FormFields type not MergeField or others. Also you must set the Bookmark property for Fields inside the template document and use it as FieldName.
Related
I'm trying to load a text file (.csv) into a SQL Server database table. Each line in the file is supposed to be loaded into a single column in the table. I find that lines starting with "#" are skipped, with no error. For example, the first two of the following four lines are loaded fine, but the last two are not. Anybody knows why?
ThisLineShouldBeLoaded
This one as well
#ThisIsATestLine
#This is another test line
Here's the segment of my code:
var sqlConn = connection.StoreConnection as SqlConnection;
sqlConn.Open();
CsvReader reader = new CsvReader(new StreamReader(f), false);
using (var bulkCopy = new SqlBulkCopy(sqlConn))
{
bulkCopy.DestinationTableName = "dbo.TestTable";
try
{
reader.SkipEmptyLines = true;
bulkCopy.BulkCopyTimeout = 300;
bulkCopy.WriteToServer(reader);
reader.Dispose();
reader = null;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
System.Diagnostics.Debug.WriteLine(ex.Message);
throw;
}
}
# is the default comment character for CsvReader. You can change the comment character by changing the Comment property of the Configuration object. You can disable comment processing altogether by setting the AllowComment property to false, eg:
reader.Configuration.AllowComments=false;
SqlBulkCopy doesn't deal with CSV files at all, it sends any data that's passed to WriteServer to the database. It doesn't care where the data came from or what it contains, as long as the column mappings match
Update
Assuming LumenWorks.Framework.IO.Csv refers to this project the comment character can be specified in the constructor. One could set it to something that wouldn't appear in a normal file, perhaps even the NUL character, the default char value :
CsvReader reader = new CsvReader(new StreamReader(f), false, escape:default);
or
CsvReader reader = new CsvReader(new StreamReader(f), false, escape : '\0');
I am using iText7 and I want to extract all the texts from a pdf and put html tag for bold ( <b>...</b> ) around all the words that uses bold fonts and save it in text file. Any pointers? I am able to independently extract text and also extract all the bold words but not able to co-relate the two.
Here is the code snippet I am using for extracting the text:
PdfDocument MyDocument = new PdfDocument(new PdfReader("C:\\MyTest.pdf"));
string MyText = PdfTextExtractor.GetTextFromPage(MyDocument.GetPage(1), new
SimpleTextExtractionStrategy());
Here is the code I am using for extracting all the words using the bold font:
MyRectangle = new Rectangle(0, 0, 50, 100);
CustomFontFilter fontFilter = new CustomFontFilter(MyRectangle);
FilteredEventListener listener = new FilteredEventListener();
LocationTextExtractionStrategy extractionStrategy =
listener.AttachEventListener(new LocationTextExtractionStrategy(), fontFilter);
PdfCanvasProcessor parser = new PdfCanvasProcessor(listener);
parser.ProcessPageContent(MyDocument.GetPage(1));
String MyBoldTextList = extractionStrategy.GetResultantText();
//------
class CustomFontFilter : TextRegionEventFilter
{
public CustomFontFilter(iText.Kernel.Geom.Rectangle filterRect) : base(filterRect){ }
override public bool Accept(IEventData data, EventType type)
{
if (type == EventType.RENDER_TEXT){
TextRenderInfo renderInfo = (TextRenderInfo)data;
PdfFont font = renderInfo.GetFont();
if (font!=null)
return font.GetFontProgram().GetFontNames().GetFontName().Contains("Bold");
}
return false;
}
}
The problem is that the pdf in question here is a multi-column document. SimpleTextExtractionStrategy brings the text in perfect order but if I use the LocationStrategy, it messes up texts by jumping from one column to next column in each line. I am not able to find any way to get the list of bold words using SimpleTextExtractionStrategy. In LocationStrategy, the list that I get is not in the right order so I am unable to co-relate it.
So to summarize:
You want to extract all the text from a pdf and put the html tag for bold (<b>...</b>) around all the text that uses bold fonts.
Your PDFs allow normal text extraction (without those <b> tags) using the SimpleTextExtractionStrategy. The LocationTextExtractionStrategy on the other hand cannot be used as it messes up the order of the multi-column text.
Bold text in your PDFs can properly be recognized by your CustomFontFilter, i.e. by the
font.GetFontProgram().GetFontNames().GetFontName().Contains("Bold")
condition.
Thus, one way to implement your task would be to extend the SimpleTextExtractionStrategy to check every chunk received using the CustomFontFilter condition and insert <b> tags where required.
For example like this:
public class BoldTaggingSimpleTextExtractionStrategy : SimpleTextExtractionStrategy
{
FieldInfo textField = typeof(TextRenderInfo).GetField("text", BindingFlags.NonPublic | BindingFlags.Instance);
bool currentlyBold = false;
public override void EventOccurred(IEventData data, EventType type)
{
if (type.Equals(EventType.RENDER_TEXT))
{
TextRenderInfo renderInfo = (TextRenderInfo)data;
string fontName = renderInfo.GetFont()?.GetFontProgram()?.GetFontNames()?.GetFontName();
if (fontName != null && fontName.Contains("Bold"))
{
if (!currentlyBold)
{
textField.SetValue(renderInfo, "<b>" + renderInfo.GetText());
currentlyBold = true;
}
}
else if (currentlyBold)
{
AppendTextChunk("</b>");
currentlyBold = false;
}
}
base.EventOccurred(data, type);
}
}
As you see I used reflection here. I did so because (A) TextRenderInfo does not allow public setting of the text and (B) AppendTextChunk must not be used before the first chunk is processed by base.EventOccurred - there the size of a StringBuilder containing the collected text chunks is used to check whether the chunk currently processed is the first one or not; if something is in that builder before at least one chunk has been processed, one gets a NullReferenceException. There are other work-arounds for that but reflection here means but one more line of code.
I want to search a text that contains comma in database, but, there is not comma in the reference.
For example. In database I have the following value:
"Development of computer programs, including electronic games"
So, I try to search the data using the following string as reference:
"development of computer programs including electronic games"
NOTE that the only difference is that in database I have a comma in the text, but, in my reference for search, I have not.
Here is my code:
public async Task<ActionResult>Index(string nomeServico)
{
using (MyDB db = new MyDB())
{
// 1st We receive the following string:"development-of-computer-programs-including-electronic-games"
// but we remove all "-" characters
string serNome = nomeServico.RemoveCaractere("-", " ");
// we search the service that contains (in the SerName field) the value equal to the parameter of the Action.
Servicos servico = db.Servicos.FirstOrDefault(c => c.SerNome.ToLower().Equals(serNome, StringComparison.OrdinalIgnoreCase));
}
}
The problem is that, in the database, the data contains comma, and in the search value, don't.
In you code you are replacing "-" with "" and that too in your search string. But as per your requirement you need to change "," with "" for your DB entry.
Try doing something like this:
string serNome = nomeServico.ToLower();
Servicos servico = db.Servicos.FirstOrDefault(c => c.SerNome.Replace(",","").ToLower() == serNome);
I am trying to read data using the Smartsheet API from Java to create different formats, such as reports & labels with the data from one row.
I've set up my IDE (NetBeans) so that the API samples work for me, but they are all about creating new sheets etc and I can not figure out how to read the contents of an existing sheet.
I would have thought that I could read the entire sheet into a java object in one line of code, but it appears more complicated than that, and I can not find any applicable documentation anywhere. The Javadoc does not say where/how to get the relevant IDs, what any of the inclusion or exclusion objects actually do, or which are required or optional etc.
Are there any examples of reading the contents of a sheet from java available?
I know that this is a bit of a broad question, but I'm totally stumped.
Thanks Kim!
For others, here's what worked for me. This code gets a list of the sheets in my account and displays the contents those with names starting with "Specs - " :
import com.smartsheet.api.Smartsheet;
import com.smartsheet.api.SmartsheetBuilder;
import com.smartsheet.api.SmartsheetException;
import com.smartsheet.api.models.Cell;
import com.smartsheet.api.models.Column;
import com.smartsheet.api.models.PagedResult;
import com.smartsheet.api.models.Row;
import com.smartsheet.api.models.Sheet;
import com.smartsheet.api.oauth.Token;
import java.util.List;
import java.util.Objects;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SampleCode {
/*
Show the contenst of all sheets whose name starts with "Specs - "
*/
public static void main(String[] args) {
final String delimiter = ", ";
// Create a Smartsheet object with our Access Token
Token token = new Token();
token.setAccessToken(Private.TOKEN);
Smartsheet smartsheet = new SmartsheetBuilder().setAccessToken(token.getAccessToken()).build();
//get a paged list of all Sheets, using null Source Inclusion & Pagination parameters
PagedResult<Sheet> homeSheets = new PagedResult<>();
try {
homeSheets = smartsheet.sheetResources().listSheets(null, null);
} catch (SmartsheetException ex) {
Logger.getLogger(SampleCode.class.getName()).log(Level.SEVERE, null, ex);
}
// get a Java List<Sheet> from the PagedResult<Sheet>
List<Sheet> sheetInfoList = homeSheets.getData();
// Loop through each sheet in the list
for (Sheet sheetInfo : sheetInfoList) {
String sheetName = sheetInfo.getName();
// Show data for all sheets with names that match our pattern
if (sheetName.startsWith("Specs - ")) {
// get the sheet object, with no optional includes or excludes
Sheet theSheet = null;
try {
theSheet = smartsheet.sheetResources().getSheet(sheetInfo.getId(), null, null, null, null, null, null, null);
} catch (SmartsheetException ex) {
Logger.getLogger(SampleCode.class.getName()).log(Level.SEVERE, null, ex);
}
// Print the sheets name
System.out.println("\nSheet: " + theSheet.getName() + "\n");
// Print the column titles as a delimited line of text.
List<Column> columnList = theSheet.getColumns();
String columnHeader = null;
for (Column col : columnList) {
columnHeader = columnHeader == null ? col.getTitle() : columnHeader + delimiter + col.getTitle();
}
System.out.println(columnHeader);
// Print each row as a delimited line of text.
List<Row> rowList = theSheet.getRows();
for (Row row : rowList) {
List<Cell> cellList = row.getCells();
String rowOutput = null;
for (Cell cell : cellList) {
String cellOutput = Objects.toString(cell.getValue() != null ? cell.getValue() : cell.getDisplayValue());
rowOutput = rowOutput == null ? cellOutput : rowOutput + delimiter + cellOutput;
}
System.out.println(rowOutput);
}
}
}
}
}
The Smartsheet API documentation contains sample code that shows how to use the Java SDK. The Java Sample Code section in the docs describes how to establish the connection, etc. Then, each operation within in the "API Reference" section shows sample code (in the "Java" tab of the panel on the right side of the page) for executing the operation using the Java SDK.
To get Sheet data you'll use the "Get Sheet" operation. As described in the API docs, here's the Java SDK sample code for that operation:
// Get sheet (omit all parameters).
smartsheet.sheetResources().getSheet(sheetId, null, null, null, null, null, null, null);
The "sheetId" parameter should be the ID of the Sheet which you want to retrieve. You can either get this ID programmatically (i.e., by using an operation like "List Sheets", for example) -- or you can get it manually via the Smartsheet UI as described in this help article. The other parameters (all set to "null" in the sample code) represent the 7 parameters described in the API documentation for this operation. I imagine intellisense in your IDE should indicate the sequence of those parameters expected by the getSheet function, as well as valid values for each parameter (but the API docs will explain the meaning of each parameter).
I've spent two days on this and I'm still not able to figure it out 8-)
I have a LibreOffice Writer document with some Placeholders (Insert -> Fields -> More Fields -> Functions -> Placeholder -> Image) and Input fields (Insert -> Fields -> More Fieds -> Functions -> Input field) and I need to retrieve the value of an Input field and use it to replace a specified Placeholder in the same document.
To be more precise. I have an Input field where I enter for example 123
and somewhere in the document is a button, which triggers a macro, and this macro should:
retrieve the current value of the specified (named?) Input field ("123"),
"replace" a specified (named?) Placeholder with an image loaded from http://domain.tld/image/123.png
Is this somehow possible? Would be great, because I'm trying to to insert externally generated barcodes into my document...
These are both "Text fields", and some information and macro examples are in Andrew Pitonyak's book OpenOffice Macros Explained (available as a free pdf download from http://www.pitonyak.org/oo.php). The wiki page also has some good background.
Form controls (from the toolbar "Form controls") are named, so they have an advantage when working with macros. Text fields, however - the kind you have in your document - are not named, so you have to cycle through all the fields in a document, or highlight a particular run of text and cycle through the field within the highlighted area to find the one you are after. The Pitonyak document has examples of both methods.
Assuming the document has only one input field, this StarBasic code will print its current value:
Sub DisplayFields
Dim oEnum As Object
Dim oField As Object
oEnum = ThisComponent.getTextFields().createEnumeration()
Do While oEnum.hasMoreElements()
oField = oEnum.nextElement()
If oField.getPresentation(True) = "Input field" Then
Print "Input field contents: " & oField.getPresentation(False)
Exit Do
End If
Loop
End Sub
As far as I can tell, there is no API to replace a placeholder with its designated content. There might be a way with the dispatcher - the list of dispatch commands tantalizingly includes "FieldDialog" - but I wasn't able to find any documentation or examples.
I think what you'd have to do is find the field, put your cursor there, insert the image, then delete the placeholder field. Some more StarBasic code (again, assuming there's only a single placeholder field in the document):
Sub InsertImage
Dim oEnum As Object
Dim oField As Object
Dim oAnchor As Object
Dim oText As Object
Dim oCursor As Object
Dim FileName As String
Dim FileURL As String
Dim objTextGraphicObject As Object
oEnum = ThisComponent.getTextFields().createEnumeration()
Do While oEnum.hasMoreElements()
oField = oEnum.nextElement()
If oField.getPresentation(True) = "Placeholder" Then
oAnchor = oField.Anchor
oText = oAnchor.getText()
oCursor = oText.createTextCursorByRange(oAnchor.getEnd)
FileName = "C:\after zoo.JPG"
FileURL = convertToURL(FileName)
objTextGraphicObject = ThisComponent.createInstance("com.sun.star.text.TextGraphicObject")
REM Optional to set the size
' Dim objSize as New com.sun.star.awt.Size
' objSize.Width = 3530
' objSize.Height = 1550
' objTextGraphicObject.setSize(objSize)
objTextGraphicObject.GraphicURL = FileURL
oText.insertTextContent(oCursor.Start, objTextGraphicObject, false)
oField.dispose()
Exit Do
End If
Loop
End Sub