OpenXml how to split a word document into pages - c#

I want to split a Word document into separate pages and save them to files like Page_1.docx; Page_2.docx ......
At first I tried to do this:
using (var sourceWordDoc = WordprocessingDocument.Open(
wordFilePath
, false))
{
var sourceElements = sourceWordDoc.MainDocumentPart.Document.Body.Elements();
var pageElements = new List<DocumentFormat.OpenXml.OpenXmlElement>();
var pageIndex = 1;
foreach (var sourceElement in sourceElements)
{
var run = sourceElement.GetFirstChild<Run>();
if (run != null)
{
var lastRenderedPageBreak = run.GetFirstChild<LastRenderedPageBreak>();
var pageBreak = run.GetFirstChild<Break>();
if (lastRenderedPageBreak != null || pageBreak != null)
{
//Create and save page
using (var destinationWordDoc = WordprocessingDocument.Create(
$"Page_{pageIndex}.docx",
DocumentFormat.OpenXml.WordprocessingDocumentType.Document))
{
var destinationPart = destinationWordDoc.AddMainDocumentPart();
destinationPart.Document = new Document();
var destinationBody = destinationPart.Document.AppendChild(new Body());
foreach (var pageElement in pageElements)
{
destinationBody.Append(pageElement.CloneNode(true));
}
destinationPart.Document.Save();
}
pageElements.Clear();
pageIndex++;
}
}
pageElements.Add(sourceElement);
}
}
But in this variand, Header is not copied.
Then I wrote the following code to copy the Header (for test):
using (var sourceWordDoc = WordprocessingDocument.Open(
wordFilePath
, false))
{
var sourceHeaderPart = sourceWordDoc.MainDocumentPart.HeaderParts.FirstOrDefault();
var sourceDocument = sourceWordDoc.MainDocumentPart.Document;
using (var destinationWordDoc = WordprocessingDocument.Create(
somePath
, WordprocessingDocumentType.Document))
{
var destinationMainDocumentPart = destinationWordDoc.AddMainDocumentPart();
destinationMainDocumentPart.Document = new DocumentFormat.OpenXml.Wordprocessing.Document();
var destinationBody = destinationMainDocumentPart.Document.AppendChild(new DocumentFormat.OpenXml.Wordprocessing.Body());
var rId = string.Empty;
if (sourceHeaderPart != null)
{
var destinationHeaderPart = destinationMainDocumentPart.AddNewPart<HeaderPart>();
rId = destinationMainDocumentPart.GetIdOfPart(destinationHeaderPart);
destinationHeaderPart.FeedData(sourceHeaderPart.GetStream());
}
var sourceElements = sourceDocument.Body.Elements();
foreach (var sourceElement in sourceElements)
{
if (sourceElement.GetType() == typeof(DocumentFormat.OpenXml.Wordprocessing.SectionProperties))
{
var sourceSectionsElements = sourceElement.Elements();
foreach (var sourceSectionsElement in sourceSectionsElements)
{
if (sourceSectionsElement.GetType() == typeof(DocumentFormat.OpenXml.Wordprocessing.HeaderReference))
{
var sourceHeaderReference = (DocumentFormat.OpenXml.Wordprocessing.HeaderReference)sourceSectionsElement;
sourceHeaderReference.Id = rId;
break;
}
}
}
destinationBody.Append(sourceElement.CloneNode(true));
}
}
}
But now I have a new problem, images from the header are not transferred.
Are there any options to break the document into separate pages and at the same time preserve the entire content of the page?

Related

EF adding new record instead of updating record

Below is my code to add new records in db. I am using EF Core.
In my code I am checking first if existing user id data is there or not in db, if there is data then it should update record otherwise it should create.
But my problem is every time it is adding new record instead of updating existing one..any idea on this.
Below is my code :
public async Task<int> Create(UserPreference _object)
{
var userPreferenceDetails = applicationDbContext.UserPreferences.Where(x => x.UserId == _object.UserId).FirstOrDefault();
if(userPreferenceDetails != null)
{
if (_object.Image != null)
{
var webRootPath = hostingEnv.WebRootPath;
var fileName = Path.GetFileName(_object.Image.FileName);
var filePath = Path.Combine(hostingEnv.WebRootPath, "images\\User", fileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await _object.Image.CopyToAsync(fileStream);
}
userPreferenceDetails.ImagePath = filePath;
//_object.ImagePath = filePath;
}
userPreferenceDetails.Name = _object.Name;
userPreferenceDetails.Location = _object.Location;
userPreferenceDetails.DateOfBirth = _object.DateOfBirth;
userPreferenceDetails.AboutMe = _object.AboutMe;
userPreferenceDetails.MatchPreference = _object.MatchPreference;
userPreferenceDetails.PlayScore = _object.PlayScore;
userPreferenceDetails.LocationPreference = _object.LocationPreference;
var obj = applicationDbContext.UserPreferences.Update(_object);
return applicationDbContext.SaveChanges();
} else
{
if (_object.Image != null)
{
var webRootPath = hostingEnv.WebRootPath;
var fileName = Path.GetFileName(_object.Image.FileName);
var filePath = Path.Combine(hostingEnv.WebRootPath, "images\\User", fileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
await _object.Image.CopyToAsync(fileStream);
}
_object.ImagePath = filePath;
}
var obj = await applicationDbContext.UserPreferences.AddAsync(_object);
return applicationDbContext.SaveChanges();
}
}
try this
if(_object.UserId > 0)
{
var userPreferenceDetails = applicationDbContext.UserPreferences.Where(x =>
x.UserId == _object.UserId).FirstOrDefault();
if(userPreferenceDetails == null) return 0;
if (_object.Image != null)
{
....your code
}
userPreferenceDetails.Name = _object.Name;
userPreferenceDetails.Location = _object.Location;
userPreferenceDetails.DateOfBirth = _object.DateOfBirth;
userPreferenceDetails.AboutMe = _object.AboutMe;
userPreferenceDetails.MatchPreference = _object.MatchPreference;
userPreferenceDetails.PlayScore = _object.PlayScore;
userPreferenceDetails.LocationPreference = _object.LocationPreference;
}
else
{
if (_object.Image != null)
{
...your code
}
applicationDbContext.UserPreferences.Add(_object);
}
var result= await applicationDbContext.SaveChangesAsync();
return result;
}

Get Connected Elements in Autodesk Inventor via API

We have Autodesk Inventor and created a C# Addon.
In this we loop through all Objects like this:
foreach (CurrencyAPIv2.IAssetInstance s in objects)
{
var c = s.NativeObject as ComponentOccurrence;
}
How can we get the connected Object of an Object (the one which is snapped to it). And also the Info to which connector it is connected (snapped)
Michael Navara:
Can you be more specific? CurrencyAPIv2.IAssetInstance is not a member of Inventor API
using CurrencyAPIv2 = Autodesk.Factory.PublicAPI.Currency.v2;
We solved it with the XML-files which can also be watched in AttributeHelper:
void LoadConnectors(Document document, List<ConnectionElement> connections, List<ConnectedComponent> components)
{
var am = document.AttributeManager;
var d = new Dictionary<string, string>();
var entities = am.FindObjects("*", "*");
foreach (var e in entities)
{
try
{
dynamic o = e;
foreach (AttributeSet attrS in o.AttributeSets)
{
foreach (Inventor.Attribute a in attrS)
{
d.Add(o.Name, a.Value as string);
}
}
}
catch(Exception)
{ }
}
foreach (var element in d)
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(element.Value);
var connectionNodes = xmlDoc.SelectNodes("//ObjectData[#Type='42']");
var componentNodes = xmlDoc.SelectNodes("//ObjectData[#Type='38']");
// Verbindungen
if (connectionNodes.Count > 0)
{
var link1Node = xmlDoc.SelectSingleNode("//ObjectData/Link1") as XmlElement;
var link2Node = xmlDoc.SelectSingleNode("//ObjectData/Link2") as XmlElement;
var connection = new ConnectionElement();
connection.Name = element.Key;
connection.Link1 = link1Node.GetAttribute("VAL");
connection.Link2 = link2Node.GetAttribute("VAL");
connections.Add(connection);
}
// Komponenten
else if (componentNodes.Count > 0)
{
var componentConnectorNodes = xmlDoc.SelectNodes("//ObjectData/Connector");
var componentConnectors = new List<ComponentConnector>();
foreach (XmlNode cc in componentConnectorNodes)
{
var idNode = cc.SelectSingleNode("Id") as XmlElement;
var displayNameNode = cc.SelectSingleNode("DisplayName") as XmlElement;
var connector = new ComponentConnector();
connector.DisplayName = displayNameNode.GetAttribute("VAL");
connector.Id = idNode.GetAttribute("VAL");
componentConnectors.Add(connector);
}
if (components.FirstOrDefault(x => x.Name == element.Key) != null)
{
components.FirstOrDefault(x => x.Name == element.Key).Connectors.AddRange(componentConnectors);
}
else
{
var component = new ConnectedComponent();
component.Name = element.Key;
component.Connectors = new List<ComponentConnector>();
component.Connectors.AddRange(componentConnectors);
components.Add(component);
}
}
}
}

How do I refactor the code which contains foreach loop

I need to refactor the below code so that the deleted_at logic will be outside of the foreach (var app in data) loop. I tried to create the list guids and then add guids to it but its not working because model.resources is inside the loop and it is still deleting all the apps.
I need deleted_at logic outside because I'm trying to delete all apps which are in the database but are not in new data that I'm receiving from API.
If you have a better approach on my code I would love to see that, Thank you.
public async Task GetBuilds()
{
var data = new List<GetBuildTempClass>();
var guids = new List<GetBuildTempClass>();
using (var scope = _scopeFactory.CreateScope())
{
var _DBcontext = scope.ServiceProvider.GetRequiredService<PCFStatusContexts>();
foreach (var app in data)
{
var request = new HttpRequestMessage(HttpMethod.Get,
"apps/" + app.AppGuid + "/builds?per_page=200&order_by=updated_at");
var response = await _client_SB.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
BuildsClass.BuildsRootObject model =
JsonConvert.DeserializeObject<BuildsClass.BuildsRootObject>(json);
foreach (var item in model.resources)
{
var x = _DBcontext.Builds.FirstOrDefault(o =>
o.Guid == Guid.Parse(item.guid));
if (x == null)
{
_DBcontext.Builds.Add(new Builds
{
Guid = Guid.Parse(item.guid),
State = item.state,
CreatedAt = item.created_at,
UpdatedAt = item.updated_at,
Error = item.error,
CreatedByGuid = Guid.Parse(item.created_by.guid),
CreatedByName = item.created_by.name,
CreatedByEmail = item.created_by.email,
AppGuid = app.AppGuid,
AppName = app.AppName,
Foundation = 2,
Timestamp = DateTime.Now
});
}
else if (x.UpdatedAt != item.updated_at)
{
x.State = item.state;
x.UpdatedAt = item.updated_at;
x.Timestamp = DateTime.Now;
}
var sqlresult = new GetBuildTempClass
{
AppGuid = Guid.Parse(item.guid)
};
guids.Add(sqlresult);
}
//var guids = model.resources.Select(r => Guid.Parse(r.guid));
var builds = _DBcontext.Builds.Where(o =>
guids.Contains(o.Guid) == false &&
o.Foundation == 2 && o.DeletedAt == null);
foreach (var build_item in builds)
{
build_item.DeletedAt = DateTime.Now;
}
}
await _DBcontext.SaveChangesAsync();
}
}
I got it working I added var guids = new List < Guid > (); list to store data,
added guids.Add(Guid.Parse(item.guid)); to populate the list and finally wrote var builds = _DBcontext.Builds.Where(o = >guids.Contains(o.Guid) == false && o.Foundation == 2 && o.DeletedAt == null); outside the loop.
If anyone has a better suggestion please add a new answer.
public async Task GetBuilds() {
var data = new List < GetBuildTempClass > ();
var guids = new List < Guid > ();
using(var scope = _scopeFactory.CreateScope()) {
var _DBcontext = scope.ServiceProvider.GetRequiredService < PCFStatusContexts > ();
foreach(var app in data) {
var request = new HttpRequestMessage(HttpMethod.Get, "apps/" + app.AppGuid + "/builds?per_page=200&order_by=updated_at");
var response = await _client_SB.SendAsync(request);
var json = await response.Content.ReadAsStringAsync();
BuildsClass.BuildsRootObject model = JsonConvert.DeserializeObject < BuildsClass.BuildsRootObject > (json);
foreach(var item in model.resources) {
var x = _DBcontext.Builds.FirstOrDefault(o = >o.Guid == Guid.Parse(item.guid));
if (x == null) {
_DBcontext.Builds.Add(new Builds {
Guid = Guid.Parse(item.guid),
State = item.state,
CreatedAt = item.created_at,
UpdatedAt = item.updated_at,
Error = item.error,
CreatedByGuid = Guid.Parse(item.created_by.guid),
CreatedByName = item.created_by.name,
CreatedByEmail = item.created_by.email,
AppGuid = app.AppGuid,
AppName = app.AppName,
Foundation = 2,
Timestamp = DateTime.Now
});
}
else if (x.UpdatedAt != item.updated_at) {
x.State = item.state;
x.UpdatedAt = item.updated_at;
x.Timestamp = DateTime.Now;
}
guids.Add(Guid.Parse(item.guid));
}
}
var builds = _DBcontext.Builds.Where(o = >guids.Contains(o.Guid) == false && o.Foundation == 2 && o.DeletedAt == null);
foreach(var build_item in builds) {
build_item.DeletedAt = DateTime.Now;
}
await _DBcontext.SaveChangesAsync();
}
}

Instagram API: How to insert all user media in c# asp.net mvc?

I am trying the get all user media from the instagram api and store into database but how can do that i don't know. i am write the code but using this code just add one media in the database. any one have the idea then please let me know how can do that. here below list the my code.
This is my C# method :
public string makePostFromInstagram()
{
var serializer1 = new System.Web.Script.Serialization.JavaScriptSerializer();
var nodes1 = serializer1.Deserialize<dynamic>(GetData(strInstagramUserId));
foreach (var date in nodes1)
{
if (date.Key == "data")
{
string theKey = date.Key;
var thisNode = date.Value;
int userCount = 0;
foreach (var post in thisNode)
{
if (thisNode[userCount]["username"] == strInstagramUserId)
{
id = thisNode[userCount]["id"].ToString();
}
userCount++;
}
}
}
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
Dictionary<string, object> csObj = serializer.Deserialize<Dictionary<string, object>>(GetRecentPost(id, accessToken));
int length = ((ArrayList)csObj["data"]).Count;
var nodes = serializer.Deserialize<dynamic>(GetRecentPost(id, accessToken));
foreach (var date in nodes)
{
if (date.Key == "data")
{
string theKey = date.Key;
var thisNode = date.Value;
foreach (var post in thisNode)
{
UsersOnInstagram objUserInsta = new UsersOnInstagram();
string result = null;
//here i am add just one image so i want to here add multiple image insert
if (post["type"] == "image")
result = UsersOnInstagram.addInstagramPost(strPtId, HttpUtility.UrlEncode(post["caption"]["text"]), post["images"]["standard_resolution"]["url"], UnixTimeStampToDateTime(Convert.ToDouble(post["created_time"])), null, post["type"]);
else if (post["type"] == "video")
result = objUserInsta.addInstagramPost(HttpUtility.UrlEncode(post["caption"]["text"]), strPtId, post["images"]["standard_resolution"]["url"], UnixTimeStampToDateTime(Convert.ToDouble(post["created_time"])), post["videos"]["standard_resolution"]["url"], post["type"]);
}
}
}
Response.End();
}
this is my api method :
public static string GetRecentPost(string instagramaccessid, string instagramaccesstoken)
{
Double MAX_TIMESTAMP = DateTimeToUnixTimestamp(DateTime.Today.AddDays(-1));
Double MIN_TIMESTAMP = DateTimeToUnixTimestamp(DateTime.Today.AddDays(-2));
string url = "https://api.instagram.com/v1/users/" + instagramaccessid + "/media/recent?access_token=" + instagramaccesstoken + "&min_timestamp=" + MIN_TIMESTAMP + "&maz_timestamp=" + MAX_TIMESTAMP;
var webClient = new System.Net.WebClient();
string d = webClient.DownloadString(url);
return d;
}
any one know how can do that please let me know.

How to fetch the data from SqLite database

I have created database in SqLite in my windows app, now I want to fetch the data from my database. This is the code how I inserted the data in databse.
var dbpath = Path.Combine(Windows.Storage.ApplicationData.Current.LocalFolder.Path, "scrapbook.sqlite");
using (var db = new SQLite.SQLiteConnection(dbpath))
{
// Create the tables if they don't exist
var bg = listAlbumContainer[0] as AlbumContainer;
var albumbg = bg.BackgroundImageName;
var sk = listAlbumContainer[0].listAlbumContainer;
var _audio = listAlbumContainer[0].listAlbumContainer5;
var _video = listAlbumContainer[0].listAlbumContainer3;
var wa = listAlbumContainer[0].listAlbumContainer4;
var ci = listAlbumContainer[0].listAlbumContainer2;
var gi = listAlbumContainer[0].listAlbumContainer1;
string snodesticker = Serializeanddeserializwhelper.Serialize(sk);
string nodegi = Serializeanddeserializwhelper.Serialize(gi);
string nodeci = Serializeanddeserializwhelper.Serialize(ci);
string nodewa = Serializeanddeserializwhelper.Serialize(wa);
string nodevideo = Serializeanddeserializwhelper.Serialize(_video);
string nodeaudio = Serializeanddeserializwhelper.Serialize(_audio);
var TittledataInsertCheck = db.Table<Title>().Where(x => x.ALBUM_TITLE.Contains(nametxt.Text)).FirstOrDefault();
if (TittledataInsertCheck == null)
{
db.Insert(new Title()
{
ALBUM_TITLE = nametxt.Text
});
var TittledataInsert = db.Table<Title>().Where(x => x.ALBUM_TITLE.Contains(nametxt.Text)).FirstOrDefault();
if (TittledataInsert != null)
{
db.Insert(new PAGE()
{
PAGE_BACKGROUND = albumbg,
TITLE_ID = TittledataInsert.ID
});
}
}
else
{
await new MessageDialog("Tittle Already Found Please change tittle").ShowAsync();
return;
}
var PagedataInsert = db.Table<PAGE>().Where(x => x.PAGE_BACKGROUND.Contains(albumbg)).FirstOrDefault();
if (PagedataInsert != null)
{
db.Insert(new CONTENT
{
PAGE_ID = PagedataInsert.ID,
STICKERS = snodesticker,
AUDIO = nodeaudio,
VIDEO = nodevideo,
GALLERY_IMAGES = nodegi,
CAMERA_IMAGES = nodeci,
WOARD_ART = nodewa
});
}
db.Commit();
db.Dispose();
db.Close();
var line = new MessageDialog("Records Inserted");
await line.ShowAsync();
}
Is this the right way to insert the data?
I have a canvas on which I set the background image. And on this background some images, video and audio.

Categories