为啥设置为左对齐的单元格内容有时会右对齐(Aspose Cells)?

Posted

技术标签:

【中文标题】为啥设置为左对齐的单元格内容有时会右对齐(Aspose Cells)?【英文标题】:Why would cell contents set to align left sometimes align right (Aspose Cells)?为什么设置为左对齐的单元格内容有时会右对齐(Aspose Cells)? 【发布时间】:2017-01-16 23:51:24 【问题描述】:

我有这段代码,它应该左对齐特定列的内容:

Cell memberItemCodeCell = customerWorksheet.Cells[rowToPopulate, MEMBERITEMCODE_COL];
memberItemCodeCell.PutValue(frbdbc.MemberItemCode, true);
var micStyle = memberItemCodeCell.GetStyle();
micStyle.Font.Name = fontForSheets;
micStyle.Font.Size = 11;
micStyle.HorizontalAlignment = TextAlignmentType.Left;
micStyle.IsTextWrapped = false;
memberItemCodeCell.SetStyle(micStyle, flag);

它工作......有时:

到底为什么有时会发生右对齐?

任何可以被视为 int 的值(不包含 alpha 字符或破折号)右对齐;但为什么它不尊重显式左对齐,不管它是否“看起来像”一个 int?

在所有特定于列的代码之后,有一些适用于整行的“通用”格式:

CellsFactory cf = new CellsFactory();
Style style4 = cf.CreateStyle();
if (shipVarDbl >= 1.0) // fewer were shipped than were ordered

    style4.ForegroundColor = Color.LightGreen;

else if (shipVarDbl < 0.0) // more were shipped than were ordered

    style4.ForegroundColor = Color.PaleVioletRed;

style4.Font.Name = fontForSheets;
style4.Font.Size = 11;
style4.Pattern = BackgroundType.Solid;
rowRange.SetStyle(style4);

...但这不应该影响对齐。

在上面首先显示的代码作为 PopulateCustomerSheet() 方法的一部分运行之后:

private void PopulateCustomerSheet()

    try
    
        if (null == _fillRateByDistributorByCustomerList) return;
        foreach (FillRateByDistributorByCustomer frbdbc in _fillRateByDistributorByCustomerList)
        
            AddCustomerRow(frbdbc);
        
        AutoFitterOptions options = new AutoFitterOptions  OnlyAuto = true ;
        customerWorksheet.AutoFitColumns(options);
    
    catch (Exception ex)
    
        RoboReporterConstsAndUtils.HandleException(ex);
    

...边框化,配置打印,最后将工作表写入磁盘:

BorderizeDataPortionOfCustomerSheet(); 
ConfigureCustomerSheetForPrinting();

// Write the file to disk
string fromAsYYYYMMDD = DateTime.Now.ToString("yyyy-MM-dd_hh-mm-ss");
RoboReporterConstsAndUtils.SetUniqueFolder(_unit);
String _uniqueFolder = RoboReporterConstsAndUtils.uniqueFolder;

var sharedFolder = String.Format(@"\\storageblade\cs\REPORTING\RoboReporter\0", _uniqueFolder);
RoboReporterConstsAndUtils.ConditionallyCreateDirectory(sharedFolder);

var filename = String.Format(@"0\1 - Fill Rate - 2.xlsx", sharedFolder, _unit, fromAsYYYYMMDD);
if (File.Exists(filename))

    File.Delete(filename);

workBook.Save(filename, SaveFormat.Xlsx);

我无法想象边框化或打印配置会更改工作表上特定列的对齐方式,但以防万一,以下是这些方法:

private void BorderizeDataPortionOfCustomerSheet()

    int rowsUsed = customerWorksheet.Cells.Rows.Count;
    int colsUsed = SHIPVARIANCE_COL;

    string bottomRightRange = string.Format("P0", rowsUsed);
    var range = customerWorksheet.Cells.CreateRange("A1", bottomRightRange);

    //Setting border for each cell in the range
    var style = workBook.CreateStyle();
    style.SetBorder(BorderType.BottomBorder, CellBorderType.Thin, Color.Black);
    style.SetBorder(BorderType.LeftBorder, CellBorderType.Thin, Color.Black);
    style.SetBorder(BorderType.RightBorder, CellBorderType.Thin, Color.Black);
    style.SetBorder(BorderType.TopBorder, CellBorderType.Thin, Color.Black);

    for (int r = range.FirstRow; r < range.RowCount; r++)
    
        for (int c = range.FirstColumn; c < range.ColumnCount; c++)
        
            Cell cell = customerWorksheet.Cells[r, c];
            cell.SetStyle(style, new StyleFlag()
            
                TopBorder = true,
                BottomBorder = true,
                LeftBorder = true,
                RightBorder = true
            );
        
    

    //Setting outline border to range
    range.SetOutlineBorder(BorderType.TopBorder, CellBorderType.Thin, Color.Black);
    range.SetOutlineBorder(BorderType.BottomBorder, CellBorderType.Thin, Color.Black);
    range.SetOutlineBorder(BorderType.LeftBorder, CellBorderType.Thin, Color.Black);
    range.SetOutlineBorder(BorderType.RightBorder, CellBorderType.Thin, Color.Black);

    customerWorksheet.FreezePanes(FIRST_DATA_ROW, SHORTNAME_COL, rowsUsed, colsUsed);


private void ConfigureCustomerSheetForPrinting()

    const double INCHES_TO_CENTIMETERS_FACTOR = 2.54;
    string lastColumn = GetExcelTextColumnName(customerWorksheet.Cells.Columns.Count);
    string printArea = String.Format("A1:01", lastColumn, customerWorksheet.Cells.Rows.Count);
    customerWorksheet.PageSetup.PrintArea = printArea;
    customerWorksheet.PageSetup.Orientation = PageOrientationType.Landscape;

    // I don't know if this does anything; I would like to set it to 54%...
    customerWorksheet.PageSetup.IsPercentScale = true;

    customerWorksheet.PageSetup.FitToPagesWide = 1;
    customerWorksheet.PageSetup.FitToPagesTall = 0;

    customerWorksheet.PageSetup.LeftMargin = 0.5 * INCHES_TO_CENTIMETERS_FACTOR;
    customerWorksheet.PageSetup.RightMargin = 0.5 * INCHES_TO_CENTIMETERS_FACTOR;
    customerWorksheet.PageSetup.TopMargin = 0.5 * INCHES_TO_CENTIMETERS_FACTOR;
    customerWorksheet.PageSetup.BottomMargin = 0.5 * INCHES_TO_CENTIMETERS_FACTOR;
    customerWorksheet.PageSetup.HeaderMargin = 0;
    customerWorksheet.PageSetup.FooterMargin = 0;

    // Repeat rows
    string repeatableRowRange = "$1:$1";
    customerWorksheet.PageSetup.PrintTitleRows = repeatableRowRange;

这怎么会导致列对齐不尊重、不服从和忽略 clear and present 指令以左对齐其内容?

更新

根据我对答案的理解,我改变了这个:

rowRange.SetStyle(style4);

...到这个:

var flag = new StyleFlag

    CellShading = true,
    FontName = true,
    FontSize = true,
    FontColor = true,
    FontBold = true,
    NumberFormat = true
;

rowRange.ApplyStyle(style4, flag);

...但它没有任何区别。

更新 2

这是明确设置问题列的代码:

Cell memberItemCodeCell = customerWorksheet.Cells[rowToPopulate, MEMBERITEMCODE_COL];
memberItemCodeCell.PutValue(frbdbc.MemberItemCode, true);
var micStyle = memberItemCodeCell.GetStyle();
micStyle.Font.Name = fontForSheets;
micStyle.Font.Size = 11;
micStyle.HorizontalAlignment = TextAlignmentType.Left;
micStyle.IsTextWrapped = false;
memberItemCodeCell.SetStyle(micStyle, flag);

所以我在这里使用的不是范围,而是一个单元格。我应该使用一个范围,以便我可以使用 ApplyStyle()?我试过这样做,但它似乎不想接受 PutValue() 等。

此外,提供的值 (frbdbc.MemberItemCode) 是一个字符串,所以这不应该阻止 Excel 将其视为 int 吗?我还需要做什么才能让 Excel 知道,“嘿,这是一个字符串,按原样呈现。”

更新 3

我尝试了 Aspose 发给我的这段代码:

customerWorksheet.Cells.CreateRange(rangeBegin, rangeEnd).ApplyStyle(style4, new StyleFlag()  Font = true, CellShading = true );

在上下文中:

string rangeBegin = RoboReporterConstsAndUtils.GetRangeLettersNumbersAsStr(SHORTNAME_COL + 1, rowToPopulate);
string rangeEnd = RoboReporterConstsAndUtils.GetRangeLettersNumbersAsStr(SHIPVARIANCE_COL + 1, rowToPopulate);

CellsFactory cf = new CellsFactory();
Style style4 = cf.CreateStyle();
if (shipVarDbl >= 1.0) // fewer were shipped than were ordered

    style4.ForegroundColor = Color.LightGreen;

else if (shipVarDbl < 0.0) // more were shipped than were ordered

    style4.ForegroundColor = Color.PaleVioletRed;

style4.Font.Name = fontForSheets;
style4.Font.Size = 11;
style4.Pattern = BackgroundType.Solid;
customerWorksheet.Cells.CreateRange(rangeBegin, rangeEnd).ApplyStyle(style4, new StyleFlag()  Font = true, CellShading = true );

...仍然没有区别。

更新 4

我认为这可能有效,我发现here:

micStyle.NumberFormat = 2;

(将“2”替换为代表“文本”的任何数字);但无法识别“NumberFormat”。这是一个过时的例子吗?

更新 5

好的,这[不]发生一定有一些合乎逻辑的原因。以下是我对该列的操作,按顺序:

首先写标题行:

private static readonly int MEMBERITEMCODE_COL = 4;
. . .
private void AddCustomerSheetHeaderRow()

    var flag = new StyleFlag
    
        CellShading = true,
        FontName = true,
        FontSize = true,
        FontColor = true,
        FontBold = true,
        NumberFormat = true
    ;

    . . .

    CellsFactory cfMemberItemCode = new CellsFactory();
    Cell MemberItemCodeCell = customerWorksheet.Cells[0, MEMBERITEMCODE_COL];
    MemberItemCodeCell.PutValue("Member Item Code");
    var styleMemberItemCode = cfMemberItemCode.CreateStyle();
    styleMemberItemCode.HorizontalAlignment = TextAlignmentType.Left;
    styleMemberItemCode.Font.Name = fontForSheets;
    styleMemberItemCode.Font.IsBold = true;
    styleMemberItemCode.Font.Size = 11;
    styleMemberItemCode.ForegroundColor = Color.LightBlue;
    styleMemberItemCode.Pattern = BackgroundType.Solid;
    MemberItemCodeCell.SetStyle(styleMemberItemCode, flag);

    . . .

所以我对齐标题行上的列;它是索引 4,IOW 列“E”

接下来,多次调用 AddCustomerRow(),填充工作表的“数据”部分(标题行下方的所有内容):

    private void AddCustomerRow(FillRateByDistributorByCustomer frbdbc) 
    
        var flag = new StyleFlag
        
            CellShading = true,
            FontName = true,
            FontSize = true,
            FontColor = true,
            FontBold = true,
            NumberFormat = true
        ;

        . . .

        // This is sometimes seen as an int by Excel, and sports the green warning triangle
        // Fixed that with the second (true) arg to PutValue(), but it right-aligns int-like vals...?!@?
        Cell memberItemCodeCell = customerWorksheet.Cells[rowToPopulate, MEMBERITEMCODE_COL];
        memberItemCodeCell.PutValue(frbdbc.MemberItemCode, true);
        var micStyle = memberItemCodeCell.GetStyle();
        micStyle.Font.Name = fontForSheets;
        micStyle.Font.Size = 11;
        micStyle.HorizontalAlignment = TextAlignmentType.Left;
        micStyle.IsTextWrapped = false;
        memberItemCodeCell.SetStyle(micStyle, flag);

        . . .

        string rangeBegin = RoboReporterConstsAndUtils.GetRangeLettersNumbersAsStr(SHORTNAME_COL + 1, rowToPopulate);
        string rangeEnd = RoboReporterConstsAndUtils.GetRangeLettersNumbersAsStr(SHIPVARIANCE_COL + 1, rowToPopulate);

        CellsFactory cf = new CellsFactory();
        Style style4 = cf.CreateStyle();
        if (shipVarDbl >= 1.0) // fewer were shipped than were ordered
        
            style4.ForegroundColor = Color.LightGreen;
        
        else if (shipVarDbl < 0.0) // more were shipped than were ordered
        
            style4.ForegroundColor = Color.PaleVioletRed;
        
        style4.Pattern = BackgroundType.Solid;
        style4.Font.Name = fontForSheets;
        style4.Font.Size = 11;
        customerWorksheet.Cells.CreateRange(rangeBegin
|rangeEnd).ApplyStyle(style4, new StyleFlag()  Font = true,
CellShading = true );
    

在这里,对齐方式也设置为左。设置好每一列后,创建“通用行样式”,以有条件地为整行着色。效果很好 - 适当的行被着色。

然后,因为标题行的着色不像以前尝试的那样起作用(将其设置为 LightBlue 不起作用),所以我在脸部之后这样做:

private void RecolorizeTopRowOfCustomerSheet()

    . . .

    CellsFactory cfMemberItemCode = new CellsFactory();
    Cell MemberItemCodeCell = customerWorksheet.Cells[0,
MEMBERITEMCODE_COL];
    var styleMemberItemCode = cfMemberItemCode.CreateStyle();
    styleMemberItemCode.HorizontalAlignment = TextAlignmentType.Left;
    styleMemberItemCode.Font.Name = fontForSheets;
    styleMemberItemCode.Font.IsBold = true;
    styleMemberItemCode.Font.Size = 11;
    styleMemberItemCode.ForegroundColor = Color.LightBlue;
    styleMemberItemCode.Pattern = BackgroundType.Solid;
    MemberItemCodeCell.SetStyle(styleMemberItemCode);

    . . .

    // Give it borders
    Range _range;
    _range = customerWorksheet.Cells.CreateRange("A1", "P1");
    //Set the borders with hair lines style.
    _range.SetOutlineBorders(CellBorderType.Hair, Color.Black);

...边框也添加到该行。最后,将边框添加到数据行(第 1 行之后的所有内容):

private void BorderizeDataPortionOfCustomerSheet()

    int rowsUsed = customerWorksheet.Cells.Rows.Count;
    int colsUsed = SHIPVARIANCE_COL;

    string bottomRightRange = string.Format("P0", rowsUsed);
    var range = customerWorksheet.Cells.CreateRange("A1", bottomRightRange);

    //Setting border for each cell in the range
    var style = workBook.CreateStyle();
    style.SetBorder(BorderType.BottomBorder, CellBorderType.Thin, Color.Black);
    style.SetBorder(BorderType.LeftBorder, CellBorderType.Thin, Color.Black);
    style.SetBorder(BorderType.RightBorder, CellBorderType.Thin, Color.Black);
    style.SetBorder(BorderType.TopBorder, CellBorderType.Thin, Color.Black);

    for (int r = range.FirstRow; r < range.RowCount; r++)
    
        for (int c = range.FirstColumn; c < range.ColumnCount; c++)
        
            Cell cell = customerWorksheet.Cells[r, c];
            cell.SetStyle(style, new StyleFlag()
            
                TopBorder = true,
                BottomBorder = true,
                LeftBorder = true,
                RightBorder = true
            );
        
    

    //Setting outline border to range
    range.SetOutlineBorder(BorderType.TopBorder, CellBorderType.Thin, Color.Black);
    range.SetOutlineBorder(BorderType.BottomBorder, CellBorderType.Thin, Color.Black);
    range.SetOutlineBorder(BorderType.LeftBorder, CellBorderType.Thin, Color.Black);
    range.SetOutlineBorder(BorderType.RightBorder, CellBorderType.Thin, Color.Black);

    customerWorksheet.FreezePanes(FIRST_DATA_ROW, SHORTNAME_COL, rowsUsed, colsUsed);

然后将文件保存到磁盘 - MemberItemCode 列中的一些项目左对齐而其他项目右对齐。为什么没有像这样的调用:

Column[3].Alignment = AlignLeft;

...可以根据需要轻松对齐特定列中的所有内容;或者有吗?由于我正在尝试的东西要么不起作用,要么非常喜怒无常,所以这样的东西肯定会很方便。

【问题讨论】:

【参考方案1】:

我相信上述问题是由于您使用从头创建的对象覆盖样式的所有方面而引起的。请注意,当您将样式应用于单元格时,您首先从该单元格中获取样式,这样您就可以保留应用于它的数字格式。但是,当您从头开始创建 Style 对象并在使用 Range.SetStyle 时将样式应用于范围时,新创建的 Style 对象的每个方面都会被覆盖到范围中,这会导致中每个单元格的格式更改为 General范围。我建议您改用 Range.ApplyStyle 方法,它允许您将 StyleFlag 的实例传递给上述方法。这样,您可以控制要覆盖的 Style 对象的各个方面。

注意:我在 Aspose 担任开发人员宣传员。

【讨论】:

你能提供一个具体如何做到这一点的例子吗?具体来说,“旗帜”应该是什么样子?我有 rowRange.ApplyStyle(style4, )。 我的 cmets 是基于这样一个事实,即您的单元格格式已更改为“常规”,这也会导致数值对齐方式发生偏移。如果您应用从头开始创建的样式,则该样式的数字格式将自动设置为常规,因此范围内所有单元格的数字格式将相应更改。也就是说,我怀疑您的代码在某处覆盖了样式。为了进一步调查此事,我恳请您通过提供一个简单的示例应用程序继续在 Aspose.Cells 支持论坛中进行对话。 通过查看问题描述中的更新 5,我注意到您在 AddCustomerSheetHeaderRow 方法中将 StyleFlag.Number 设置为 true。您能否通过评论此声明来尝试此案例? 请注意,如果不查看应用程序的实际流程和输入电子表格,并不总是能够查明问题原因,因此,我再次请求您分享一个简单的可执行示例应用程序以及Aspose.Cells 支持论坛中的源和目标(所需结果)以供进一步调查。 很高兴知道您已经成功实现了目标。如果可以,请将您的示例应用程序发布到 Aspose.Cells 支持论坛,以便我们对其进行审查以提出改进建议。【参考方案2】:

我可以让它工作的唯一方法是通过在完成其他所有操作后将该列中的所有单元格显式设置为左对齐来“强制它”:

private static readonly int MEMBERITEMCODE_COL = 4;
. . .
SetAllCustomerSheetColValsLeftAligned(MEMBERITEMCODE_COL);
BorderizeDataPortionOfCustomerSheet();    
. . .    
private void SetAllCustomerSheetColValsLeftAligned(int colIndex)

    int rowsUsed = customerWorksheet.Cells.Rows.Count;
    CellsFactory cf = new CellsFactory();
    Cell currentCell = null;
    Style currentStyle = null;
    for (int i = 2; i <= rowsUsed; i++)
    
        currentCell = customerWorksheet.Cells[i, colIndex];
        currentStyle = cf.CreateStyle();
        currentStyle.HorizontalAlignment = TextAlignmentType.Left;
        currentStyle.Font.Name = fontForSheets;
        currentStyle.Font.Size = 11;
        currentCell.SetStyle(currentStyle);
    

【讨论】:

以上是关于为啥设置为左对齐的单元格内容有时会右对齐(Aspose Cells)?的主要内容,如果未能解决你的问题,请参考以下文章

有用aspose.words的吗,请教单元格内容怎么水平居中

excel怎么居中单元格

Excel单元格内容太多会覆盖遮住下一单元格范围

设置DataGridView单元格的文本对齐方式

QTableView中单元格内容居中对齐

vertical-align详解