设置打印区域 - OpenXML with Excel
有人知道如何通过Excel中的OpenXML SDK设置打印区域吗?
我尝试使用以下代码:
public void XLUpdateDefinedName(string fileName, string definedName, string newRange)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
WorkbookPart wbPart = document.WorkbookPart;
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
DefinedName name = definedNames.Descendants<DefinedName>().Where(m => m.Name == definedName).Single();
UInt32Value locSheetId = name.LocalSheetId;
name = null;//.Remove();
wbPart.Workbook.Save();
name = new DefinedName() { Name = definedName, LocalSheetId = locSheetId , Text = newRange}
;
wbPart.Workbook.Save();
//newDefinedName.Text = newRange;
//definedNames.Append(newDefinedName);
}
}
更新:
我继续收到来自 excel 的错误,指出文件中包含以下代码的内容不可读。
public void XLUpdateDefinedName(string fileName, string definedName, string newRange, string sheet, UInt32Value localId)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
String sheetName = sheet;
string topLeft = newRange.Split(':').First();
string bottomRight = newRange.Split(':').Last();
WorkbookPart wbPart = document.WorkbookPart;
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
var nameCollection = definedNames.Descendants<DefinedName>().Where(m => m.Text.StartsWith(sheetName));
DefinedName name = nameCollection.Count() > 0 ? nameCollection.First() : null;
UInt32Value locSheetId;
if (name != null)
{
locSheetId = name.LocalSheetId;
name.Remove();
wbPart.Workbook.Save();
}
else
{
locSheetId = localId;
}
name = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = locSheetId};
name.Text = String.Format("{0}!{1}:{2}", sheetName,topLeft,bottomRight);
definedNames.Append(name);
wbPart.Workbook.Save();
}}
newRange 的形式为 ( $A$10:$C$15 )
Does anybody know how to set print area through OpenXML SDK in Excel?
I've tried using the following code:
public void XLUpdateDefinedName(string fileName, string definedName, string newRange)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
WorkbookPart wbPart = document.WorkbookPart;
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
DefinedName name = definedNames.Descendants<DefinedName>().Where(m => m.Name == definedName).Single();
UInt32Value locSheetId = name.LocalSheetId;
name = null;//.Remove();
wbPart.Workbook.Save();
name = new DefinedName() { Name = definedName, LocalSheetId = locSheetId , Text = newRange}
;
wbPart.Workbook.Save();
//newDefinedName.Text = newRange;
//definedNames.Append(newDefinedName);
}
}
UPDATE:
I continue to receive an error from excel saying there is unreadable content in file with the following code.
public void XLUpdateDefinedName(string fileName, string definedName, string newRange, string sheet, UInt32Value localId)
{
using (SpreadsheetDocument document = SpreadsheetDocument.Open(fileName, true))
{
String sheetName = sheet;
string topLeft = newRange.Split(':').First();
string bottomRight = newRange.Split(':').Last();
WorkbookPart wbPart = document.WorkbookPart;
var definedNames = wbPart.Workbook.Descendants<DefinedNames>().FirstOrDefault();
var nameCollection = definedNames.Descendants<DefinedName>().Where(m => m.Text.StartsWith(sheetName));
DefinedName name = nameCollection.Count() > 0 ? nameCollection.First() : null;
UInt32Value locSheetId;
if (name != null)
{
locSheetId = name.LocalSheetId;
name.Remove();
wbPart.Workbook.Save();
}
else
{
locSheetId = localId;
}
name = new DefinedName() { Name = "_xlnm.Print_Area", LocalSheetId = locSheetId};
name.Text = String.Format("{0}!{1}:{2}", sheetName,topLeft,bottomRight);
definedNames.Append(name);
wbPart.Workbook.Save();
}}
newRange is of the form ( $A$10:$C$15 )
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我发现了一些有关似乎未使用互操作的方法的信息。您可以尝试以下操作:
看看这是否有帮助。我自己还没有尝试过,但我会验证一下。
更新:
第一种方法似乎需要额外的库。您可以从这里获取它:
http://closexml.codeplex.com/。我自己没有使用过它,所以我不能向你保证它可以正常工作。
纯 OpenXML 解决方案
我已经通过在记事本编辑器中手动修改 xlsx 文件内容来更改打印区域。
在 C# 中,您应该尝试使用以下方法(它将打印区域设置为 A1:G19):
您需要更改的是行:
printAreaDefName.Text = "Worksheet1!$A$1 :$G$19";
。您应该更改文本值以包含以下格式的信息:[工作表名称]![打印区域的左上角]:[打印区域的右下角]。它应该将您的打印区域设置为具有指定左上角和右下角的矩形。
如果您想为不同的工作表指定打印区域,请尝试添加多个
DefinedName
对象:我还建议使用OpenXML SDK 2.0 Productivity Tool。它允许您显示所选 OpenXML 文件的内容、比较文件、验证文件,甚至显示您为以编程方式重新创建文件而编写的 C# 代码:)。
您可以从这里下载:
http://www.microsoft.com/download/en/details.aspx ?id=5124
更新II:
我已经更正了打印区域值字符串的格式错误。抱歉造成混乱。
我还采用了您发布的代码并基于它创建了一个方法。它工作正常,修改打印区域后,我可以在 Excel 中打开该文件,没有任何问题。该代码假设已经定义了打印范围,并且您现在只需更改它,但也可以对其进行修改以添加新的打印范围。
代码如下:
我将工作表名称和打印区域范围的值放在方法内,这样您就可以看到它们应该具有什么样的值。我希望这有帮助。
I've found some information about a method that seems not to be using Interop. You can try something like:
See if this helps. I haven't tried it myself yet, but I'm going to verify it.
UPDATE:
The first method seems to require an additional library. You can get it from here:
http://closedxml.codeplex.com/. I haven't used it myself, so I cannot assure you it works correctly.
Pure OpenXML solution
I've managed to change the print area by manually modifying the xlsx file contents in notepad editor.
In C# you should try to use the follwoing method (it sets printing area to A1:G19):
The thing you need to change is line:
printAreaDefName.Text = "Worksheet1!$A$1:$G$19";
.You should change the Text value to contain information in format: [worksheet_name]![top-left corner of print area]:[bottom-right corner of print area]. It should set your print area to a rectangle with upper-left and bottom-right corners as specified.
If you want to specify print areas for different worksheets, try to add multiple
DefinedName
objects:I also recommend using OpenXML SDK 2.0 Productivity Tool. It allows you to show the contents of a chosen OpenXML file, compare files, validate a file and even show a C# code that you would write in order to recreate the file programatically :).
You can download it from here:
http://www.microsoft.com/download/en/details.aspx?id=5124
UPDATE II:
I've corrected a mistake in format of the print area value string. Sorry for the confusion.
I've also took the code you posted and created a method based on it. It works correctly and after modifying the print area I can open the file in Excel without issues. The code assumes that a print range is already defined and you are now just changing it, but it can be modified to add new print range as well.
Here's the code:
I put the values of worksheet name and print area range inside the method, so you can see what kind of values they should have. I hope this helps.
让我解释一下我的情况:我有 Excel 工作簿,其中包含以下工作表(T1,I1,M1)。现在我的要求是基于某些条件T1,I1,M1将多次复制到同一个Excel工作簿,例如T2,I2,M2,T3,I3,M3等。对我来说,I2、M2 的打印区域没有任何问题,但对于复印表 T2、T3... 有问题。因为它有大量数据。 Excel 列上升到“AG”。所以这就是我在代码中所做的
一旦将新工作表添加到工作簿,
首先获取当前工作表计数
获取工作表计数,这将在 LocalsheetId 中用作 printarea 设置。
仅对于复制的技术表,打印区域设置不正确。因此需要正确设置。
请注意 defName.Text,格式为“T1”!$A$1:$AG$19
我不需要在 DefinedNames 集合中添加新的 Definedname。所以我刚刚添加到工作簿定义名称集合中并且它起作用了。
Let me explain my case: I have excel workbook with following sheets (T1,I1,M1). Now my requirement was based on some condition T1,I1,M1 will be copied to same excel workbook multiple times e.g. T2,I2,M2, T3,I3,M3 and so on. For me I2,M2 did not have any issues with Print area but for copied sheet T2,T3... had issue. since it had huge data. excel column goes upto "AG". So here is what i did in code
Once the new sheet is added to workbook
first get the current sheet count
Get the sheet count, this will be used in LocalsheetId as printarea setting.
Only for copied techical sheet the print area was not set properly. Hence need to be set correctly.
Be care full with defName.Text the format is 'T1'!$A$1:$AG$19
There was no need for me to add new Definedname in DefinedNames collection. So I just added to workbook definedNames collection and it worked.