是否可以使用 PX.Data.XLSXReader 从特定单元格读取 Excel 数据?
Is it possible to read Excel data from specific cells using PX.Data.XLSXReader?
是否可以使用 PX.Data.XLSXReader 从特定单元格读取 Excel 数据?
我正在尝试使用 Acumatica 的 XLSXReader 库从 Excel 文件中读取特定列,但我一直无法找到获取特定单元格信息的函数 - 例如H7。
看来我需要为列定义一个索引才能迭代并获取信息。但是,在我的例子中 excel 文件不包含第一行的信息,我们无法修改它,因为它是由第三方自动生成的。
这是我的行动:
[PXUIField(DisplayName = "Upload Data", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Visible = true)]
[PXButton()]
public virtual IEnumerable uploadFileBatch(PXAdapter adapter)
{
string complete = "";
if (this.NewFilePanel.AskExt() == WebDialogResult.OK)
{
PX.SM.FileInfo info = PXContext.SessionTyped<PXSessionStatePXData>().FileInfo[SessionKey] as PX.SM.FileInfo;
byte[] bytes = info.BinData;
List<string> pONotFound = new List<string>();
using (PX.Data.XLSXReader reader = new XLSXReader(bytes))
{
reader.Reset();
Dictionary<String, Int32> indexes = reader.IndexKeyPairs.ToDictionary(p => p.Value.ToUpper(), p => p.Key);
while (reader.MoveNext())
{
//This is correct when there is info in the first row with those titles
string data = reader.GetValue(indexes["TITLE"]).Trim() + "\n";
//However I would like to do something like this
string data2 = reader.GetValue("H7").Trim() + "\n";
}
}
}
}
另外,我注意到当我不包括
Dictionary<String, Int32> indexes = reader.IndexKeyPairs.ToDictionary(p => p.Value.ToUpper(), p => p.Key);
代码没有迭代
reader.MoveNext()
我理解为什么 Acumatica 使用第一行来标识列并在文档上传期间帮助映射 - 但我正在考虑更灵活地管理图书馆 - 如果可能的话。
Is it possible to read Excel data from specific cells using PX.Data.XLSXReader?
是的,可以像您的示例中那样使用 GetValue
方法获取一行的特定单元格。
无法随机访问行,因为它们使用 IEnumerator:
IEnumerator<Worksheet.Row> _rowIterator;
但是第一行是一种特殊情况,可以通过 IndexKeyPairs
属性.
Also, I have noticed that when I don't include […] the code doesn't
iterate with
访问 IndexKeyPairs
属性 具有分配 _keys
私有成员的副作用。这种副作用可能会改变 XLSXReader
class.
的行为
public IDictionary<int, string> IndexKeyPairs
{
get
{
if (_keys == null)
{
_keys = new Dictionary<int, string>();
if (_headerRow != null)
foreach (Worksheet.Cell cell in _headerRow.Cells)
_keys.Add(new KeyValuePair<int, string>(cell.Address.Column, GetValue(cell)));
}
return _keys;
}
}
I'm thinking of managing the library with more flexibility - if
possible.
该库针对需要顺序迭代器而不是随机访问的速度进行了优化。它可能不那么方便,但 MoveNext
方法的设计速度很快。要访问特定行,请调用 Reset
方法重置迭代器并重复调用 MoveNext
直到到达目标行。
要评估 XLSXReader
class 提供的可用功能,请查找 IContentReader
界面:
public interface IContentReader : IDisposable
{
/// <summary>
/// Move to next record in data source
/// </summary>
/// <returns>true, if the operation was performed successfully</returns>
bool MoveNext();
/// <summary>
/// Find value in record by given key index
/// </summary>
/// <param name="index">index of value</param>
/// <returns>null, if given key index was not found</returns>
string GetValue(int index);
/// <summary>
/// Reset state of reader
/// </summary>
void Reset();
/// <summary>
/// Collection of value keys
/// </summary>
IDictionary<int, string> IndexKeyPairs { get; }
}
是否可以使用 PX.Data.XLSXReader 从特定单元格读取 Excel 数据? 我正在尝试使用 Acumatica 的 XLSXReader 库从 Excel 文件中读取特定列,但我一直无法找到获取特定单元格信息的函数 - 例如H7。 看来我需要为列定义一个索引才能迭代并获取信息。但是,在我的例子中 excel 文件不包含第一行的信息,我们无法修改它,因为它是由第三方自动生成的。 这是我的行动:
[PXUIField(DisplayName = "Upload Data", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select, Visible = true)]
[PXButton()]
public virtual IEnumerable uploadFileBatch(PXAdapter adapter)
{
string complete = "";
if (this.NewFilePanel.AskExt() == WebDialogResult.OK)
{
PX.SM.FileInfo info = PXContext.SessionTyped<PXSessionStatePXData>().FileInfo[SessionKey] as PX.SM.FileInfo;
byte[] bytes = info.BinData;
List<string> pONotFound = new List<string>();
using (PX.Data.XLSXReader reader = new XLSXReader(bytes))
{
reader.Reset();
Dictionary<String, Int32> indexes = reader.IndexKeyPairs.ToDictionary(p => p.Value.ToUpper(), p => p.Key);
while (reader.MoveNext())
{
//This is correct when there is info in the first row with those titles
string data = reader.GetValue(indexes["TITLE"]).Trim() + "\n";
//However I would like to do something like this
string data2 = reader.GetValue("H7").Trim() + "\n";
}
}
}
}
另外,我注意到当我不包括
Dictionary<String, Int32> indexes = reader.IndexKeyPairs.ToDictionary(p => p.Value.ToUpper(), p => p.Key);
代码没有迭代
reader.MoveNext()
我理解为什么 Acumatica 使用第一行来标识列并在文档上传期间帮助映射 - 但我正在考虑更灵活地管理图书馆 - 如果可能的话。
Is it possible to read Excel data from specific cells using PX.Data.XLSXReader?
是的,可以像您的示例中那样使用 GetValue
方法获取一行的特定单元格。
无法随机访问行,因为它们使用 IEnumerator:
IEnumerator<Worksheet.Row> _rowIterator;
但是第一行是一种特殊情况,可以通过 IndexKeyPairs
属性.
Also, I have noticed that when I don't include […] the code doesn't iterate with
访问 IndexKeyPairs
属性 具有分配 _keys
私有成员的副作用。这种副作用可能会改变 XLSXReader
class.
public IDictionary<int, string> IndexKeyPairs
{
get
{
if (_keys == null)
{
_keys = new Dictionary<int, string>();
if (_headerRow != null)
foreach (Worksheet.Cell cell in _headerRow.Cells)
_keys.Add(new KeyValuePair<int, string>(cell.Address.Column, GetValue(cell)));
}
return _keys;
}
}
I'm thinking of managing the library with more flexibility - if possible.
该库针对需要顺序迭代器而不是随机访问的速度进行了优化。它可能不那么方便,但 MoveNext
方法的设计速度很快。要访问特定行,请调用 Reset
方法重置迭代器并重复调用 MoveNext
直到到达目标行。
要评估 XLSXReader
class 提供的可用功能,请查找 IContentReader
界面:
public interface IContentReader : IDisposable
{
/// <summary>
/// Move to next record in data source
/// </summary>
/// <returns>true, if the operation was performed successfully</returns>
bool MoveNext();
/// <summary>
/// Find value in record by given key index
/// </summary>
/// <param name="index">index of value</param>
/// <returns>null, if given key index was not found</returns>
string GetValue(int index);
/// <summary>
/// Reset state of reader
/// </summary>
void Reset();
/// <summary>
/// Collection of value keys
/// </summary>
IDictionary<int, string> IndexKeyPairs { get; }
}